引言
SSH協議支持三大類遠程服務器活動:a) 命令執行(包括登錄shell),b) 網絡轉發和操作,以及c) 文件傳輸。
OpenSSH維護者已確定sftp和scp對端口轉發(通過-L和-R選項)沒有合法用途。在使用這些實用程序進行文件傳輸期間,一個明確禁用這些功能的標誌會被無條件地傳遞給子SSH可執行文件。
某些用戶可能確實需要這些功能。一個明顯的子集是滲透測試人員,他們的任務是驗證此功能是否在公共SFTP服務器上被明確禁用。
以下是兩種啟用這些被抑制功能的技術,方法是修改sftp二進製文件本身的字符串,或通過能夠輕鬆編輯命令行的shell進行重定向。根據平台的功能,可能需要任一技術才能實現此目標。
抑制細節
首先,重要的是找到感興趣的運行進程。下面的shell函數將顯示與shell模式匹配的PID(請注意,這不是正則表達式)。這在Debian dash(和大多數其他常用shell)下運行,並依賴於BSD的ps選項:
<code>pps () { local a= b= c= IFS=$'\r'; ps ax | while read -ra do [ "$b" ] || c=1; for b; do case "$a" in *"$b"*) c=1;; esac; done; [ "$c" ] && printf '%s\n' "$a" && c=; done; }</code>
啟動一個傳統的SFTP會話,以檢查與其相關的進程:
<code>$ id uid=1001(aturing) gid=1001(aturing) groups=1001(aturing)... $ sftp aturing@sftp.victimandum.com aturing@sftp.victimandum.com's password: Connected to sftp.victimandum.com. sftp></code>
我們假設上面的本地UNIX用戶在遠程SFTP服務器上擁有相同用戶名帳戶。
會話運行後,對用戶名進行本地進程搜索將顯示由SFTP生成的子SSH進程:
<code>$ pps aturing PID TTY STAT TIME COMMAND 9666 pts/0 S 0:00 sftp aturing@sftp.victimandum.com 9667 pts/0 S 0:00 /usr/bin/ssh -oForwardX11 no -oPermitLocalCommand no -oClearAllForwardings yes -oForwardAgent no -l aturing -s -- sftp.victimandum.com sftp</code>
上面的ClearAllForwardings yes參數將抑制任何轉發嘗試,而無需採取任何措施來破壞它。
-L和-R端口轉發標誌並非作為SFTP命令行的有效選項存在,但我們可以使用-S選項明確觸發它們以指定自定義SSH處理程序,在本例中為郵件服務器:
<code>$ cat portssh #!/bin/sh exec ssh -L2525:smtp.victimandum.com:25 "$@"</code>
如果轉發抑制沒有到位,則此SFTP調用足以建立轉發連接:
<code>$ sftp -S ./portssh -oClearAllForwardings\ no aturing@sftp.victimandum.com aturing@sftp.victimandum.com's password: Connected to sftp.victimandum.com. sftp></code>
現在可以在子SSH進程中看到轉發嘗試:
<code>$ pps aturing PID TTY STAT TIME COMMAND 9897 pts/0 S 0:00 sftp -S ./portssh -oClearAllForwardings no aturing@sftp.victimandum.com 9898 pts/0 S 0:00 ssh -L2525:smtp.victimandum.com:25 -oForwardX11 no -oPermitLocalCommand no -oClearAllForwardings yes -o ClearAllForwardings no -oForwardAgent no -l aturing -s -- sftp.victimandum.com sftp</code>
但是,由於顯式覆蓋,嘗試通過本地轉發端口聯繫遠程郵件服務器是不成功的:
<code>$ nc localhost 2525 $</code>
此無條件抑制在源代碼中可見:
<code>$ sed -n /X11/,/Forwardings/p openssh-8.7p1/sftp.c addargs(&args, "-oForwardX11 no"); addargs(&args, "-oPermitLocalCommand no"); addargs(&args, "-oClearAllForwardings yes");</code>
這些靜態字符串在編譯後的二進製文件中也可見:
<code>$ strings /usr/bin/sftp | grep [-]o[CFP] -oForwardX11 no -oPermitLocalCommand no -oClearAllForwardings yes -oForwardAgent no -oPort %d</code>
最後,文檔清楚地說明了這種抑制是有意的,並給出了合理的理由:
<code>$ man ssh_config | sed -n /ClearAllForwardings/,/default/p ClearAllForwardings Specifies that all local, remote, and dynamic port forwardings specified in the configuration files or on the command line be cleared. This option is primarily useful when used from the ssh(1) command line to clear port forwardings set in configura‐ tion files, and is automatically set by scp(1) and sftp(1). The argument must be yes or no (the default).</code>
更改編譯後的字符串
對於那些希望禁用默認的ClearAllForwardings yes配置的人來說,一個選項是使用sed直接編輯SFTP二進製文件中的字符串(假設平台的sed是二進制安全的):
<code>$ sed 's/AllForwardings yes/AllForwardings no /' sftp.noclearforward</code>
這種直接修改比編譯新的二進製文件要容易得多。
我們可以確認字符串已成功修改:
<code>$ strings ./sftp.noclearforward | grep [-]o[CFP] -oForwardX11 no -oPermitLocalCommand no -oClearAllForwardings no -oForwardAgent no -oPort %d</code>
雖然修改後的SFTP的內容和校驗和將不同,但任何存在的Linux BuildID sha1都將保持不變(但在使用編輯後的SFTP時,請不要提交支持工單):
<code>$ file /usr/bin/sftp ./sftp.noclearforward /usr/bin/sftp: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=d7e77e24d5fac0fdc89e62a4c9c656091f2c4a33, for GNU/Linux 3.2.0, stripped ./sftp.noclearforward: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=d7e77e24d5fac0fdc89e62a4c9c656091f2c4a33, for GNU/Linux 3.2.0, stripped $ sha1sum /usr/bin/sftp ./sftp.noclearforward d8bdaf0b4642b9c324f9c2e0aeee2d9578fbe383 /usr/bin/sftp b12dda8ecfd7bd2847919b5531aea7c03364c123 ./sftp.noclearforward $ sha256sum /usr/bin/sftp ./sftp.noclearforward 986eecdfc654c9b3ff3fd0dce59690d47cf56be96a4b98a04a3682aef95d3f52 /usr/bin/sftp c8f99ce33fc129250c11dc6dbb8a01112e01124e470a92d0acefb955fd17d670 ./sftp.noclearforward</code>
可以調用修改後的SFTP二進製文件來啟用端口轉發:
<code>$ chmod 755 sftp.noclearforward $ ./sftp.noclearforward -S ./portssh aturing@sftp.victimandum.com aturing@sftp.victimandum.com's password: Connected to sftp.victimandum.com. sftp></code>
現在可以在子進程中看到修改後的設置:
<code>$ pps aturing PID TTY STAT TIME COMMAND 9991 pts/0 S 0:00 ./sftp.noclearforward -S ./portssh aturing@sftp.victimandum.com 9992 pts/0 S 0:00 ssh -L2525:smtp.victimandum.com:25 -oForwardX11 no -oPermitLocalCommand no -oClearAllForwardings no -oForwardAgent no -l aturing -s -- sftp.victimandum.com sftp</code>
該功能在遠程服務器上已啟用並可運行,並且可以在單獨的shell中驗證連接:
<code>$ nc localhost 2525 220 smtp.victimandum.com Microsoft ESMTP MAIL Service, Version: 1.2.3456.78901 ready at Sun, 1 Jan 2023 01:23:45 -0100 ^C</code>
當服務器上禁用轉發功能時,客戶端將在連接嘗試時收到指示此狀態的通知:
<code>channel 3: open failed: administratively prohibited: open failed</code>
分配不受信任帳戶的SFTP管理員應該可能驗證服務器配置是否明確禁用了轉發和命令執行。
超越POSIX Shell
雖然dash和POSIX標準提供set --作為重置命令行參數的方法,但bash和ksh93中提供了更高級的功能:
<code>$ cat ynargs #!/bin/bash echo "${@//yes/no}"</code>
快速測試確認成功編輯:
<code>$ ./ynargs -oForwardX11 no -oPermitLocalCommand yes -oClearAllForwardings yes -oForwardAgent no -oForwardX11 no -oPermitLocalCommand no -oClearAllForwardings no -oForwardAgent no</code>
請注意,上面的${@//.../...}不是有效的POSIX,並且在dash或任何從pdksh派生的shell(mksh,oksh)中都不能運行。許多平台沒有捆綁具有此功能的shell(例如Android和OpenBSD,儘管有添加它們的方法);對於受限平台,二進制編輯技術可能更直接,而不是安裝替代shell。
要利用具有功能強大的shell的此功能,我們創建一個目錄,然後在其中創建一個清除問題設置的SSH包裝器:
<code>$ cat ~/switcharoo/ssh #!/bin/bash exec /usr/bin/ssh "${@//yes/no}"</code>
然後在$PATH中設置系統SSH之前的目錄:
<code>$ export PATH=~/switcharoo:$PATH $ which ssh ~/switcharoo/ssh</code>
然後,我們在這種修改後的環境下調用系統SFTP:
<code>$ /usr/bin/sftp -S ./portssh aturing@sftp.victimandum.com aturing@sftp.victimandum.com's password: Connected to sftp.victimandum.com. sftp></code>
我們觀察到shell重置了問題參數:
<code>$ pps aturing PID TTY STAT TIME COMMAND 10058 pts/0 S 0:00 /usr/bin/sftp -S ./portssh aturing@sftp.victimandum.com 10059 pts/0 S 0:00 /usr/bin/ssh -L2525:smtp.victimandum.com:25 -oForwardX11 no -oPermitLocalCommand no -oClearAllForwardings no -oForwardAgent no -l aturing -s -- sftp.victimandum.com sftp</code>
再次確認了到轉發端口的本地連接:
<code>$ nc localhost 2525 220 smtp.victimandum.com Microsoft ESMTP MAIL Service, Version: 1.2.3456.78901 ready at Sun, 1 Jan 2023 01:23:45 -0100 ^C</code>
作為最終演示,可以使用以下腳本進行完整的SMTP交換:
<code>$ cat awkmail #!/bin/gawk -f BEGIN { smtp="/inet/tcp/0/localhost/2525"; ORS="\r\n"; r=ARGV[1]; s=ARGV[2]; sbj=ARGV[3]; # /bin/awkmail to from subj 0) print |& smtp print "." |& smtp; smtp |& getline j; print j print "quit" |& smtp; smtp |& getline j; print j close(smtp) } # /inet/protocol/local-port/remote-host/remote-port</code>
我們可以使用該腳本將自身郵件發送到目標SMTP服務器可以訪問的遠程收件人:
<code>$ ./awkmail jatanasoff@victimandum.com aturning@localhost awkmail Queued mail for delivery</code>
在高度受控的環境中,這些功能的存在並非最佳。
服務器限制
可以理解的是,SFTP管理員不希望允許其用戶在服務器的幫助下進行任意TCP連接,這可能會使敏感網絡面臨風險。限制此活動是一種謹慎的安全設置。
常見的限制性配置是將不受信任的SFTP用戶添加到組中,然後在sshd_config中約束此組的活動:
<code>Match Group sftponly ChrootDirectory %h ForceCommand internal-sftp AllowTcpForwarding no</code>
此推薦配置通常足以阻止所有轉發嘗試。
建議添加DisableForwarding yes:
<code>$ man sshd_config | sed -n /DisableForwarding/,/configurations/p DisableForwarding Disables all forwarding features, including X11, ssh-agent(1), TCP and StreamLocal. This option overrides all other forwarding- related options and may simplify restricted configurations.</code>
這留給管理員練習。
結論
過於嚴格的SFTP客戶端設置可能會導致某種程度的服務器管理盲目性。 SFTP客戶端限制很容易通過多種方法規避。
對於SFTP服務器管理員來說,了解哪些地方受到限制以及在哪裡限制非常重要,並且不要依賴客戶端來保護服務器免受任意TCP控制。客戶端受用戶控制,如果配置錯誤,則很難實現對服務器的TCP命令。任何測試都應該在用戶ssh_config中沒有廣泛設置轉發的情況下進行,注意文檔中的警告。
雖然這種功能可能有可以想像的合法用途,但濫用行為將很少見。
這些問題並非新鮮事物,因為站點exec的變體幾十年來一直存在於明文FTP中。 SFTP並不是明文文件傳輸的簡單替代品,它本身也具有許多易於利用的功能。
希望管理員能夠使用這些方法驗證其服務器的安全性,以免措手不及。
以上是SFTP端口轉發:啟用抑制功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!