RCE-CTFHub
前言
本文是作者由CSDN博客迁移而来,原文地址:https://blog.csdn.net/2302_81178149/article/details/145460980?spm=1001.2014.3001.5501
在众多的CTF平台当中,CTFHub对于初学者来说,是入门平台的不二之选。CTFHub通过自己独特的技能树模块,可以帮助初学者来快速入门。具体请看官方介绍:CTFHub。
作者的CTFHub技能树汇总:
为了方便学习,在练习过程中可以查阅作者的RCE总结:RCE学习总结-CSDN博客
eval执行
一进来是一段代码
那我们审计一下这段代码,if里面用了issert()函数,用来检测$_REQUEST['cmd']
是否为空
那$_REQUEST['cmd']
是什么?
就是一种全局变量,来收集我们传递的cmd
的值
变量 | 描述 |
---|---|
$_GET |
收集来自 method="get" 的表单中的值 |
$_POST |
收集来自 method="post" 的表单中的值 |
$_REQUEST |
包含 $_POST 、$_GET 和 $_COOKIE |
$GLOBALS |
全部变量的全局组合数组 |
$_COOKIE |
常用于识别用户 |
$_SESSION |
存储关于用户会话(session)的信息 |
$_FILES |
用来获取通过 POST 方法上传文件的相关信息 |
$_SERVER |
服务器和执行环境信息 |
$_ENV |
环境变量 |
那这段代码我们就很清楚了,一旦我们用HTTP方法传递了cmd
的值,就会继续往下执行,而下面明显是一句话木马。
不知道什么是一句话木马可以去看看作者的文件上传总结:
所以我们用蚁剑连接试试
连接成功
我们在根目录下找到flag
这里其实算取巧了,我们再结合RCE专题训练一遍
服务器一般都是Linux系统,我们试试Linux指令
这里我们先提一下常见Linux指令
1 |
|
出来路径了
1 |
|
继续尝试,我们列一下根目录的文件
1 |
|
出来了
我们打开根目录下的这个文件
1 |
|
出Flag了
文件包含
还是代码
不过有个shell,我们看一下。
发现还是一句话木马
我们先来看一下那段代码是什么意思
error\_reporting(0);
:关闭所有错误报告。error_reporting() 函数用于设置 PHP 错误报告的级别,传递 0 作为参数将关闭所有错误报告。
strpos($_GET["file"], "flag")
:返回”flag”在$_GET[“file”]中第一次出现的位置,如果“flag“不存在,则返回false。
注意前面又加了!,那就是如果“flag“不存在,则返回true。
实际上就是检测我们传的参数带不带“flag“,带的话就会说我们是黑客
比如我们输入:
1 |
|
不带的话,就包含文件,文件名我们传递file的值。
那肯定要包含shell.txt,并且连接蚁剑
1 |
|
还是在根目录下找到flag
php://input
还是审计代码
issert()函数用来检测$_GET[‘file’]是否为空,substr($_GET[“file”], 0, 6)是取出前6个字符,然后判断是否为”php://”,如果是,就会include($_GET["file"]);
看题目很明显要求我们用到伪协议的php://input
,
php://input
作用:可用于查看源码,同时是要查看未压缩文件的只读流。在post请求中能查看请求的原始数据,并将post请求中的post数据当作php代码执行。(只读流是说只能进行读操作的数据)
条件:allow_url_fopen=off/on;allow_url_include=on
点击题中的 phpinfor 查看php情况,检查allow_url_include
是否为on
可以看到已经开了
然后我们就用POST传参,别忘了传递参数
1 |
|
POST传递的数据为
1 |
|
出flag位置了
然后还是POST传参,加上?file=php://input
POST传递的数据为
1 |
|
这里还是要修改成大家自己的flag位置。
确保无误后放包,出flag
读取源代码
代码和之前相似
还是尝试php://input
,发现失败了,估计是allow_url_include=off
的问题
但是在php伪协议中还存在:php://filter
php://filter
- 条件:
allow_url_fopen=off/on;allow_url_include=off/on
- 作用:用过滤器读写数据流
可以发现,php://filter
相当于没有条件
接下来我们进一步了解php://filter
,其具有四个参数:
名称 | 描述 | 备注 |
---|---|---|
resource=<要过滤的数据流> |
指定了你要筛选过滤的数据流。 | 必选 |
read=<读链的筛选列表> |
可以设定一个或多个过滤器名称,以管道符(|)分隔。 | |
write=<写链的筛选列表> |
可以设定一个或多个过滤器名称,以管道符(|)分隔。 | |
<;两个链的筛选列表> |
任何没有以 read= 或 write= 作前缀的筛选器列表会视情况应用于读或写链。 |
这道题就直接构造payload了
1 |
|
Flag出来了
有些比赛赛题情况下还要用base64输出
1 |
|
远程包含
代码和之前类似
看看phpinfo
allow_url_fopen= on;allow_url_include= on
可以用伪协议php://input
出flag
但按题目看,这里是用远程包含。
HP的配置选项allow_url_include
为ON的话,则include/require函数可以加载远程文件,这种漏洞被称为”远程文件包含漏洞(Remote File Inclusion,即RFI)”。
allow_url_fopen = On
是否允许打开远程文件;allow_url_include = On
是否允许include/require远程文件。
在服务器中mkdir一个文件夹,然后在文件夹里vi一个webshell_post.txt
编辑一个一句话木马
1 |
|
随后用python启动一个http服务
1 |
|
然后用蚁剑连接
1 |
|
这样就会包含我们的文件,即包含我们的一句话木马,蚁剑成功连接。
命令注入
还是看看代码
上面那个提交框输入的是ip
然后发送了之后会通过exec函数执行命令
最后显示执行的命令。
需要详细了解各种管道符的请看总结:RCE学习总结-CSDN博客
这道题没有过滤,那我们直接试试&
1 |
|
返回数据了,回显www-data说明whoami执行成功
列一下当前目录试试
1 |
|
15120590614198.php有些可疑,看一下它
1 |
|
没回显
一般遇见这种情况 咱们首先考虑两种方法
第一种,直接查看源代码
果不其然 直接在源代码中找到了
第二种方法是将文件内容base64编码出来
提交payload
1 |
|
然后解码即可
过滤cat
这一关看题目应该是过滤cat
在linux下,不只有cat 可以读取文件内容,more、less、head、tac,都可以对文本进行读取。
1 |
|
1 |
|
或者
1 |
|
过滤空格
这题很明显是过滤空格,
空格可以用以下字符串代替:
< 、<>、%20(space)、%09(tab)、$IFS$9、 ${IFS}、$IFS
等
$IFS在linux下表示分隔符,但是如果单纯的cat$IFS2,bash解释器会把整个IFS2当做变量名,所以导致输不出来结果,然而如果加一个{}就固定了变量名,同理在后面加个$可以起到截断的作用,但是为什么要用$9呢,因为$9只是当前系统shell进程的第九个参数的持有者,它始终为空字符串。
接下来我们开始做题
1 |
|
1 |
|
还是查看源代码
过滤目录分隔符
1 |
|
1 |
|
1 |
|
过滤运算符
题目说过滤了几个运算符,但没过滤;
1 |
|
1 |
|
综合过滤练习
过滤运算符、过滤目录分隔符、过滤反斜杠、过滤空格、过滤封号、过滤cat、过滤关键字flag和ctfhub
先我们要使用ls列目录,发现这里过滤了运算符,连;也过滤了,绕过的方式有%0a、%0d、%0D%0A
1 |
|
注意是在URL上写
我们使用ls flag_is_here列出子目录的文件,免不了绕过空格和flag的顾虑,绕过空格前面已经有writeup中附带了相关技巧,我们这里可以使用${IFS}
绕过
绕过flag关键字,我们使用的方法也是多种多样,这里不一一列出了,经过尝试可以使用$*来绕过关键字过滤,如fl$*ag_is_here
1 |
|
也是在URL上写
最后组合一下,用more替代cat
1 |
|