'Trying to run a buffer-overflow with Python/pwntools
I work on a online program in which I should do a buffer Overflow.
When I run the program, I have to complete a sum of two numbers generated randomly) :
>>> 451389913 + 1587598959 =
If I put the right result, I get a "That's okay". Otherwise the console writes "Try it again".
I decompiled the program with Ghidra and get the following code in the main()
function :
{
int iVar1;
char local_9 [36];
int local_42;
uint local_6;
uint local_f;
local_f = rand();
local_6 = rand();
local_42 = local_6 + local_f;
printf(">>> %d + %d = ",(ulong)local_f,(ulong)local_6);
fflush(stdout);
fgets(local_9,100,stdin);
iVar1 = atoi(local_9);
if (local_42 == iVar1) {
puts("That's ok");
}
else {
puts("Try it again");
}
return 0;
}
I notice a fgets
function that make me suppose I can do the buffer overflow just before the sum. I also see that the local9
variable is composed of 36 characters. So I suppose that at the beginning of the payload, there must be 36 characters.
I began to write the following snippet with the pwntools Python library :
import pwn
offset = 36
payload = b'A'*offset + b'[.....]'
c = pwn.remote("URL",Port)
c.sendline(payload)
c.interactive()
The thing is I know I have to write something after the b'A'*offset
but I don't really see what to add.. My difficulty is to join that sum of random numbers to the payload.
Is it possible to do it ?
Any ideas would be very appreciated, thanks
Solution 1:[1]
Of course, it's possible, pwn is the swiss army knife for CTFs.
# string = c.recv()
# assuming the string you receive is this
string = b">>> 451389913 + 1587598959 ="
# receive expression as bytes
# convert it into utf8 string for convenience
# split() splits the string at whitespaces and store them as array elements
expression = string.decode("utf8").split()
# covert string to int for to get logical sum instead of literal
solution = int(expression[1])+int(expression[3])
c.sendline(payload)
However, in a more challenging scene, where the server might ask you multiple answers with division or difference you'd have to change operators as needed. And I'd rather use operator lib than write a bunch of ifs.
import operator
ops = {
'+' : operator.add,
'-' : operator.sub,
'*' : operator.mul,
'/' : operator.truediv
}
string = b">>> 451389913 + 1587598959 ="
expression = string.decode("utf8").split()
solution = ops[expression[2]](int(expression[1]), int(expression[3]))
c.sendline(solution)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | xicc |