An open API service indexing awesome lists of open source software.

https://github.com/probiusofficial/bashfuck

exec BashCommand with only ! # $ ' ( ) < \ { } just 10 charset used in Bypass or CTF
https://github.com/probiusofficial/bashfuck

Last synced: 5 months ago
JSON representation

exec BashCommand with only ! # $ ' ( ) < \ { } just 10 charset used in Bypass or CTF

Awesome Lists containing this project

README

          

## **关于**

针对Linux终端 bashshell 的无字母命令执行的骚操作x

支持在线生成:https://probiusofficial.github.io/bashFuck/

Used in [【RCE-labs · level 9-12: BashFuck - 无字母命令执行】](https://github.com/ProbiusOfficial/RCE-labs) to simplify the generation process.

目前可以实现的字符集:


- `#` `$` `'` `(` `)` `0` `1` `<` `\` (9 Charset)

- `#` `$` `'` `(` `)` `0` `<` `\` `{` `}` (10 Charset)

- `!` `#` `$` `'` `(` `)` `<` `\` `{` `}` (10 Charset)

- `!` `$` `&` `'` `(` `)` `=` `< ` `\` `_` `{` `}` `~` (13 Charset)

...更多可能?

Idea来源于[CTFshow](https://www.ctf.show/)周末的极限挑战赛

(后面不定期有各种有意思的挑战赛哦~欢迎各位师傅来平台玩呀)

## **Usage**

*现已支持在线生成:https://probiusofficial.github.io/bashFuck/

使用python3运行bashFuck.py文件即可,根据提示输入你的命令,程序会自动为你生成从最基本的`$'\xxx'`形式到更复杂的形式。

```Bash
python bashFuck.py
```

![](https://fastly.jsdelivr.net/gh/ProbiusOfficial/My_pic@main/2023y-3m-3-d22-h16m1677852984445.png)

![](https://fastly.jsdelivr.net/gh/ProbiusOfficial/My_pic@main/2023y-3m-3-d22-h11m1677852696300.png)

## bashFuck-Wiki

### 前言

整个项目的核心是 Linux终端可以通过 `$'\xxx'` 的方式执行命令,xxx是字符ascii码的八进制形式,通过这一点,我们可以通过位运算符号和Linux终端的其他特性,在没有数字的情况下继续构造这样的形式以实现无字母数字仅用几个字符就实现任意命令执行。

当然本项目也有一定局限性,这取决于linux的系别,我们知道sh其实是一个软连接,在debian系操作系统中,sh指向dash;在centos系操作系统中,sh指向bash,这也是本项目名称为 Bashfuck 的原因。

### 原理解析

#### common_otc(cmd)

首先我们知道,在终端中,`$'\xxx'`可以将八进制ascii码解析为字符,仅基于这个特性,我们可以得到第一个函数`common_otc(cmd)`,该函数将传入的命令的每一个字符转换为`$'\xxx\xxx\xxx\xxx'`的形式,但是注意,如果为连续的一串`$'\xxx\xxx\xxx\xxx'`形式,则我们无法执行带参数的命令。

比如"`ls -l`"也就是`$'\154\163\40\55\154'`,因为这样会把整个字符串当作一个单词,而不会分割成不同的参数,这里涉及到bash的一个单词分割,在Bash中,单词分割是一种将参数扩展、命令替换和算术扩展的结果分割成多个单词的过程,它发生在双引号之外,并且受到IFS变量的影响

(简单提一嘴,IFS是一个环境变量,它定义了字段分隔符,也就是用来分割字符串的字符。默认情况下,空格、制表符和换行符被认为是字段分隔符)

如果一个字符串包含空格或其他IFS字符,它会被分割成多个单词,每个单词作为一个独立的参数传递给命令。

但因为八进制转义序列是在命令行解析之前就执行的,所以它不会触发单词分割

(具体原理可以参考:

【Bash word splitting mechanism】https://stackoverflow.com/questions/18498218/bash-word-splitting-mechanism

【$IFS】https://bash.cyberciti.biz/guide/$IFS

#### bashfuck_x(cmd, form)

基于上面的基本原理,我们引入一些表示特性和运算特性:

比如,在bash中,支持二进制的表示整数的形式:`$((2#binary))`。

通过阅读bash的参考文档https://www.gnu.org/software/bash/manual/bash.html

我们知道`$`作为一个特殊字符,有多样化的功能,比如`$()`可用来表示命令替换或者算术扩展。

在这里我们引入 `$(())` 也就是 算术扩展,让其在括号中执行运算再替换到当前位置。

如果括号里面没有东西的话,也就是为`0`,那么直接`echo $(())` 我们就可以得到字符 `0`

比如我们下面引入一些位运算

左移运算符: `1<<1`可以得到`2` ;

取反:我们在 `0` 的基础上取反,就可以得到字符 `-1` (这个原理很简单,因为`0`的二进制表示是`00000000`,取反后得到`11111111`,这个数在补码表示法下就是`-1`)

除了`$()` `$` 还可以 用`${}`的方式来扩展变量,具体的用法可以参考:https://stackoverflow.com/questions/5163144/what-are-the-special-dollar-sign-shell-variables

这里我们主要用到下面的特性:

`${#var}` 可以计算 `var`变量的字符长度:

![](https://fastly.jsdelivr.net/gh/ProbiusOfficial/My_pic@main/2023y-3m-8-d14-h24m1678256674906.png)

当然 如果 `var` 是 `#` / `_` / `?`这样的本来获取的值就是一个字符特殊参数 那么字符本身为变量,输出 `1`,

如果var为NULL即不带参数 则为 `0`

![](https://fastly.jsdelivr.net/gh/ProbiusOfficial/My_pic@main/2023y-3m-8-d17-h37m1678268229611.png)

![](https://fastly.jsdelivr.net/gh/ProbiusOfficial/My_pic@main/2023y-3m-8-d14-h25m1678256730074.png)

将上面的几种特性结合起来,我们就能使用 `1` `0` / `0` 甚至不用数字来构造字符的八进制形式。

比如只使用0和1:位运算让我们可以很轻松获得数字2,在下面的整数表示中就可以使用`$(($((1<<1))#binary))`来表示任意数字,然后构造八进制

而在上面的基础上,我们用 `${##}` 来替换 `1` ,用 `${#}` 来替换 `0`

那么对于命令`ls`就有下面的几种写法。

```Bash
$\'\\$(($((1<<1))#10011010))\\$(($((1<<1))#10100011))\'

$\'\\$(($((${##}<<${##}))#${##}00${##}${##}0${##}0))\\$(($((${##}<<${##}))#${##}0${##}000${##}${##}))\'

$\'\\$(($((${##}<<${##}))#${##}${#}${#}${##}${##}${#}${##}${#}))\\$(($((${##}<<${##}))#${##}${#}${##}${#}${#}${#}${##}${##}))\'
```

但是上面的命令最终只能被bash还原为八进制转义序列,不会再进一步解析了:

![](https://fastly.jsdelivr.net/gh/ProbiusOfficial/My_pic@main/2023y-3m-8-d14-h25m1678256740148.png)

至于为什么没有进一步解析,我们需要从bash的底层说起,我们可以看参考手册了解问题的所在: https://www.gnu.org/software/bash/manual/html_node/Shell-Expansions.html

```Bash
3.5 Shell Expansions
Expansion is performed on the command line after it has been split into s. There are seven kinds of expansion performed: token
brace expansion
tilde expansion
parameter and variable expansion
command substitution
arithmetic expansion
word splitting
filename expansion
The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and filename expansion.
```

Bash在执行命令之前,会对命令行进行一系列的扩展(expansions),这些扩展包括花括号扩展(brace expansion)、波浪号扩展(tilde expansion)、**参数和变量扩展**(parameter and variable expansion)、**算术扩展(arithmetic expansion)、命令替换(command substitution)**、单词分割(word splitting)和文件名扩展(filename expansion)等,最重要的是这些扩展的顺序是固定的,而且是从左到右进行的。

也就是说,bash shell 会先对命令行中的花括号进行扩展,然后再对波浪号进行扩展,依次类推,直到完成所有的扩展为止。

我们上面的操作都是基于 **算术扩展和命令替换** 而八进制转义也就是 $'\xxx\xxx' 的执行则是依赖于**参数和变量扩展**

所以当把这一些列运算符解析成八进制转义的时候,已经执行过一次**参数和变量扩展**了,所以不会再次解析。

所以这里我们引入Linux Bash Shell的Here string语法(https://bash.cyberciti.biz/guide/Here_strings)

让八进制转义作为标准输入再完成一次解析:

```
bin/bash<<