[Window Application Exploit] SEH overflow exploit



출처: https://www.fuzzysecurity.com/tutorials.html


본 포스팅은 fuzzysecurity Tutorials part 3 -> SEH overflow exploit을 분석 및 의역하여 작성하였습니다. 

Windows Application에 존재하는 취약점을 학습하는 데 그 목적이 있습니다.



Step 1. Application

단순히 mp3 file을 실행해주는 program입니다. mp3 file을 하나씩 추가할 수 있으며 .plf 형식의 playlist를 만들어서 추가할 수 있습니다.




Step 2. 취약점 분석

program에서 나타난 취약점은 playlist를 추가할 때 발생합니다. Program 내부적으로 playlist가 Stack에 쌓이게 되고 이때 playlist의 길이에 대한 제한이 되어있지 않아 Stack에 무한적으로 data가 쌓이게 됩니다.


단순히 “A”가 1000개 들어간 exp.plf 만드는 code를 작성합니다.


import struct

file = open("exp.plf", "w")

exp = "A" * 1000

file.write(exp)
file.close()


Program에서 Playlist로 만들어진 파일을 추가시키면 아래와 같이 EIP가 바뀐 것을 확인할 수 있습니다.



Step 3. Exploit

EIP가 바뀌었다고 해서 program의 실행 흐름을 바꿀 수 있는 것이 아닙니다. EIP까지 offset을 구하고 shellcode의 주소를 넣어보면 shellcode가 아닌 다른 code가 실행되는 것을 확인할 수 있습니다.

“A”만 넣었을 때를 다시 살펴보면 SE handler라는 정보가 있습니다. SE handler는 EIP가 변조되었을 때 예외처리로 실행되는 함수의 주소를 말합니다.




여기서 SE handler의 주소에도 0x41414141이 있는것을 확인할 수 있습니다. 이 결과로 보아 SE handler 함수 주소도 stack에 같이 쌓이는 것을 알 수 있습니다. 그렇다면 EIP가 아닌 SE handler함수 주소까지의 offset을 구해보도록 하겠습니다.

pattern을 만들어 넣어보면 0x41347541이라는 data가 담긴 것을 확인할 수 있습니다.



root@kali:/usr/share/metasploit-framework/tools/exploit# ./pattern_offset.rb 0x41347541
[*] Exact match at offset 612


SE handler 함수 주소까지의 offset은 612bytes라는 것을 알아냈다. 이제 실행 흐름을 어떻게 shellcode로 옮길지를 생각해봐야 합니다.

EIP가 변조된 후 shift + F9를 누르면 예외처리 구문으로 빠지게 됩니다. 그렇다면 그림에서 보이는대로 handler 함수에 대한 stack frame이 다시 구성되고 그에 따라 esp가 갖고있는 값도 바뀌게 됩니다. 이 때 esp가 가진 값은 0x127E40입니다. 거기서 esp + 0x8의 주소를 보면 내가 넣은 data가 있는 것을 확인할 수 있습니다.




해당 주소를 보면 next SEH record의 주소로 나와있습니다. 만약 덮은 SE handler함수 주소에 pop-pop-ret code가 담겨져 있다면 esp는 8bytes위로 올라가 내가 넣은 문자열을 code처럼 실행시키게 될것입니다.




pop-pop-ret code를 SE handler에 담은 exploit code를 작성합니다.


import struct

file = open("exp.plf", "w")

exp = "\x90" * 608
exp += "A" * 4
exp += struct.pack('<L', 0x6164172e)
#exp += shellcode

file.write(exp)
file.close()


ret로 인해서 nop sled를 타게되고 내가 넣은 “AAAA”가 실행되는 것을 확인할 수 있습니다.




그리고 현재 memory의 상태를 보면 0x41414141이 있고 pop-pop-ret code 그 이후에 shellcode를 담을수 있는 것을 알 수 있습니다.

SE handler쪽을 넘어서 shellcode를 담을 수 있으므로 0x41414141 부분에 jmp 어셈블리를 넣어 shellcode를 실행시켜야 합니다.




Debugger에서 해당 주소로  code patch를 시켜보면 \xeb\x06이라는 data를 확인할 수 있습니다. 해당 code와 shellcode를 exploit code에 넣어 실행 파일을 만들어 실행시킵니다.




9999 port를 여는 binding shellcode를 넣어 .plf 파일을 만들어 실행시키면 9999 port가 열린 것을 확인할 수 있습니다. 



그리고 local에서 netcat을 이용해 해당 port로 연결하게 되면 shell을 획득할 수 있습니다.



이 글을 공유하기

댓글