2017-09-20 62 views
2

我用一些二進制挑戰SSHd到遠程服務器。在tty上寫非ASCII字符到程序的stdin(通過ssh)

有一次,它要求我輸入文字。我知道它使用fgets()來讀取stdin,並且我可以溢出它被複制到並覆蓋附近變量的位置。

的問題是我不知道如何鍵入我所需要的地址值,\x84\x04等。如果我能夠使用bash我會echo -ne "\x84"或使用C六角陣列,但我不能做那種這裏的東西。

我試過使用十六進制ASCII轉換器和複製二進制字符,也使用期望腳本發送二進制值,但都有同樣的問題。 x84增加了一個額外的字符,x04根本不會寫入。

任何想法最好的方法來可靠地寫入值的內存,不能用Unix上的tty上的ASCII字符通過ssh表示?

+1

你的問題很混亂。您是問如何在終端上輸入控制字符,或者C程序如何將它讀入內存? – Barmar

+0

如果你使用二進制數據,你不應該使用'fgets()'和朋友。這是爲了讀取文本數據。 –

+0

對不起,我現在正在使用我的手機。可能是前者。如果我寫AAAA,我會在內存中獲得x41x41x41x41等。如果我寫\ x84它會寫x78x38x34等。我在編寫十六進制值時遇到了困難,因爲fgets將所有內容解釋爲ascii,而且似乎不允許使用轉義序列。 – GhostSparkles

回答

3

對於高字符,您可能可以複製/粘貼。

例如echo -ne "\x84" | xclip -i然後在您的終端模擬器中單擊,如果您的桌面也在運行Linux。 (或可能不是,見)。或者echo ... | ssh [email protected]可以工作。

ssh -T或其他任何終端仿真程序中的等價物也可能是「禁用僞終端分配」的選項,因此遠程端的程序將使其stdin成爲sshd的管道而不是僞 - 終端,我想。這可能會導致像^s^v這樣的東西變得很特殊,我想。

相反,echo foo | ssh -tt會強制它在遠程端請求一個tty,即使你將東西輸入到ssh中。


A-侵入較少的方法以確保二進制數據通過SSH獲取通過TTY層和接收程序的stdin是每字節與一個控制v(十六進制0x16)之前。

正如Barmar指出的那樣,這是字面上的下一個字符(lnextstty -a輸出)。您可以在之前每字節使用它;它甚至在普通字符之前被接收器中的TTY層剝離。

# LANG=C sed to replace every byte with ^V byte 
# using bash $'' to put a literal control-V on sed's command line 
echo "hello" | LANG=C sed $'s/./\x16&/g' | hd 
     16 68 16 65 16 6c 16 6c 16 6f 0a     |.h.e.l.l.o.| 

您可以通過輸入到hexdump -C(又名hd)測試這個本地所有。只需在終端中運行它,然後鍵入或粘貼一些內容,然後控制-D直到它退出。

$ echo -ne "\x01\xff\x99" | LANG=C sed $'s/./\x16&/g' | hd 
00000000 16 01 16 ff 16 99         |......| 
00000006 
     # yup, correct bytes from sed 
$ echo -ne "\x01\xff\x99" | LANG=C sed $'s/./\x16&/g' | xclip -i 
$ LANG=C hd 
^A��  (middle click, return, control-d) 
00000000 01 ef bf bd ef bf bd 0a       |........| 
    # nope, that munged my data :/ 

$ xclip -o | hd 
00000000 16 01 16 ff 16 99         |......| 

所以X選擇本身是正確的,但是它越來越受Konsole的被改寫的無論是作爲我貼,或通過從Konsole的到hexdump的方式TTY層?後者似乎不太可能;可能這是一個粘貼問題。 Konsole的「編碼」設置是UTF-8。它似乎沒有簡單的ASCII設置。

也許試試LANG=C xterm什麼的,或者只是腳本expect正確發送實際二進制數據到ssh,而不是轉義碼。


當然不處理轉義序列的fgets,任何超過strcpy會。通常C函數不會;但在C編譯器編譯器處理字符串文字中的轉義序列。

+1

'前面的每個字節都帶有control-v(十六進制0x16)',對我來說非常合適。我使用pexpect腳本來發送十六進制。 對Barmar的回答很好的延伸。 Upvoted兩個。 '它被接收器中的TTY層剝離,甚至在普通人物的非常有趣的信息之前,謝謝! – GhostSparkles

3

通過在鍵盤上輸入控制字符,可以編寫0x000x1f範圍內的字符。按住控制鍵,同時在此ASCII Chart的第三列中鍵入一個字符以獲取第一列中的相應代碼。

一些控制字符具有特殊意義的終端驅動器(例如CTL -C殺死進程),則可以通過用CTL-V前述手動鍵入它們。

而且你可以通過鍵入CTL-V刪除得到0x7f(這是落後刪除字符,這可能是labeld Backspace鍵,而不是向前刪除,可能是在一個單獨的鍵盤)。

我不確定是否有任何簡單的方法來輸入上面的字符。根據終端仿真器中的設置,您可以通過在輸入相應的ASCII字符時按住鍵來保持高位設置。例如。 Alt-A將發送0xc10x80 | 0x41)。

+0

如果您可以克服終端中的任何UTF-8假設,您也可以複製/粘貼高位設置的數據。 ' –