Sprintf buffer-overflow - RIP register contains garbage data

0

I try to exploit sprintf c function in my program which is used like this:

char line[512];
sprintf(line,"[%s]", UserCommand);

As you can see the line can be exploited and trigger something else. I found how to change rbp register but when it comes to RIP register, I can change it with "0xFFFF7FFFEBFF8C10" but I couldn't with "0x00007FFFEBFF8C10", the first 2 bytes "00 00" are replaced with 0x2D5D ( ]) which becomes 0x2D5D7FFFEBFF8C10. This address cannot lead me to my buffer where my arbitrary code reside.

The stack $rsp-100: 0x7fffebff8d94: 0xd23148f6 0x3bc08348 0xebe8050f 0x2fffffff 0x7fffebff8da4: 0x2f6e6962 0x4168732f 0x41414141 0x41414141 0x7fffebff8db4: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffebff8dc4: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffebff8dd4: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffebff8de4: 0xffffffff 0x41414141 0x0000155a 0x41414141 0x7fffebff8df4: 0x41414141 0xebff8c10 0x205d7fff 0x00000000 0x7fffebff8e04: 0x00000000 0x00bd5760 0x00000000 0x00000000

Backtrace in gdb: 0 0x00000000004093a0 in ProcessCmd (Ctx=40, Connect=27, Msg=0x7fffebff9e32 '\220' <repeats 200 times>..., Len=522) at /home/sam/srv/cmd/proc.c:305 1 0x205d7fffebff8c10 in ?? () 2 0x0000000000000000 in ?? ()

Register:

info r
rax            0xffffffff       4294967295
rbx            0x7fffebfff700   140737152808704
rcx            0x7ffff78cb1fd   140737346580989
rdx            0x919f40 9543488
rsi            0x0      0
rdi            0x919f40 9543488
rbp            0x4141414141414141       0x4141414141414141
rsp            0x7fffebff8df8   0x7fffebff8df8
r8             0x0      0
r9             0x29     41
r10            0x11     17
r11            0x0      0
r12            0x1      1
r13            0x7fffebfff9c0   140737152809408
r14            0x7fffebfff700   140737152808704
r15            0x0      0
rip            0x4093a0 0x4093a0 <ProcessCmd+407>
eflags         0x10202  [ IF RF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0

I want to know if this can be exploited or not ?

Is there any way to have a valid canonical address in the RIP register and remove the 2 bytes that making my address invalid ?

Thanks in advance

c
printf
buffer-overflow
exploit
asked on Stack Overflow Nov 7, 2019 by Bugger • edited Nov 8, 2019 by Bugger

1 Answer

0

sprintf(line,"[%s] ", UserCommand);, sprintf will write '[' to line, then your input which is NULL terminated string, then ']', ' ', and last NULL terminator. Suppose you enter the string containing the shellcode and end with a return address. As you know that %s format speicfier will STOP writing this input when it finds a NULL byte.

Case 1:

Non_NULL_Shellcode = Your_shellcode
Return_address = 0xFFFF7FFFEBFF8C10

As you can see, no NULL byte in your input. So sprintf will write '[' to line, then your input which is NULL terminated string containing shellcode and complete return address, then ']', ' ', and last NULL terminator. It works well.

Case 2:

Non_NULL_Shellcode = Your_shellcode
Return_address = 0x00007FFFEBFF8C10

What is the difference? Yes, your return address containing two NULL byte at the end, which is interpreted by sprintf as a marker to STOP writing from your input. So this will happen. sprintf will write '[' to line, then your input which is NULL terminated string containing shellcode and incomplete return address, then ']', ' ', and last NULL terminator. ']' == 0x5d and ' ' == 0x20 in ascii. When writing your return address (suppose in little endian) sprintf will write 0x10, 0x8C, 0xFF, 0xEB, 0xFF, 0x7F and continue write 0x5D, 0x20, and last 0x00 which is NULL terminator. So it explain why your address 0x00007FFFEBFF8C10 changes to 0x205D7FFFEBFF8C10. 0x205D is not garbage data it's your string. Hope it helpful :).

answered on Stack Overflow Mar 29, 2021 by whoami • edited Mar 30, 2021 by whoami

User contributions licensed under CC BY-SA 3.0