- 简介
- 一、基础知识篇
- 二、工具篇
- 三、分类专题篇
- 四、技巧篇
- 五、高级篇
- 六、题解篇
- 6.1 Pwn
- 6.1.1 pwn HCTF2016 brop
- 6.1.2 pwn NJCTF2017 pingme
- 6.1.3 pwn XDCTF2015 pwn200
- 6.1.4 pwn BackdoorCTF2017 Fun-Signals
- 6.1.5 pwn GreHackCTF2017 beerfighter
- 6.1.6 pwn DefconCTF2015 fuckup
- 6.1.7 pwn 0CTF2015 freenote
- 6.1.8 pwn DCTF2017 Flex
- 6.1.9 pwn RHme3 Exploitation
- 6.1.10 pwn 0CTF2017 BabyHeap2017
- 6.1.11 pwn 9447CTF2015 Search-Engine
- 6.1.12 pwn N1CTF2018 vote
- 6.1.13 pwn 34C3CTF2017 readme_revenge
- 6.1.14 pwn 32C3CTF2015 readme
- 6.1.15 pwn 34C3CTF2017 SimpleGC
- 6.1.16 pwn HITBCTF2017 1000levels
- 6.1.17 pwn SECCONCTF2016 jmper
- 6.1.18 pwn HITBCTF2017 Sentosa
- 6.1.19 pwn HITBCTF2018 gundam
- 6.1.20 pwn 33C3CTF2016 babyfengshui
- 6.1.21 pwn HITCONCTF2016 Secret_Holder
- 6.1.22 pwn HITCONCTF2016 Sleepy_Holder
- 6.1.23 pwn BCTF2016 bcloud
- 6.1.24 pwn HITCONCTF2016 HouseofOrange
- 6.1.25 pwn HCTF2017 babyprintf
- 6.1.26 pwn 34C3CTF2017 300
- 6.1.27 pwn SECCONCTF2016 tinypad
- 6.1.28 pwn ASISCTF2016 b00ks
- 6.1.29 pwn Insomni'hackteaserCTF2017 TheGreatEscapepart-3
- 6.1.30 pwn HITCONCTF2017 Ghostinthe_heap
- 6.1.31 pwn HITBCTF2018 mutepig
- 6.1.32 pwn SECCONCTF2017 vmnofun
- 6.1.33 pwn 34C3CTF2017 LFA
- 6.1.34 pwn N1CTF2018 memsafety
- 6.1.35 pwn 0CTF2018 heapstorm2
- 6.1.36 pwn NJCTF2017 messager
- 6.1.37 pwn sixstarctf2018 babystack
- 6.1.38 pwn HITCONCMT2017 pwn200
- 6.1.39 pwn BCTF2018 houseofAtum
- 6.1.40 pwn LCTF2016 pwn200
- 6.1.41 pwn PlaidCTF2015 PlaidDB
- 6.1.42 pwn hacklu2015 bookstore
- 6.1.43 pwn 0CTF2018 babyheap
- 6.1.44 pwn ASIS2017 start_hard
- 6.1.45 pwn LCTF2016 pwn100
- 6.2 Reverse
- 6.3 Web
- 6.1 Pwn
- 七、实战篇
- 7.1 CVE
- 7.1.1 CVE-2017-11543 tcpdump sliplink_print 栈溢出漏洞
- 7.1.2 CVE-2015-0235 glibc _nsshostnamedigitsdots 堆溢出漏洞
- 7.1.3 CVE-2016-4971 wget 任意文件上传漏洞
- 7.1.4 CVE-2017-13089 wget skipshortbody 栈溢出漏洞
- 7.1.5 CVE–2018-1000001 glibc realpath 缓冲区下溢漏洞
- 7.1.6 CVE-2017-9430 DNSTracer 栈溢出漏洞
- 7.1.7 CVE-2018-6323 GNU binutils elfobjectp 整型溢出漏洞
- 7.1.8 CVE-2010-2883 Adobe CoolType SING 表栈溢出漏洞
- 7.1.9 CVE-2010-3333 Microsoft Word RTF pFragments 栈溢出漏洞
- 7.1 CVE
- 八、学术篇
- 8.1 The Geometry of Innocent Flesh on the Bone: Return-into-libc without Function Calls (on the x86)
- 8.2 Return-Oriented Programming without Returns
- 8.3 Return-Oriented Rootkits: Bypassing Kernel Code Integrity Protection Mechanisms
- 8.4 ROPdefender: A Detection Tool to Defend Against Return-Oriented Programming Attacks
- 8.5 Data-Oriented Programming: On the Expressiveness of Non-Control Data Attacks
- 8.7 What Cannot Be Read, Cannot Be Leveraged? Revisiting Assumptions of JIT-ROP Defenses
- 8.9 Symbolic Execution for Software Testing: Three Decades Later
- 8.10 AEG: Automatic Exploit Generation
- 8.11 Address Space Layout Permutation (ASLP): Towards Fine-Grained Randomization of Commodity Software
- 8.13 New Frontiers of Reverse Engineering
- 8.14 Who Allocated My Memory? Detecting Custom Memory Allocators in C Binaries
- 8.21 Micro-Virtualization Memory Tracing to Detect and Prevent Spraying Attacks
- 8.22 Practical Memory Checking With Dr. Memory
- 8.23 Evaluating the Effectiveness of Current Anti-ROP Defenses
- 8.24 How to Make ASLR Win the Clone Wars: Runtime Re-Randomization
- 8.25 (State of) The Art of War: Offensive Techniques in Binary Analysis
- 8.26 Driller: Augmenting Fuzzing Through Selective Symbolic Execution
- 8.27 Firmalice - Automatic Detection of Authentication Bypass Vulnerabilities in Binary Firmware
- 8.28 Cross-Architecture Bug Search in Binary Executables
- 8.29 Dynamic Hooks: Hiding Control Flow Changes within Non-Control Data
- 8.30 Preventing brute force attacks against stack canary protection on networking servers
- 8.33 Under-Constrained Symbolic Execution: Correctness Checking for Real Code
- 8.34 Enhancing Symbolic Execution with Veritesting
- 8.38 TaintEraser: Protecting Sensitive Data Leaks Using Application-Level Taint Tracking
- 8.39 DART: Directed Automated Random Testing
- 8.40 EXE: Automatically Generating Inputs of Death
- 8.41 IntPatch: Automatically Fix Integer-Overflow-to-Buffer-Overflow Vulnerability at Compile-Time
- 8.42 Dynamic Taint Analysis for Automatic Detection, Analysis, and Signature Generation of Exploits on Commodity Software
- 8.43 DTA++: Dynamic Taint Analysis with Targeted Control-Flow Propagation
- 8.44 Superset Disassembly: Statically Rewriting x86 Binaries Without Heuristics
- 8.45 Ramblr: Making Reassembly Great Again
- 8.46 FreeGuard: A Faster Secure Heap Allocator
- 8.48 Reassembleable Disassembling
- 九、附录
6.3.1 web HCTF2017 babycrack
题目解析
题目就不用多说了,很容易发现是 JavaScript 代码审计。
整个文件的变量名/函数名可以看作是混淆了的,分析一下整个文件的结构:
——
|- _0x180a,关键字的替换数组
|- 匿名函数,对数组元素进行重排
|- _0xa180,取出对应索引的数组元素
|- check,主要的分析函数
|- test,主要的运行函数
这道题结合浏览器进行动态调试,可以节省很多脑力。
首先是重排,这里不需要去深究到底逻辑原理,让引擎代替你去把数组重排好即可。结合程序员计算器和 CyberChef 分析更加方便。
解题流程
这样我们可以直接进入 check 函数进行分析。
——
|- _0x2e2f8d,又一次进行数组混淆,得到一个新数组
|- _0x50559f,获取 flag 的前四位,即 ‘hctf’
|- _0x5cea12,由 ‘hctf’ 生成一个基数
|- 这里有一个 debug 的事件,个人认为是阻止使用 F12 调试用的,所以可以直接删去
|- 匿名函数,对 _0x2e2f8d 这个数组再进行排列
|- _0x43c8d1,根据输入获取数组中相应值的函数
|- _0x1c3854,将输入的 ascii 码转化为 16 进制,再加上 ‘0x’
以上部分可以看成是准备部分,这一部分的难点在于多次处理了数组,在动态调试时,很多函数如果多次执行就会产生与原答案不同的数组结构,因此,每次执行都需要重新初始化。
——
|- _0x76e1e8,以下划线分割输入,从后面分析可以得知 flag 一共有 5 段
|- _0x34f55b,这一段给出了第一个逆向的条件,结合下一句 if 条件。
单独来分析,其实最初我看掉了一个括号,结果弄混了符号优先级,导致觉得这个条件没有意义。
这个条件是说,第一段的最后两个字符的 16 进制和 ‘{’ 的 16 进制异或后,对第一段的长度求余应该等于 5 。
这里可以先进行如下猜测
第一段,已经有 ‘hctf{’ 了,这里正好去最后两位,先猜测第一段一共只有 7 位,这个猜测是后验的,先不细说。
——
|- b2c
理解这个函数极为重要,通过随机输入进行测试,输出结果有些眼熟,像是 base64 但不对,比对后确定是 base32 编码,知道这个就不用再去多解读它了。同时,这里也有一个 debug 需要删除
——
|- e,第二个逆向条件
这一句是说,第三段做 base32 编码,取等号前的部分,再进行 16 进制和 0x53a3f32 异或等于 0x4b7c0a73
计算 0x4b7c0a73^0x53a3f32=0x4E463541
4E463541 => NF5A 16 进制转字符
NF5A => iz base32 解码
因此,flag 暂时如下 hctf{x_x_iz_x_x}
——
|- f,第三个逆向条件
这一句是说,第四段和第三段一样编码后,和 0x4b7c0a73 异或等于 0x4315332
计算 0x4315332^0x4b7c0a73=0x4F4D5941
4F4D5941 => OMYA
OMYA => s0
flag hctf{x_x_iz_s0_x}
——
|- n,f*e*第一段的长度(先不管)
|- h,将输入字符串的每一个字符 ascii 码进行计算(*第二段长度)
后连接起来显示(字符到 ascii 码转换)
|- j,将第二段以 ‘3’ 分割,又后面可以确定是分成了两部分
|- 第四个逆向条件
首先是,分割的两部份长度相等,第一部分和第二部分 16 进制异或等于 0x1613 ,这个条件只能后验,也先不管。
——
|- k,输入的 ascii 码*第二段的长度
|- l,第一部分逐字符 ascii 码*第二段长度等于 0x2f9b5072
首先,0x2f9b5072 == 798707826
798 707 826
正好分成三个,已知h是对应 ascii 码*常数,
所以假设第一部分有三个字符,那么就是变成了求解常数
也就是 798 707 826 的最大公约数
求解得常数为 7
字符 114 101 118 => rev
所以,第二段一共有 7 个字符,前四个字符为 rev3,带入上面的后验条件 0x1613
0x726576^0x1613=0x727365
727365 => rse
flag hctf{?_rev3rse_iz_s0_?}
——
|- m,第五个逆向条件,第五段的前四位和第一段的长度有关
题目的 hint 提示,每一段都有意义,因此我们这里做个爆破,假设第一段的长度在 6-30 之间,我们可以算出 n,在用 n 去算第五段前四位。
n = f*e*(6-30)
第五段前四位 = n % 0x2f9b5072 + 0x48a05362
代码:
import binascii
for i in range(6,31):
n = 0x4315332*0x4b7c0a73*i
strings = n%0x2f9b5072 + 0x48a05362
print binascii.a2b_hex(str(hex(strings))[2:-1])
从结果中可以看到大多数字符都没有意义,除了 h4r 让人遐想联翩,可惜还是不全,但是结合已经分析出的 flag,猜测应该是 h4rd。
flag hctf{??_rev3rse_iz_s0_h4rd?}
——
|- _0x5a6d56,将输入重复指定次数组合
|- 第六个逆向条件和第七个逆向条件
- 第五段的第六位重复两次不等于倒数第 5-8 位,这个条件也让人摸不着头脑。
- 第五段倒数第 2 位等于第五段第五位加 1
- 第五段第 7-8 位去掉 0x 等于第五段第 7 位的 ascii 码*第五段长度*5
- 第五段第五位为 2,第五段 7-8 位等于第五段第 8 位重复两次
- 结合 hint
由以上条件可以推出以下 flag
hctf{??_rev3ser_iz_s0_h4rd2?3??3333}
先假设 2 和 3 之间没有数字了,这时 7-8 位还未知但是 7-8 位相同,这时的方程
而且在这里,由于直接把 0x 去掉,所以 x 的 16 进制一定全为数字
字符拼接 {hex(x)hex(x)} = ascii(x)*13*5
爆破代码:
import binascii
for i in range(1,128):
string1 = hex(i)[2:]
try:
if int(string1+string1) == i*13*5:
print chr(i)
except:
continue
output:
e
验证前面的后验条件可以确定如下 flag
hctf{??_rev3ser_iz_s0_h4rd23ee3333}
只剩下最前面的两位,为了方便,利用题目提供的 sha256 结果,我就不回溯条件在判断,直接进行碰撞。
import hashlib
a = 'hctf{'
b = '_rev3rse_iz_s0_h4rd23ee3333}'
e1 = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k',
'l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
e2 = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k',
'l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
for i in e1:
for j in e2:
sh = hashlib.sha256()
sh.update(a+i+j+b)
if sh.hexdigest() == "d3f154b641251e319855a73b010309a168a12927f3873c97d2e5163ea5cbb443":
print a+i+j+b
output:
hctf{j5_rev3rse_iz_s0_h4rd23ee3333}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论