学习web安全的那些二三事-php篇(1)
从大一入学学习安全到现在,我已经见识到许多基本漏洞以及这些漏洞的变形,这里就写几篇博客总结一下这段时间的学习,顺便也记录一下一些漏洞,以便查看
这里从一些常见的php的语言特性和函数开始说起
1.intval
细说一下intval的具体用法
1 | intval(mixed $value, int $base = 10) |
intval
用于获取变量的整数值,$value为任意类型的变量,后面为进制数,意思是经过转化后输出该进制的数,如果没有数或者输入的数为0,则默认为十进制
这里罗列了以下几种输入(注释内容为intval转化后的内容):
1 |
|
这里说一下e和f
$e作为一个浮点数,因为它使用了科学计数法,2e10代表2 * 10^10^,如果超出范围,则会输出0或者其他不确定的数(这里不是随机数,每一个数对应一个定值)
$f作为一个字符串,intval会先将其转化为数字然后再作进一步修改,如果转化后的数超出范围,则取最大的整数
有的ctf招新会这样出:
1 |
|
这里就可以利用上述例子提到的数组绕过
不过get传数组跟php里面传数组时处理的结果会不一样,get传参对数组的处理似乎有点复杂?(找时间复现一下然后加在这下面),而php里面,由于已经明确要传递空数组,因此判断方便(目前只能大体说说)
num就可以这样赋值:num[]=(啥都行)
2.弱类型比较
我们常见的弱类型比较就是==
了
当数据在使用==
,php会“悄悄”把数据类型进行转化,这样就不用其他的数据转化脚本。
这种“悄悄”的转化方式称为隐式类型转换,它应用于很多编程语言,例如c,javascript等
在8.0版本以前,==的处理比较简单,举个栗子
1 | var_dump('234' == 234); // bool(true) |
这里的弱比较相当于在两端加上了intval
在8.0版本以后,开发者对==进行优化,对于数值字符串有一个很好的转换方法:
若字符串符合数值字符串的定义,则直接作为字符串进行比较.
若字符串不符合数值字符串的定义,则将数值转化为字符串后再进行比较。
数值字符串是指一个包含数字字符的字符串,而像0x7,0b1100110这种有明确进制标识符的不是数值字符串(当然,要符合进制的要求)
:::warning
如果像0x9这种数值被包上引号后则会被标识为数值字符串(这么说会感觉有点矛盾),没有被包上引号则作为数值出现
:::
以上数据输出如下:
1 | var_dump('234' == 234); // bool(true) |
更多内容的可以看看这个博客
附上几种数值的常见标识符:
二进制(0b),八进制(0),十六进制(0x),科学计数法([0-9]e)
有的比赛会根据弱比较类型来考怎么绕过,这里列几个比较常见的
md5绕过
对于md5而言,目前还没有一个好的算法来对md5编码进行解密,很多网站上的md5解密实际上是通过查询变量的md5值来进行破解的。说白了,破解者通过某些算法来生成字典并对这个md5进行爆破。因此,想通过某一个md5的值来破解得到明文在算法上并不可行
当md5出现在php时,又该怎么应对呢
一道经典的题型如下:
1 |
|
对于这种题,我们可以采用数组绕过,因为md5对数组编码后返回为空,我们只需要让数组名不同就行
特别地,若题目变成这样
1 |
|
由于弱比较的特性,我们可以通过爆破来传入相应的值。之前有个例子提到关于科学计数法,e是个比较特殊的字母,我们可以利用0e来进行绕过(毕竟0乘任何数都是0)
根据这个,我们可以查询哪些数值或字符串能够在md5编码后开头为0e
:::info
可以思考一下[0-9]e后如果先接字符后数字或者先数字再字符时会输出什么
:::
3.preg_match
preg_match用于执行匹配正则表达式,说白了就是查找选定字符串中有没有能匹配得上正则表达式部分的。这个只需知道如何看出匹配哪些字符就行,根据条件来写传入的数据
php文档给出的匹配模式如下:
1 | [abc] 单个字符:a、b 或 c |
例如preg_match(/[a-z][A-Z][0-9]/, $a)
表示的是查看$a中是否含有字母和数字,其中字母包含大小写
在审计这种代码时,需要记住匹配模式中每一个正则表达式表示的是什么
这里拿一个ctfshow的题目出来说说
1 |
|
第一层匹配是查询所有行中是否至少有一行是php,第二层则是查询第一行中是否只有php
在/i模式下只能匹配一行,但是加了/m后,php就会解析每一行
因此可以传入cmd=php%0a123,其中%0a为换行符的url编码
:::info
可能有同学会不理解第一次和第二次都能过,因为在/im模式下,php会将%0a识别为换行符,因此我们穿的一行数据在经过解析之后实际上是两行数据;而在/i模式下,%0a只是一个普通的字符串而已
之前也提过,preg_match('/^php$/im', $a)
是检查某一行中的从头到尾是否是php,这就意味着你有一行只能是php
:::
额外补充一个
strpos
用于查找某个字符或某个字符串在某个变量中第一次出现的位置,当匹配字符串时,返回变量中匹配的字符串的第一个字符的位置
1 |
|
4.highlight_file
官方文档给出的用法:highlight_file([string] $filename, [bool] $return = false): [string]|[bool]
我们用到的highlight_file一般用于高亮一个文件(展示一个文件的内容并将对应的代码块进行高亮),因此bool类型一般不会用到
而$filename传入的实际上是文件的地址
5.file_put_contents
php官方文档:file_put_contents(
[string] $filename,
[mixed] $data,
[int] $flags = 0,
[?][resource] $context = **null**
`): [int]|[false]``
其中主要的是filename,需要对内容进行写入的文件(传的是文件名而非地址,注意和其他函数的区别),data就是写入的内容
file_put_contents用于向一个文件里面写内容,针对的是当前目录下的文件,如果当前目录下存在目标文件名,则将该文件进行覆盖重写,反之则创建一个新文件并将内容写入其中
6.call_user_func
php官方文档:
call_user_func([callable] $callback, [mixed] ...$args): [mixed]
call_user_func把第一个参数作为回调函数调用
:::info no-icon
回调:一个过程,将某个函数作为参数放到另外一个函数中,当另外一个函数执行完后,再转过头来执行这个函数
而回调函数实际上是一个参数
:::
第一个传递的是php的函数,例如eval,hex2bin等
第二个传递的是回调函数的参数
学习web安全的那些二三事-php篇(1)
1.渗透总结
2.Hello World
3.学习web安全的那些二三事-反弹Shell篇
4.linux-second
5.学习web安全的那些二三事-linux篇(1)
6.ssti-First
7.ciscn2024
8.ISCTF2023