问题
I'm SSHd into a remote server with some binary challenges.
At one point it asks for me to input text. I know it's using fgets()
to read stdin
, and that I can overflow where it is being copied to and overwrite a nearby variable.
The problem is I don't know how to type the address values I need, \x84
and \x04
etc. If I were able to use bash I would echo -ne "\x84"
or use a C hex array but I can't do that kind of thing here.
I've tried using a hex to ASCII converter and copying the binary character and also using expect script to send the binary values but both have the same issue. x84 adds an extra char and x04 won't write at all.
Any idea the best way to reliably write values to memory that can't be represented by ASCII characters over ssh on a Unix tty?
回答1:
For high characters, you can probably copy/paste.
e.g. echo -ne "\x84" | xclip -i
then middle-click in your terminal emulator, if your desktop is also running Linux. (or maybe not, see below). Or echo ... | ssh user@host
could work.
ssh -T
or the equivalent in any other terminal emulator might also be an option, to "Disable pseudo-terminal allocation", so the program on the remote side would have its stdin
be a pipe from sshd, rather than a pseudo-terminal, I think. This would disable stuff like ^s
and ^v
being special, I think.
Conversely, echo foo | ssh -tt
will force it to request a tty on the remote side, even though you're piping stuff into ssh.
A less-intrusive way to make sure binary data over SSH gets through the TTY layer and to the stdin
of the receiving program is to precede every byte with a control-v
(hex 0x16).
As Barmar points out, that's the literal-next character (lnext
in stty -a
output). You can use it before every byte of your payload; it's stripped by the TTY layer in the receiver even before ordinary characters.
# 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.|
You can test all this locally by typing into hexdump -C
(aka hd
). Just run it in a terminal, and type or paste some stuff, then control-D until it exits.
$ 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 |......|
So the X selection itself is correct, but it's getting munged either by Konsole as I paste, or by the TTY layer on the way from Konsole to hexdump
? The latter seems unlikely; probably it's a paste problem. Konsole's "encoding" setting is UTF-8. It doesn't seem to have a plain ASCII setting.
Maybe try with LANG=C xterm
or something, or just script expect
correctly to send actual binary data to ssh
, rather than escape codes.
fgets
of course does not process escape sequences, any more than strcpy
would. In general C functions don't; but in C the compiler processes escape sequences inside string literals at compile time.
回答2:
You can write characters in the range 0x00
to 0x1f
by typing control characters on the keyboard. Hold down the Control key while typing a character in the third column of this ASCII Chart to get the corresponding code in the first column.
Some control characters have special meaning to the terminal driver (e.g. Ctl-c to kill the process), you can type them literally by preceding with Ctl-v.
And you can get 0x7f
by typing Ctl-vDelete (this is the backward delete character, which might be labeld Backspace, not the forward delete that may be in a separate keypad).
I'm not sure if there's any easy way to type characters above this. Depending on the settings in your terminal emulator, you might be able to get the high bit set by holding the Alt key while typing the corresponding ASCII character. E.g. Alt-A would send 0xc1
(0x80 | 0x41
).
来源:https://stackoverflow.com/questions/46329447/write-non-ascii-characters-to-stdin-of-a-progam-on-a-tty-over-ssh