ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 0x00.(Windows)ALmind Lite 1.3 Exploit
    0x.Exploit 2018. 11. 10. 16:29

    0x00.(Windows)ALmind Lite 1.3 Exploit


    윈도우 익스플로잇을 공부할 겸, 1-day 익스를 하나씩 작성하기로 하였고, 제일 첫 번째 포스팅은 스택 오버플로우로 정하였다. 환경은 Windows8에서 진행하였고, 프로그램은 한참 전에 나온 Almind Lite 1.3 버전이며 다음과 같은 크래시로 진행을 하였다.


    가장 먼저 crash가 나온 6cd82..emm 파일을 실행시켜보았다.



    프로그램이 위와 같이 아주 잘 죽는다. 이제 report를 통해서 어떤 종류의 크래시인지를 확인해보자.


    Access violation (second chance) at 0x616d2f73

    Security risk level: Exploitable
    Access violations at the instruction pointer are exploitable if not near NULL


    Exploitable로 판단이되고 0x616d2f73에서 프로그램이 죽었다는 것을 알 수 있다. 조금 더 내려서 해당 부분을 보면 eip가 0x616d2f73으로 잡혔다는 것을 알 수 있으며, 해당 값은 Stack Dump의 마지막줄에서 발견이 된다. 문자열 값 부분에서 maps/map 부분에서 먼가 발생한 것 같다고 추측을 할 수 있다.


    Registers:
    eax=00000000 ebx=00000000 ecx=00001f13 edx=00000000 esi=04034b50 edi=0013e654
    eip=616d2f73 esp=0013e508 ebp=0013e540 iopl=0         no up ei pl nz na pe nc
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000             efl=00010206

    ebp -> 4d 61 73 74 65 72 32 2e 78 6d 6c 50 4b 01 02 14 Master2.xmlPK...
    edi -> 6a 70 67 50 4b 01 02 14 00 14 00 00 00 08 00 00 jpgPK...........
    esi -> 67 44 68 44 69 44 6a 44 6b 44 6c 44 6d 44 6e 44 gDhDiDjDkDlDmDnD

    Stack trace:
    Frame   Origin
    0013E540 2E327265 (0x2e327265)

    Stack pointers:
    [esp+0x00] -> 00 6f 00 77 00 33 00 32 00 00 00 63 00 6f 00 6d .o.w.3.2...c.o.m
    [esp+0x02] -> 00 00 00 00 20 00 00 00 00 00 00 00 14 00 00 00 ................
    [esp+0x07] -> fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd ................
    [esp+0x10] -> 43 ff b2 06 44 ff cc 06 45 ff c2 06 46 ff c2 06 C...D...E...F...
    [esp+0x18] -> 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    [esp+0x1f] -> f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 ................
    [esp+0x27] -> 00 00 00 00 00 00 01 00 09 04 00 00 10 64 00 00 .............d..

    Stack dump:
    0013E508: 01 1f 14 00 14 00 00 00 08 da 00 00 00 00 5c 51 ..............\Q
    0013E518: 2f dd 2a 04 00 00 57 2a 00 00 17 00 00 00 00 00 /.*...W*........
    0013E528: 00 d7 00 00 00 00 00 00 4a 6f 00 00 6d 61 70 2f ........Jo..map/
    0013E538: 6d 61 70 73 2f 6d 61 70                         maps/map        


    분석을 위해 windbg를 활용하여 동적으로 확인을 해봐야 정확한 크래시가 분석이 가능할 것 같다. 한 컴바보 멘토님께서 말씀하시길 사람이 할 일을 컴퓨터에게 시켜야 진정한 해커라고 하셨다. 그러므로 bat 파일을 다음과 같이 생성해서 ollydbg를 실행시킬 것이다.


    windbg -g "C:\Program Files\ESTsoft\ALMind1\ALMind1.exe" "C:\Users\Administrator\Desktop\crash\6cd82beb0b8d422e5b0e1e40a27856dd.emm"


    실행을 시켜보면...



    디버거에 정상적으로 붙혔다!! 하지만 크래시 상황이 달라보인다.



    sx를 확인해보니 ld가 hmindmapapp을 불러올 때 bp를 걸게 해놓고 있었다. 그래서 해당 값을 sxd ld 명령어로 비활성화 시켰다.



    다시 bat를 실행시켜보자.



    어디서 많이 본 것 같은 크래시가 나왔다 eip를 확인해보니 0x616d2f73 크래시 log 파일과 동일한 값이였다. 이제 분석을 시작하면 된다 ^^. 마지막에 로드된 것으로 보이는 모듈이 msxml3.dll 이므로 해당 모듈 로드 지점에 bp를 걸어놓았다.



    그리고 다시 실행시켜보면 아래와 같이 크래시가 발생하지 않은 msxml3.dll이 로드되는 시점에서 bp가 걸리게 된다.



    p를 엄청 눌러서 step over를 해서 찾는 방식이 비효율적이라고 생각을 하기에 다른 방법을 생각해봐야 했다.



    eip로 잡힌 부분을 보면 0013e578에서 조금 떨어진 곳에 위치한 데이터의 값인데 해당 데이터를 복사하는 과정에서 오버플로우가 발생했다고 예측할 수 있다. 그래서 복사하는데 사용하는 API를 추적하는 방식을 사용하기로 하였다.



    lm으로 로드된 명령어들을 보면 msvcp80과 msvcr80이라는 함수가 눈에 띄인다. 두 API안에는 memcpy() 함수가 존재한다.



    x명령어로 확인해보니 memcpy가 존재한다. 둘 중에 어떤 놈인지를 알 수가 없으니 두 부분에 다 bp를 걸었다.


    bp msvcp80!memcpy
    bp msvcr80!memcpy


    이렇게 bp를 걸고 다시 디버깅을 시작해보았다.



    하지만 역시나 길은 험난했다. 너무나도 많은 memcpy()가 불리는 것이다. 그래서 bp의 옵션을 변경하여 자동화 시키는 방식을 사용하기로 하였다.


    bp msvcp80!memcpy ".printf \"ret:%08x dst:%08x src:%08x size:%d\", poi(esp), poi(esp+4), poi(esp+8), poi(esp+c); .echo ; g"

    bp msvcr80!memcpy ".printf \"ret:%08x dst:%08x src:%08x size:%d\", poi(esp), poi(esp+4), poi(esp+8), poi(esp+c); .echo ; g"


    위와 같이 memcpy가 수행될때마다 ret와 dst, src, size의 값을 출력하고 계속 진행하도록 하여 크래시가 발생하기 직전에 수행되는 memcpy를 찾아보았다.



    가장 마지막에 수행되는 memcpy는 3408바이트의 크기에 대한 복사를 수행하는데 바로 이 부분에서 오버플로우가 발생한다고 예측하였다.


    다시 bp 옵션을 다음으로 변경을 한 뒤 실행하였다.


    bp msvcp80!memcpy ".if (poi(esp+c)!=0n3408){g}"
    bp msvcr80!memcpy ".if (poi(esp+c)!=0n3408){g}"


    성공하였다!.



    이제 해당 memcpy 부분을 잘 분석하면 어느부분에서 eip를 덮을수 있을지 알 수 있을 것이다.


    k로 콜스택을 확인해보았다.



    MSVCR80!memcpy가 수행되기 직전에 불린 곳은 01004359 부분이다. 해당 부분을 ub로 어셈블리 코드를 확인해보았더니,



    HMindmapApp+0x434a 부분이었다. 해당 부분이 맞는지는 HMindmappApp로 sxe ld 옵션을 줘서 bp 01004357로 확인해보면 될 것 같다. 해당 주소에서 2~3번 정도 bp가 걸린 뒤에 직접적인 영향을 주는 fread가 호출이 된다.



    아이다로 해당 부분을 분석하기로 하였다. HMindmapAPP.dll의 0x1004357부분을 찾아보면 다음의 부분이다.



    해당 부분에서 call ebp를 하면서 fread가 호출이 되고 크래시가 발생한다. 이 부분에서 overflow가 발생한다면 영향을 받는 부부분을 찾기 위해 bottom to top 방식으로 올라가보았다.


    사이즈의 값을 담당하는 eax에 0x1f13이라는 값이 들어가잇는데 해당 값은 사이즈를 의미한다. 그리고 *buffer가 [esi+46]에 의해 유동적인 값을 가지기에 해당 값으로 인하여 esp가 overwrite됬다고 판단이 되었다. 그를 위해 위로 올라가 스택프레임의 첫부분을 찾아보기 시작하였다.


    살짝 위로 올라가보면 eax의 값으로 esp_arg+0의 값을 받는 부분이 있다. 해당 부분을 xrefs하여 호출 부분으로 더 올라가보았다.



    호출 부분은 다음처럼 생겼다. 좀 더 올라가서 해당 프레임의 첫 부분으로 올라가보았다.



    첫 시작부분은 sub_10033F0였다.



    프레임의 첫 시작부분에 bp를 걸고 해당 부분에서의 esp를 확인해보았다.



    해당 부분에서의 esp가 0x13e4fc 였고, eip가 변조된 후의 esp는 0x13e508이었다.



    결국 3번째 fread가 수행된 뒤에 스택이 덮힌 것이므로, fread가 실행되서 복사되는 정보에서부터 eip까지의 offset을 계산해보았다.



    결국 0013e3e6에서 278바이트 떨어진 곳인 0013e4fc이 0x616d2f73으로 덮힌 것이다. 이를통해 0x13e3e6+0x116의 위치인 0x13e4fc를 조작하여 eip에 대한 변조가 가능하다.


    정확히 분석을 해보자면 다음과 같다.



    fread부분에서 al+46부터 값을 입력받는데, 1*(al+28) 만큼이 overwrite되면서 overflow가 발생한다.



    xref를 해보면 해당 함수는 위에서 호출이 된다.



    v12는 bp-0x144이고, v12+46 부터 값이 적히기 때문에 0x116바이트 뒤의 값을 덮어씌워지면서 eip가 변조되는 것이다.


    해당 부분을 010editor를 통해 찾은 뒤 아래와 같이 0x41414141로 4바이트를 변조해보았다.



    다시 디버깅을 시도해보니 다음과 같은 결과가 나왔다.


    eip가 0x41414141로 변경되었다!! 이를 통해 우리는 eip를 조작할 수 있게 되었다. 이제 쉘코드를 올리기 위해서 다음의 명령어로 aslr여부를 확인해보았다.


    !py mona noaslr


    명령어를 치고 모듈들을 확인해보니 아래와 같이 ASLR에 False가 적혀있었다. 이를 통해 매번 똑같은 위치의 가젯을 사용하여 쉘코드로 점프를 뛸 수 있는 가능성이 증가하였다.



    가장 좋은건 트램폴린 형식으로 다음의 바이트로 점프를 뛰는 것이다. 그를 위해 jmp esp의 헥스 값을 찾은 뒤에 위의 모듈을 상태로 찾아보았다.



    결과를 살펴보니 아래와 같이 많은 주소가 나왔다!!



    하지만 실행권한이 있는 주소가 나오지 않아서 ALmind1.dll이 아닌 HMindMapApp.dll을 상대로 noaslr이 걸린 "jmp esp" 주소를 검색해보았다.



    다행히 실행권한이 주어진 주소가 많이 발견되었다. 그 많은 주소들 중, 0x01323df9를 사용하기로 하였다.



    다시 실행시키면 jmp esp 후에 프로그램이 다음과 같이 죽게된다.



    esp를 dump 뜬 데이터를 기준으로 다시 한번 문자열 검색을 하였다.



    0xcccccccc로 변경하여 jmp esp 가젯이 수행된 뒤에 해당주소로 점프를 뛰도록 하였다.



    위와 같이 esp에 c*8이라는 값을 두었는데, 실행 시에 해당 명령어가 잡힌다면 쉘 코드의 점프 지점이 될 것이다. 실행을 시켜보았더니..



    cc에서 bp가 걸렸다 !!! 이제 쉘 코드를 집어넣고 계산기가 실행되는지를 확인해보면 될 것 같다.


    https://github.com/peterferrie/win-exec-calc-shellcode


    위의 깃허브 주소에서 쉘 코드를 받아서 실행시켜보았다.



    익스플로잇 성공 !!


    댓글

Designed by Tistory.