- 简介
- 一、基础知识篇
- 二、工具篇
- 三、分类专题篇
- 四、技巧篇
- 五、高级篇
- 六、题解篇
- 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.2.2 re ECTF2016 tayy
章节 5.8.1 中讲解了 Z3 约束求解器的基本使用方法,通过这一题,我们可以更进一步地熟悉它。
题目解析
Tayy is the future of AI. She is a next level chatbot developed by pro h4ckers at NIA Labs. But Tayy hides a flag. Can you convince her to give it you?
$ file tayy
tayy: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=1fcd1c49eae4807f77d51227a3b457d8874170b4, not stripped
$ ./tayy
=============================================================
Welcome to the future of AI, developed by NIA Research, Tayy!
=============================================================
1. Talk to Tayy.
2. Flag?
0. Exit.
> 2
Flag: EEXL�▒#@N5&[g,q2H7?09:G>4!O]iJ('
V
=============================================================
1. Talk to Tayy.
2. Flag?
0. Exit.
> 1
=============================================================
1. Ayy lmao, Tayy lmao.
2. You are very cruel.
3. Memes are lyf.
4. Go away!.
5. zzzz
6. Cats > Dogs.
7. Dogs > Cats.
8. AI is overrated?.
9. I dont like you.
0. <exit to menu>
> 1
Tayy: Die, human!
=============================================================
1. Talk to Tayy.
2. Flag?
0. Exit.
> 2
Flag: EFZO�*$IX@2hv<�D[KTFPR`XO=l{�jII-z
=============================================================
玩了一会儿我们发现:
- 每次我们与 Tayy 交谈后,flag 就会变
- 最多可以交谈 8 次,然后程序退出
通过调试,我们首先发现了 flag 的初始值:
gdb-peda$ n
[----------------------------------registers-----------------------------------]
RAX: 0x0
RBX: 0x0
RCX: 0x0
RDX: 0x7ffff7dd4710 --> 0x0
RSI: 0x7fffffffe460 --> 0x231819834c584545
RDI: 0x400d2c ("Flag: %s\n")
RBP: 0x7fffffffe490 --> 0x400a70 (<__libc_csu_init>: push r15)
RSP: 0x7fffffffe450 --> 0x2
RIP: 0x4009e5 (<main+292>: call 0x4005c0 <printf@plt>)
R8 : 0x7fffffffdf11 --> 0x3f00007ffff7ff00
R9 : 0xa ('\n')
R10: 0x0
R11: 0xa ('\n')
R12: 0x400630 (<_start>: xor ebp,ebp)
R13: 0x7fffffffe570 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x4009d8 <main+279>: mov rsi,rax
0x4009db <main+282>: mov edi,0x400d2c
0x4009e0 <main+287>: mov eax,0x0
=> 0x4009e5 <main+292>: call 0x4005c0 <printf@plt>
0x4009ea <main+297>: jmp 0x4009f6 <main+309>
0x4009ec <main+299>: mov edi,0x400d38
0x4009f1 <main+304>: call 0x4005a0 <puts@plt>
0x4009f6 <main+309>: mov eax,DWORD PTR [rip+0x201688] # 0x602084 <num2>
Guessed arguments:
arg[0]: 0x400d2c ("Flag: %s\n")
arg[1]: 0x7fffffffe460 --> 0x231819834c584545
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe450 --> 0x2
0008| 0x7fffffffe458 --> 0x7fffffffe460 --> 0x231819834c584545
0016| 0x7fffffffe460 --> 0x231819834c584545
0024| 0x7fffffffe468 --> 0x67035b26354e401c
0032| 0x7fffffffe470 (",q2H7?09:G>4!O]iJ('\nV")
0040| 0x7fffffffe478 (":G>4!O]iJ('\nV")
0048| 0x7fffffffe480 --> 0x560a27284a ("J('\nV")
0056| 0x7fffffffe488 --> 0x74941753df1a500
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x00000000004009e5 in main ()
gdb-peda$ x/s 0x7fffffffe460
0x7fffffffe460: "EEXL\203\031\030#\034@N5&[\003g,q2H7?09:G>4!O]iJ('\nV"
gdb-peda$ x/37x 0x7fffffffe460
0x7fffffffe460: 0x45 0x45 0x58 0x4c 0x83 0x19 0x18 0x23
0x7fffffffe468: 0x1c 0x40 0x4e 0x35 0x26 0x5b 0x03 0x67
0x7fffffffe470: 0x2c 0x71 0x32 0x48 0x37 0x3f 0x30 0x39
0x7fffffffe478: 0x3a 0x47 0x3e 0x34 0x21 0x4f 0x5d 0x69
0x7fffffffe480: 0x4a 0x28 0x27 0x0a 0x56
然后是一个有趣的函数 giff_flag
,它在每次交谈是被调用,作用是修改 flag。
[0x00400630]> pdf @ sym.giff_flag
/ (fcn) sym.giff_flag 264
| sym.giff_flag ();
| ; var int local_1ch @ rbp-0x1c
| ; var int local_18h @ rbp-0x18
| ; var int local_4h @ rbp-0x4
| ; CALL XREF from 0x004009c3 (main)
| 0x004007b9 55 push rbp
| 0x004007ba 4889e5 mov rbp, rsp
| 0x004007bd 48897de8 mov qword [local_18h], rdi
| 0x004007c1 8975e4 mov dword [local_1ch], esi
| 0x004007c4 c745fc000000. mov dword [local_4h], 0
| ,=< 0x004007cb e9d6000000 jmp 0x4008a6
| | ; JMP XREF from 0x004008aa (sym.giff_flag)
| .--> 0x004007d0 8b05ae182000 mov eax, dword [obj.num2] ; eax = num2 ; num2 是交流次数,最大为 8
| :| 0x004007d6 99 cdq
| :| 0x004007d7 c1ea1f shr edx, 0x1f
| :| 0x004007da 01d0 add eax, edx
| :| 0x004007dc 83e001 and eax, 1 ; eax = eax & 1 = num2 % 2
| :| 0x004007df 29d0 sub eax, edx
| :| 0x004007e1 85c0 test eax, eax
| ,===< 0x004007e3 740a je 0x4007ef ; eax == 0 时跳转,即 num2 % 2 == 0
| |:| 0x004007e5 83f801 cmp eax, 1 ; 1
| ,====< 0x004007e8 745e je 0x400848 ; eax == 1 时跳转
| ,=====< 0x004007ea e9b3000000 jmp 0x4008a2
| |||:| ; JMP XREF from 0x004007e3 (sym.giff_flag) ; 情况一:num2 % 2 != 1
| ||`---> 0x004007ef 8b45fc mov eax, dword [local_4h] ; eax = i ; i 是循环计数
| || :| 0x004007f2 4863d0 movsxd rdx, eax ; rdx = eax = i
| || :| 0x004007f5 488b45e8 mov rax, qword [local_18h] ; rax = &flag
| || :| 0x004007f9 488d3402 lea rsi, [rdx + rax] ; rsi = &flag + i = &flag[i]
| || :| 0x004007fd 8b45fc mov eax, dword [local_4h] ; eax = i
| || :| 0x00400800 4863d0 movsxd rdx, eax ; rdx = eax = i
| || :| 0x00400803 488b45e8 mov rax, qword [local_18h] ; rax = &flag
| || :| 0x00400807 4801d0 add rax, rdx ; rax = &flag + i
| || :| 0x0040080a 0fb600 movzx eax, byte [rax] ; eax = flag[i]
| || :| 0x0040080d 89c7 mov edi, eax ; edi = eax = flag[i]
| || :| 0x0040080f 8b45e4 mov eax, dword [local_1ch] ; eax = key ; key 是交谈语句的序号
| || :| 0x00400812 0faf45fc imul eax, dword [local_4h] ; eax = eax * i = key * i
| || :| 0x00400816 89c1 mov ecx, eax ; ecx = eax = key * i
| || :| 0x00400818 baa7c867dd mov edx, 0xdd67c8a7
| || :| 0x0040081d 89c8 mov eax, ecx
| || :| 0x0040081f f7ea imul edx
| || :| 0x00400821 8d040a lea eax, [rdx + rcx]
| || :| 0x00400824 c1f805 sar eax, 5
| || :| 0x00400827 89c2 mov edx, eax
| || :| 0x00400829 89c8 mov eax, ecx
| || :| 0x0040082b c1f81f sar eax, 0x1f
| || :| 0x0040082e 29c2 sub edx, eax
| || :| 0x00400830 89d0 mov eax, edx
| || :| 0x00400832 c1e003 shl eax, 3
| || :| 0x00400835 01d0 add eax, edx
| || :| 0x00400837 c1e002 shl eax, 2
| || :| 0x0040083a 01d0 add eax, edx
| || :| 0x0040083c 29c1 sub ecx, eax
| || :| 0x0040083e 89ca mov edx, ecx ; edx = ecx = key * i
| || :| 0x00400840 89d0 mov eax, edx ; eax = edx = key * i
| || :| 0x00400842 01f8 add eax, edi ; eax = eax + edi = flag[i] + input * i
| || :| 0x00400844 8806 mov byte [rsi], al ; flag[i] = flag[i] + input * i
| ||,===< 0x00400846 eb5a jmp 0x4008a2
| |||:| ; JMP XREF from 0x004007e8 (sym.giff_flag) ; 情况二:num2 % 2 == 1
| |`----> 0x00400848 8b45fc mov eax, dword [local_4h] ; eax = i
| | |:| 0x0040084b 4863d0 movsxd rdx, eax ; rdx = eax = i
| | |:| 0x0040084e 488b45e8 mov rax, qword [local_18h] ; rax = &flag
| | |:| 0x00400852 488d3402 lea rsi, [rdx + rax] ; rsi = &flag + i = &flag[i]
| | |:| 0x00400856 8b45fc mov eax, dword [local_4h] ; eax = i
| | |:| 0x00400859 4863d0 movsxd rdx, eax ; rdx = eax = i
| | |:| 0x0040085c 488b45e8 mov rax, qword [local_18h] ; rax = &flag
| | |:| 0x00400860 4801d0 add rax, rdx ; rax = &flag + i
| | |:| 0x00400863 0fb600 movzx eax, byte [rax] ; eax = flag[i]
| | |:| 0x00400866 89c7 mov edi, eax ; edi = eax = flag[i]
| | |:| 0x00400868 8b45e4 mov eax, dword [local_1ch] ; eax = key
| | |:| 0x0040086b 0faf45fc imul eax, dword [local_4h] ; eax = eax * i = key * i
| | |:| 0x0040086f 89c1 mov ecx, eax ; ecx = eax = key * i
| | |:| 0x00400871 baa7c867dd mov edx, 0xdd67c8a7
| | |:| 0x00400876 89c8 mov eax, ecx
| | |:| 0x00400878 f7ea imul edx
| | |:| 0x0040087a 8d040a lea eax, [rdx + rcx]
| | |:| 0x0040087d c1f805 sar eax, 5
| | |:| 0x00400880 89c2 mov edx, eax
| | |:| 0x00400882 89c8 mov eax, ecx
| | |:| 0x00400884 c1f81f sar eax, 0x1f
| | |:| 0x00400887 29c2 sub edx, eax
| | |:| 0x00400889 89d0 mov eax, edx
| | |:| 0x0040088b c1e003 shl eax, 3
| | |:| 0x0040088e 01d0 add eax, edx
| | |:| 0x00400890 c1e002 shl eax, 2
| | |:| 0x00400893 01d0 add eax, edx
| | |:| 0x00400895 29c1 sub ecx, eax ; ecx = (key * i) % 37
| | |:| 0x00400897 89ca mov edx, ecx ; edx = ecx
| | |:| 0x00400899 89d0 mov eax, edx ; eax = edx = ecx
| | |:| 0x0040089b 29c7 sub edi, eax ; edi = edi - eax = flag[i] - key * i % 37
| | |:| 0x0040089d 89f8 mov eax, edi ; eax = edi
| | |:| 0x0040089f 8806 mov byte [rsi], al ; flag[i] = flag[i] - key * i % 37
| | |:| 0x004008a1 90 nop
| | |:| ; JMP XREF from 0x00400846 (sym.giff_flag)
| | |:| ; JMP XREF from 0x004007ea (sym.giff_flag)
| `-`---> 0x004008a2 8345fc01 add dword [local_4h], 1 ; i = i + 1
| :| ; JMP XREF from 0x004007cb (sym.giff_flag)
| :`-> 0x004008a6 837dfc24 cmp dword [local_4h], 0x24 ; [0x24:4]=-1 ; '$' ; 36
| `==< 0x004008aa 0f8e20ffffff jle 0x4007d0 ; i <= 36 时跳转
| 0x004008b0 8b05ce172000 mov eax, dword [obj.num2] ; [0x602084:4]=0
| 0x004008b6 83c001 add eax, 1
| 0x004008b9 8905c5172000 mov dword [obj.num2], eax ; [0x602084:4]=0
| 0x004008bf 5d pop rbp
\ 0x004008c0 c3 ret
该函数的汇编代码大概可以整理成下面的伪代码:
int num2 = 0; // 交谈次数
void giff_flag(&flag, int key) {
for(int i = 0; i <= 36; i++) {
if (num2 % 2 == 1) {
flag[i] = flag[i] - i * key % 37;
} else {
flag[i] = flag[i] + i * key % 37;
}
}
num2++;
}
我们知道 flag 的格式应该是 ECTF{...}
,所以只要初始 flag 在多次转换后出现这几个字符,就很可能是最终的 flag 了。我们已经理清了算法,接下来的事情就交给 Z3 了。
参考资料
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论