반응형

 

[[ 참고 : http://docs.angr.io/docs/examples.html ]]

 

[[ angr 설치 ]]

기존에 python이 설치 되어 있는 상태라면 설치 과정에서 컴파일이 안되는 상황이 발생합니다.

따라서, 깨끗한 환경에서 설치하기를 추천 합니다.

설치 방법은 다음과 같습니다.

 

1.  $ sudo apt-get install python-dev libffi-dev build-essential virtualenvwrapper

2.  .bashrc 2줄 추가

$ cat >> .bashrc

export WORKON_HOME="~/.envAngr"
source /usr/share/virtualenvwrapper/virtualenvwrapper.sh

^D

3. $ source .bashrc

 

 

 

 

4. $ mkvirtualenv angr && pip install angr

(pip install angr 만 해도 무방 합니다.)

5. 확인

$ python

>>> import angr

 

 

그럼 이제, Symbolic Execution을 진행 해보도록 하겠습니다.

 

Symbolic Execution이란 무엇이냐?

Symbol = 상징, 부호

Execution = 실행

특정한 값이 아닌 x, y, z와 같은 임의의 문자로 변환하여 프로그램을 구동 시키는 방식을 의미

참조 : http://inc0gnito.com/Inc0gnito/Automation%20of%20Software%20Vulnerability%20Analysis.pdf

 

그럼 angr 환경이 구축 되어 있으니, 어떻게 활용해야 하는지 확인 해보도록 합시다.

angr의 경우 시작 지점과 끝 지점을 지정하면 angr 스스로 프로그램이 동작하여 끝 지점까지 실행을 시켜 줍니다.

따라서, baby-re를 분석하면 다음 주소에서 eax가 1이면 flag 값을 표시하게 되어 있습니다.

 

...............................

.text:00000000004028E0 E8 E1 DD FF FF                                call    near ptr CheckSolution
.text:00000000004028E5 84 C0                                         test    al, al

.text:00000000004028E7 74 58                                         jz      short loc_402941 <--- 분기할 경우 "Wrong" 문자열이 출력 / 따라서, 분기 하지 않도록 test al, al 값을 맞춰야 합니다.


.text:00000000004028E9 44 8B 65 D0                                   mov     r12d, [rbp+var_30]
.text:00000000004028ED 8B 5D CC                                      mov     ebx, [rbp+var_34]
.text:00000000004028F0 44 8B 5D C8                                   mov     r11d, [rbp+var_38]
.text:00000000004028F4 44 8B 55 C4                                   mov     r10d, [rbp+var_3C]
.text:00000000004028F8 44 8B 4D C0                                   mov     r9d, [rbp+var_40]
.text:00000000004028FC 44 8B 45 BC                                   mov     r8d, [rbp+var_44]
.text:0000000000402900 8B 7D B8                                      mov     edi, [rbp+var_48]
.text:0000000000402903 8B 75 B4                                      mov     esi, [rbp+var_4C]
.text:0000000000402906 44 8B 75 B0                                   mov     r14d, [rbp+var_50]
.text:000000000040290A 44 8B 6D AC                                   mov     r13d, [rbp+var_54]
.text:000000000040290E 8B 4D A8                                      mov     ecx, [rbp+var_58]
.text:0000000000402911 8B 55 A4                                      mov     edx, [rbp+var_5C]
.text:0000000000402914 8B 45 A0                                      mov     eax, [rbp+var_60]
.text:0000000000402917 41 54                                         push    r12
.text:0000000000402919 53                                            push    rbx
.text:000000000040291A 41 53                                         push    r11
.text:000000000040291C 41 52                                         push    r10
.text:000000000040291E 41 51                                         push    r9
.text:0000000000402920 41 50                                         push    r8
.text:0000000000402922 57                                            push    rdi
.text:0000000000402923 56                                            push    rsi
.text:0000000000402924 45 89 F1                                      mov     r9d, r14d
.text:0000000000402927 45 89 E8                                      mov     r8d, r13d
.text:000000000040292A 89 C6                                         mov     esi, eax
.text:000000000040292C BF 88 2A 40 00                                mov     edi, offset aTheFlagIsCCCCC ; "The flag is: %c%c%c%c%c%c%c%c%c%c%c%c%c"...
.text:0000000000402931 B8 00 00 00 00                                mov     eax, 0
.text:0000000000402936 E8 45 DC FF FF                                call    _printf
.text:000000000040293B 48 83 C4 40                                   add     rsp, 40h
.text:000000000040293F EB 0A                                         jmp     short loc_40294B
.text:0000000000402941                               ; ---------------------------------------------------------------------------
.text:0000000000402941
.text:0000000000402941                               loc_402941:                             ; CODE XREF: main+300j
.text:0000000000402941 BF B1 2A 40 00                                mov     edi, offset s   ; "Wrong"
.text:0000000000402946 E8 15 DC FF FF                                call    _puts
.text:000000000040294B
.text:000000000040294B                               loc_40294B:                             ; CODE XREF: main+358j
.text:000000000040294B B8 00 00 00 00                                mov     eax, 0
.text:0000000000402950 48 8B 5D D8                                   mov     rbx, [rbp+var_28]
.text:0000000000402954 64 48 33 1C 25 28 00 00 00                    xor     rbx, fs:28h
.text:000000000040295D 74 05                                         jz      short loc_402964
.text:000000000040295F E8 0C DC FF FF                                call    ___stack_chk_fail 

 

.text:00000000004028E0 E8 E1 DD FF FF                             call    near ptr CheckSolution
.text:00000000004028E5 84 C0                                         test    al, al

 

al 값은 어디에서 참조 할까요? 그건 "CheckSolution" 함수를 확인 해야 합니다.

 

....................................................
.text:00000000004006C6                               CheckSolution   proc far                ; CODE XREF: main+2F9p
.text:00000000004006C6
.text:00000000004006C6                               var_2B8         = qword ptr -2B8h
.text:00000000004006C6                               var_2B0         = dword ptr -2B0h
.text:00000000004006C6                               var_2AC         = dword ptr -2ACh
.text:00000000004006C6                               var_2A8         = dword ptr -2A8h
.text:00000000004006C6                               var_2A4         = dword ptr -2A4h
.text:00000000004006C6                               var_2A0         = dword ptr -2A0h
.text:00000000004006C6                               var_29C         = dword ptr -29Ch
.text:00000000004006C6                               var_298         = dword ptr -298h
.text:00000000004006C6                               var_294         = dword ptr -294h
.text:00000000004006C6                               var_290         = dword ptr -290h
.text:00000000004006C6                               var_28C         = dword ptr -28Ch
.text:00000000004006C6                               var_288         = dword ptr -288h
.text:00000000004006C6                               var_284         = dword ptr -284h
.text:00000000004006C6                               var_280         = dword ptr -280h
.text:00000000004006C6                               var_27C         = dword ptr -27Ch
.text:00000000004006C6                               var_278         = dword ptr -278h
.text:00000000004006C6                               var_274         = dword ptr -274h
.text:00000000004006C6                               var_270         = dword ptr -270h
.text:00000000004006C6                               var_26C         = dword ptr -26Ch
.text:00000000004006C6                               var_268         = dword ptr -268h
.text:00000000004006C6                               var_264         = dword ptr -264h
.text:00000000004006C6                               var_260         = dword ptr -260h
.text:00000000004006C6                               var_25C         = dword ptr -25Ch
.text:00000000004006C6                               var_258         = dword ptr -258h

.................................................... 

 

CheckSolution() 안에 들어가면 머리 아픈 변수가 엄청나게 선언 되어 있습니다.

따라서, 이걸 손과 눈으로 따라가기엔 문제가 있다는 것을 직감할 수 있습니다.

 

그럼 우리가 원하는 al은 어디에서 사용 되었을까요?

그 부분은 쉽게 확인 할 수 있습니다.

바로 return 되기 전에 al 값을 설정하고 이후에 CheckSolution()가 나온 직후 비교를 하기 때문입니다.

따라서, return 주변을 확인하면 eax 값을 찾을 수 있습니다.

 

text:00000000004025B3 8B 00                                         mov     eax, [rax]
.text:00000000004025B5 0F AF C2                                      imul    eax, edx
.text:00000000004025B8 01 C8                                         add     eax, ecx
.text:00000000004025BA 3D 45 49 1B 00                                cmp     eax, 1788229    <--- 연산 된 값이 "1788229"와 같다면 mov eax, 1을 틀리면 mov eax, 0을 지정하고 return 하게 되어 있습니다.
.text:00000000004025BF 74 0B                                         jz      short loc_4025CC
.text:00000000004025C1 EB 02                                         jmp     short loc_4025C5
.text:00000000004025C1                               ; ---------------------------------------------------------------------------
.text:00000000004025C3 3E FB                                         db 3Eh, 0FBh
.text:00000000004025C5                               ; ---------------------------------------------------------------------------
.text:00000000004025C5
.text:00000000004025C5                               loc_4025C5:                             ; CODE XREF: CheckSolution+1EFBj
.text:00000000004025C5 B8 00 00 00 00                                mov     eax, 0
.text:00000000004025CA EB 05                                         jmp     short loc_4025D1
.text:00000000004025CC                               ; ---------------------------------------------------------------------------
.text:00000000004025CC
.text:00000000004025CC                               loc_4025CC:                             ; CODE XREF: CheckSolution+1EF9j
.text:00000000004025CC B8 01 00 00 00                                mov     eax, 1
.text:00000000004025D1
.text:00000000004025D1                               loc_4025D1:                             ; CODE XREF: CheckSolution+FD6j
.text:00000000004025D1                                                                       ; CheckSolution+111Ej ...
.text:00000000004025D1 48 8B 75 F8                                   mov     rsi, [rbp+var_8]
.text:00000000004025D5 64 48 33 34 25 28 00 00 00                    xor     rsi, fs:28h
.text:00000000004025DE 74 05                                         jz      short locret_4025E5
.text:00000000004025E0 E8 8B DF FF FF                                call    ___stack_chk_fail
.text:00000000004025E5                               ; ---------------------------------------------------------------------------
.text:00000000004025E5
.text:00000000004025E5                               locret_4025E5:                          ; CODE XREF: CheckSolution+1F18j
.text:00000000004025E5 C9                                            leave
.text:00000000004025E6 C3                                            retn 

 

그럼 우리는 Symbolic Execution을 진행할 때 어디에 지정하면 좋을까요?

눈치 빠른 분이면 알 수 있겠죠.

 

바로

 

.text:00000000004025CC B8 01 00 00 00                                mov     eax, 1

 

이 곳입니다.

이 부분은 정확한 계산 값이 아니면 찾아 올 수 없는 부분이므로 해당 부분에  대한 주소를 지정하고 Sysmbolic을 할경우 원하는 값을 찾을 수 있습니다.

 

위의 분석된 결과를 기반으로 작성 된 exploit 입니다.

 

[[ exploit.py ]]

import angr 

proj = angr.Project('./baby-re', load_options={"auto_load_libs": False}) 
initial_state = proj.factory.entry_state() 
path_group = proj.factory.path_group(initial_state) 
path_group.explore(find=0x4025cc)   <--- 목적지를 알려줍니다.

found = path_group.found[0] 

print "[%s]\n" % found
print found.state.se.any_str(found.state.memory.load(found.state.regs.rbp, 200))

 

[[ 실행 결과 ]]

 

babyhack@ubuntu:~/tmp/defcon2016$ python exp_baby-re.py
WARNING | 2016-05-30 17:58:08,140 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:58:09,880 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:58:12,636 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:58:17,196 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:58:23,512 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:58:31,627 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
...............................................

WARNING | 2016-05-30 17:13:06,972 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:13:51,269 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:14:48,520 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
[<Path with 269 runs (at 0x4025cc)>]

 

��������(@Math is hard!``�@�������

 

실행 시킨 후 3-5분 정도 지나면 아래와 위와 같이 flag 문자열을 얻을 수 있습니다.

 

Flag is @Math is hard!

반응형

'Reverse > pwnable' 카테고리의 다른 글

[vagrant] CGC (Cyber Grand Challenge) 환경 구축  (0) 2016.08.02
[pwntools] test code  (0) 2016.07.27
[pwntools] 함수 offset 계산 방법  (0) 2016.07.21
[defcon 23 - 2015] r0pbaby Writeup  (0) 2016.05.18
[pcf2013] ropasaurusrex  (0) 2016.05.11

+ Recent posts