Passing Input

Often, you need to pass hex input to your programs, which may be difficult to do. Here are some techniques to accomplish this.

Pwntools

Pwntools is really useful for passing data, both locally and remotely.

Sending data over the network using PwnTools

Connect:

io = pwn.remote(RHOST, RPORT)

Receive data:

# Receive until newline
io.recvline()

# Receive an EXACT NUMBER of bytes
io.recvn(length) 

# Receive UP TO a number of bytes and RETURN IMMEDIATELY when data becomes available. 
# Warning: You might not get all the data this way.
io.recv(length) 

Send data:

io.send(bytes)

Convert values to bytes:

pwn.p32(value)

Receive as much input as you're given:

while io.can_recv():
    print(io.recv())

Passing input to program parameters

Passing hex to gdbserver

gdbserver 0.0.0.0:22222 ./target "$(perl -e 'print "\x41\x41\x41\x41\x41\x41"')"

Passing hex to gdb

This is a bit convoluted but it works:

gdb --args ./target "$(perl -e 'print "\x41\x41\x41\x41"')"

Passing hex to radare2

Warning: This didn't work properly for a more complex payload :(

You'll probably have better luck if you start up a gdbserver with hex parameters and then connect to that gdbserver using radare2. But it might still be unreliable. Honestly, GDB sucks but at least it's reliable, so consider using that...

You need to make a radare2 profile, args.rr2:

#!/usr/bin/rarun2
arg1=\x41\x41\x41\x41

Then pass in that profile:

r2 -A -d -r args.rr2 myexecutable

Passing hex using echo

You can use echo -e:

echo -e '\x41'
A

Or you can use this:

echo  $'\x41'
A

The following will pass the letter “A” to some-program as a program parameter:

./some-program "$(echo -n -e '\x41')"

Warning: This doesn't want to work well together with radare2, which inserts unnecessary symbols (like a `\` symbol before a space)

Here's how I got the hex representation of a payload. I'm sure there's a better way to do it, but it works:

for i in payload: print('{}{}'.format('\\x', hex(i)[2:]), end='')

Passing input to read()

Passing hex using Python

You can create a script to output the necessary bytes. Take a look at this Solution for an example.

Passing hex from stdin during program execution

Timestamped explanation

If you want to pass hex on the command line by typing it in yourself via stdin, then this is one way to do it:

echo -e "$(cat -)" | ./net-zero 

You’re reading stdin with cat, passing that into echo -e and piping it into net-zero. The good thing is that you don’t have to read the input before the program is executed, you can do it while it’s executed.

So what will happen is that net-zero will execute and ask for your input. You can type in some input, for example \xae\r\x7fJ , add a newline and press CTRL+d. CTRL+d passes the END OF TRANSMISSION byte to cat, which stops reading from stdin and passes the input to the program.

If you’re wondering where the \xae\r\x7fJ came from, then that is the format string representation of the integer 1249840558, which I got using Python:

python
>>> import struct
>>> struct.pack("I",1249840558)
'\xae\r\x7fJ'

Passing predefined input and then reading from stdin

This will read predefined input from input.txt into stack-five, after which input from stdin will be passed. This is useful for getting a shell and then passing commands to that shell from stdin.

(cat ~/input.txt; cat) | /opt/phoenix/amd64/stack-five

Last updated