题目链接:Whois - Bugku CTF
进入环境
这里要求选择一个server和输入一个query,先根据它默认的选择和输入的提示,在输入框输入php.net点击查询
输出了很多信息,用Ctrl+F查找关键字(flag、shellmates)没有找到什么有用的信息
选择其他server变换输入内容也没找到有用的信息
查看地址栏的URL发现是通过query.php接收host和query参数
直接在地址栏中输入query.php看能否查看该网页
可以查看到源码
直接快速找到php代码执行出口
当if中表达式成立output变量就为"Invalid query or whois host"的字符串;否则就将"/usr/bin/whois -h "和host变量拼接,再和query变量拼接,然后用shell_exec()函数执行字符串,将执行结果赋值给output变量。最后通过htmlspecialchars($output)函数显示。
那这题应该是远程代码执行漏洞(RCE)
简单来说就是通过参数传入恶意指令,通过shell_exec()函数在服务端执行
例如:这里传入的 host=whois.verisign-grs.com query=php.net
最后拼接后的命令为:/usr/bin/whois -h whois.verisign-grs.com php.net
当传入恶意代码时: host=whois.verisign-grs.com; query=ls /
最后拼接后的命令为:/usr/bin/whois -h whois.verisign-grs.com; ls /
就会列出根目录下的所有文件
这里对host和query进行了检查,关于PHP正则表达式:PHP正则表达式,看这一篇就够了 - 爱写bug的程序员 - 博客园 (cnblogs.com)
host参数只能由0-9、a-z、A-Z、.(点)、-(减号)以及\n或者\r 组成
query参数只能由0-9、a-z、A-Z、.(点)、 (空格)以及\n或者\r组成
通过这个可以发现以\n或者\r结尾的也会匹配上
显然以;做命令分割是不可行的。可以用换行符来分割命令
那么可以构造如下请求
/query.php?host=whois.verisign-grs.com%0a&query=ls
最后拼接的命令为
/usr/bin/whois -h whois.verisign-grs.com ls
这里%0a是\n(换行符)的url编码
在linux服务器上执行的命令为:
[www-data@linux]# /usr/bin/whois -h whois.verisign-grs.com [www-data@linux]# ls
该请求返回当前目录下的文件
直接看thisistheflagwithrandomstuffthatyouwontguessJUSTCATME文件内容
query.php?host=whois.verisign-grs.com%0a&query=cat thisistheflagwithrandomstuffthatyouwontguessJUSTCATME
拿到flag
shellmates{i_$h0U1D_HaVE_R3AD_7HE_dOc_W3Ll_9837432986534065}