Closed integeruser closed 6 years ago
What’s going on is that the send()s both complete before the first read() completes. You’re sending data too fast.
There is no way to guarantee buffer contents. That’s not how the read(2) syscall works.
I would recommend inserting a call like io.recvuntil(“read: “) between the sends, so that you know the target program has processed your data. On Sat, Feb 24, 2018 at 12:28 PM Francesco Cagnin notifications@github.com wrote:
Consider the following C program, containing two consecutive calls to read() (as in countless CTF challenges):
root@dec7debf5e1f:/tmp# cat test.c
include
include
void getdata() { char buf[1024] = {0};
int n = read(fileno(stdin), buf, 1024); printf("read: '%s' (%d bytes)\n", buf, n);
} int main(int argc, char const *argv[]) { getdata(); getdata(); return 0; }
I want to interact with this program in such a way that it reads the string AAAA in the first call to read() and reads BBBB in the second call. With any terminal emulator, I can do this by pressing Ctrl+D (which should send an EOF signal) after typing each of the two strings:
root@dec7debf5e1f:/tmp# gcc -o test test.c root@dec7debf5e1f:/tmp# ./test AAAAread: 'AAAA' (4 bytes) BBBBread: 'BBBB' (4 bytes)
How can I achieve the same behaviour consistently using pwntools? Two send()s do not always result in two read()s by the receiving program (not even sure if this is a bug or is expected):
root@dec7debf5e1f:/tmp# cat test.py#!/usr/bin/env python2# -- coding: utf-8 --from pwn import *
argv = ['./test'] envp = {}
io = process(argv=argv, env=envp)
io.send('AAAA') io.send('BBBB')
io.interactive()
root@dec7debf5e1f:/tmp# PWNLIB_DEBUG=1 python2 ./test.py [+] Starting local process './test' env={} : pid 488 [DEBUG] Sent 0x4 bytes: 'A' 0x4 [DEBUG] Sent 0x4 bytes: 'B' 0x4 [] Switching to interactive mode [] Process './test' stopped with exit code 0 (pid 488) [DEBUG] Received 0x2e bytes: "read: 'AAAA' (4 bytes)\n" "read: 'BBBB' (4 bytes)\n" read: 'AAAA' (4 bytes) read: 'BBBB' (4 bytes) [*] Got EOF while reading in interactive
root@dec7debf5e1f:/tmp# PWNLIB_DEBUG=1 python2 ./test.py [+] Starting local process './test' env={} : pid 493 [DEBUG] Sent 0x4 bytes: 'A' 0x4 [DEBUG] Sent 0x4 bytes: 'B' 0x4 [*] Switching to interactive mode [DEBUG] Received 0x1b bytes: "read: 'AAAABBBB' (8 bytes)\n" read: 'AAAABBBB' (8 bytes)$
(tested using the Dockerfile pwntools/pwntools:stable after updating to pwntools 3.12.0)
I have spent some time reading about PTYs and related but I still have no idea on how to "flush" after a send() (like Ctrl+D) with pwntools. Until now, I worked around this by inserting short sleep()s immediately after sending data, but even so it still does not work consistently and is often source of frustration.
I'd really appreciate if someone could explain what's going on here and which is the correct way to handle these situations.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Gallopsled/pwntools/issues/1116, or mute the thread https://github.com/notifications/unsubscribe-auth/AAG0GEST9Nhf_T2v-EcZ_1bLTuu2ow8Lks5tYFTGgaJpZM4SR_bJ .
Ah, now it's clear. Thanks!
Consider the following C program, containing two consecutive calls to
read()
(as in countless CTF challenges):I want to interact with this program in such a way that it reads the string
AAAA
in the first call toread()
and readsBBBB
in the second call. With any terminal emulator, I can do this by pressingCtrl
+D
(which should send anEOF
signal) after typing each of the two strings:How can I achieve the same behaviour consistently using
pwntools
? Twosend()
s do not always result in tworead()
s by the receiving program (not even sure if this is a bug or is expected):(tested using the Dockerfile
pwntools/pwntools:stable
after updating topwntools 3.12.0
)I have spent some time reading about PTYs and related but I still have no idea on how to "flush" after a
send()
(likeCtrl
+D
) withpwntools
. Until now, I worked around this by inserting shortsleep()
s immediately after sending data, but even so it still does not work consistently and is often source of frustration.I'd really appreciate if someone could explain what's going on here and which is the correct way to handle these situations.