Download presentation
Presentation is loading. Please wait.
1
Re:Zero 부터 시작하는 Flash Player CVE 분석
H3X0R 김도현 지금부터 Re:Zero부터 시작하는 Flash Player CVE 분석 발표를 시작 하겠습니다.
2
Agenda Basic Knowledge Of AVM Native Level Debugging
CVE Use-After-Free CVE Use-After-Free Conclusion 다음은 목차입니다만, 이번에는 CVE 까지만 발표 하도록 하겠습니다.
3
Who Am I 김도현 H3X0R H3X0R CTF1, CTF2 주최 명호고등학교 저에 대한 소개입니다.
4
1 Basic Knowledge Of AVM
5
Basic Knowledge Of AVM Q : What is AVM?
AVM (Action Script Virtual Machine) was designed to execute programs written in the Actionscript 3.0 language -avm2overview 먼저 Flash Player의 AVM이란 놈에 대해 알아봅시다. AVM이란 Actionscript 3.0 언어로 써진 프로그램을 실행 하기 위해 설계된 프로그램입니다.
6
Basic Knowledge Of AVM Q : How It Works? Compiler AVM Source Code
ActionScript ByteCode (.swf) Machine Code ( Assembly ) Compiler AVM 다음은 그 구조입니다. 먼저 action script source code를 컴파일러단에서 ActionScript ByteCode로 컴파일 합니다. 그러면 해당 바이트코드를 AVM에서 해석하여 어셈블리레벨에서 해당 작업을 수행 하게 되는 것입니다. 이런 구조를 JIT라고 합니다.
7
Native Level Debugging
2 Native Level Debugging
8
Native Level Debugging
Environment Setting Adobe Flash Player Internet Explorer 8.0 Windows 7 Windbg (x86) Pykd bindiff 다음은 환경 세팅입니다.
9
Native Level Debugging
Useful Thing AVM+ Source Code ( Github ) 다음은 분석 하는데 많은 도움을 받은 자룡입니다.
10
Native Level Debugging
인터넷 익스플로러에 attach 하여 플래시 Active X를 분석하는 방법을 알려 드리겠습니다. Internet Options On Connect ( Stand-by )
11
Native Level Debugging
알림창을 띄워논 상태로 ... Check Process Windbg - Attach
12
Native Level Debugging
Process Attached Module Loaded ( Flash32_16_0_0_287.ocx )
13
3 CVE
14
CVE-2015-0311 UAF https://cve.mitre.org https://www.rapid7.com
우선 취약점에 대한 정보를 수집 해 봤습니다. 취약점은 ByteArray의 UncompressViaZlibVariant 함수에서 발생 한다고 합니다.
15
Save original data before uncompress
CVE UAF 그렇다면 지금부터 깃허브의 소스 코드를 보며 분석 해 보도록 하겠습니다. 먼저 압축하기 전의 데이터를 실제 압축 하는 과정의 함수에 인자로 줍니다. Save original data before uncompress
16
ByteArray::UncompressViaZlibVariant()
CVE UAF ByteArray::UncompressViaZlibVariant() ( L1735~L1745 ) ByteArray::Write() 그리고 UncompressViaZlibVariant를 보게 되면 inflate 하여 압축 해제를 진행 하고 Write를 통해 데이터를 ByteArray에 쓰는 것을 알 수 있습니다. 그렇다면 Write를 봐야 되는데 Write 함수가 패치되어 과거의 커밋을 보며 분석을 진행 했습니다.
17
Original ByteArray::Write()
CVE UAF 진짜 Write 함수를 보게 되면 Grower라는 메소드로 ByteArray의 버퍼를 확장시킨 후 move_or_copy 함수로 데이터를 옮겨 씁니다. Something Patched Original ByteArray::Write()
18
Grower::EnsureWritableCapacity()
CVE UAF EnsureWritableCapacity 함수가 새로 버퍼를 확장 하고 Grower::EnsureWritableCapacity()
19
CVE-2015-0311 UAF Grower::~Grower()
20
Grower::NotifySubscribers()
CVE UAF 다음은 그 과정입니다. 참조자의 수에 따라 루프를 돌며 notifyGlobalMemoryChanged 함수를 수행 하여 Grower::NotifySubscribers()
21
Grower::notifyGlobalMemoryChanged()
CVE UAF 결론적으로는 notifyGlobalMemoryChanged 함수로 새로 배치된 메모리로 교체작업을 합니다. Grower::notifyGlobalMemoryChanged()
22
ByteArray::UncompressViaZlibVariant()
CVE UAF 그렇다면 다시 ByteArray::Uncompress 함수로 돌아와 봅시다. ByteArray::Uncompress의 압축 해제 도중 에러가 발생 했을때, Grower로 자라나고 있던 메모리를 해제 하고 이전의 저장된 값들을 가져와 ByteArray의 데이터는 복구 시킵니다. 하지만 이 코드 어디에도 참조자에게 데이터값들이 원래대로 돌아갔고, 현재의 Grower는 삭제해야된다는 내용의 코드는 보이지 않습니다. 이로 인해 참조자는 ByteArray의 Grower중에 생긴 메모리의 포인터를 들고 있으며 그 메모리는 앞서 에러 처리 과정에서 free되어 uaf가 트리거 됩니다. ByteArray::UncompressViaZlibVariant() ( L1767~L1796 )
23
Compress & Set domainMemory
CVE UAF PoC Compress & Set domainMemory Trigger UAF 그럼 이제 PoC를 분석 해 보도록 합시다. PoC에서는 ba에 총 4000 바이트를 쓰고 압축을 합니다. 그 후에 domainMemory라는 간단히 말하자면 프로세스끼리 정보 교환을 하기 위한 메모리 영역인데 여기에 ba를 할당 합니다. 그 후에 0x200 지점부터 널바이트를 끝까지 쓰고 uncompress를 불러 에러를 유도 합니다. 그리고 새로운 Vector를 할당 하고 casi32로 해당 메모리의 길이값을 제한값을 넘어 모든 영역에 read write가 가능하게 길이를 무한정으로 늘렸습니다. 참고로 여기서 0x200지점 뒤부터 널바이트를 쓰는 이유는 앞쪽에는 중요한 zlib 헤더가 있기 떄문입니다. Allocate New Vector
24
CVE UAF PoC * Crash *
25
CVE UAF PoC ‘mms.cfg’ Trace result
26
CVE-2015-0311 UAF Analyze Two ways to analyze ocx
Binary Diffing ( Using bindiff ) String Search & Xref Search
27
CVE-2015-0311 UAF Analyze Q : What is binary diffing?
A B C D E F G H I A B C D E E G H I Comparing Difference
28
CVE UAF Analyze Bindiff Result
29
CVE UAF Analyze Bindiff Flowgraph
30
CVE UAF Analyze
31
CVE-2015-0311 UAF Analyze ByteArrayObject::algorithmToEnum()
Use string value “algorithm”
32
String search “algorithm”
CVE UAF Analyze String search “algorithm”
33
sub_10691de0 == algorithmToEnum
CVE UAF Analyze sub_10691de0 == algorithmToEnum
34
compress, uncompress uses algorithmToEnum()
CVE UAF Analyze compress, uncompress uses algorithmToEnum()
35
Xrefs to algorithmToEnum
CVE UAF Analyze Xrefs to algorithmToEnum
36
ByteArray::Uncompress
CVE UAF Analyze ByteArray::Uncompress
37
CVE UAF Analyze
38
CVE UAF Analyze Pykd Script Executed
39
CVE UAF Analyze Set Breakpoints & Run
40
CVE-2015-0311 UAF Analyze ByteArray::Buffer = *( ( ecx + 24h ) + 4h )
ByteArray::Buffer->Array = *( *( ( ecx + 24h ) + 4h ) + 8h ) ByteArray::Buffer.Capacity = *( ( ecx + 24h ) + 4h ) + Ch ByteArray::Buffer.Length = *( ( ecx + 24h ) + 4h ) + 10h ecx = ByteArray ( ba )
41
CVE-2015-0311 UAF Analyze Zlib encoded Breakpoint #1
ba.buffer, ba.buffer->array Breakpoint #2 ba.buffer, ba.buffer->array
42
CVE UAF Analyze domainmemory
43
CVE-2015-0311 UAF Analyze ByteArray::Buffer->Array = +0
ByteArray::Buffer.length = +4 ByteArrayObject::this = +8
44
CVE-2015-0311 UAF Analyze Breakpoint #3 Breakpoint #4
Before Uncompress() Breakpoint #4 After Uncompress()
45
CVE-2015-0311 UAF Analyze Breakpoint #4 Breakpoint #5
Before Declaring Vector Breakpoint #5 After Declaring Vector
46
CVE-2015-0311 UAF Analyze Breakpoint #5 Breakpoint #6
Before execute casi32() Breakpoint #6 After execute casi32()
47
4 CVE
48
CVE UAF
49
https://wikileaks.org/hackingteam/emails/emailid/513536
CVE UAF Leaked Data
50
https://wikileaks.org/hackingteam/emails/emailid/513536
CVE UAF Leaked Data
51
Allocate New Object & New ByteArray
CVE UAF Leaked Data Allocate New Object & New ByteArray
52
CVE UAF Leaked Data Call Object.valueOf()
53
CVE UAF Leaked Data Object.valueOf()
54
CVE UAF PoC
55
CVE UAF Analyze * Crash *
56
CVE UAF Analyze ‘mms.cfg’ Trace result
57
ByteArrayObject::setUintProperty()
CVE UAF Analyze ByteArrayObject::setUintProperty()
58
ByteArrayObject::setUintProperty()
CVE UAF Analyze ByteArrayObject::setUintProperty()
59
CVE UAF Analyze AvmCore::integer()
60
ScriptObject::defaultValue()
CVE UAF Analyze case kObjectType: AvmCore::number() ScriptObject::defaultValue()
61
CVE-2015-5119 UAF Analyze Code Memory ba = new ByteArray()
ba.length = 0xfa0 ba[3] = o.valueOf() o.valueOf = function(){ ba.length = 0x1100 uv = new Vector(0x3e0) return 0xff } Memory … Heap(??) ba
62
CVE-2015-5119 UAF Analyze Code Memory ba = new ByteArray()
ba.length = 0xfa0 ba[3] = o.valueOf() o.valueOf = function(){ ba.length = 0x1100 uv = new Vector(0x3e0) return 0xff } Memory … Heap(??) Heap(0xfa0) ba
63
CVE-2015-5119 UAF Analyze Code Memory ba = new ByteArray()
ba.length = 0xfa0 ba[3] = o.valueOf() o.valueOf = function(){ ba.length = 0x1100 uv = new Vector(0x3e0) return 0xff } Memory … Heap(??) Heap(0xfa0) ba Heap(0x1100) ba
64
CVE-2015-5119 UAF Analyze Code Memory ba = new ByteArray()
ba.length = 0xfa0 ba[3] = o.valueOf() o.valueOf = function(){ ba.length = 0x1100 uv = new Vector(0x3e0) return 0xff } Memory … Heap(??) Heap(0xfa0) ba , uv Heap(0x1100) ba
65
CVE-2015-5119 UAF Analyze Code Memory ba = new ByteArray()
ba.length = 0xfa0 ba[3] = o.valueOf() o.valueOf = function(){ ba.length = 0x1100 uv = new Vector(0x3e0) return 0xff } Memory … Heap(??) Heap(0xfa0) ba , uv Heap(0x1100) ba
66
CVE-2015-5119 UAF Analyze Code Memory ba = new ByteArray()
ba.length = 0xfa0 ba[3] = o.valueOf() o.valueOf = function(){ ba.length = 0x1100 uv = new Vector(0x3e0) return 0xff } Memory … Heap(??) Heap(*) ba , uv Heap(0x1100) ba
67
Set Breakpoint ‘Object.toString()’
CVE UAF Debugging Set Breakpoint ‘Object.toString()’
68
CVE UAF Debugging Search ByteArray
69
CVE UAF Debugging After Define Vector
70
After Return o.valueOf()
CVE UAF Debugging After Return o.valueOf()
71
5 Conclusion
72
Conclusion – Demo CVE
73
Conclusion AVM CVE = Funny AVM CVE Exploit = Funny * 2
AVM 1-Day Exploit = Funny * 3 AVM 0-Day Exploit = Funny * 4 (?)
74
References & Thanks To Special Thanks To Hacklab.kr hdarwin
Similar presentations