level 16

2020. 9. 9. 11:40

 

buffer에 48글자 입력받고, 스택주소 사용 X, LD_PRELOAD 사용 X, 인자 한 개 X

 

제약 조건엔 별로 없네요.

FPO를 쓸까해서 봤더니 사용자 정의 함수가 없기 때문에 불가능하고,

FS는 당연히 아니고, RET Sled를 쓸까했더니 딱 RET 덮을 때까지만 받기 때문에 안되네요.

 

문제 위를 보면 FEBP라고 나와있습니다.

이는 Fake EBP로, EBP를 속인다는 뜻이죠.

원리는 이렇습니다.

함수의 에필로그는 leave와 ret으로 이루어지죠.

mov esp, ebp
pop ebp             leave
--------------------------
pop eip              ret
jmp eip

여기서 leave는 SFP에 지정된 주소를 사용합니다.

만약, SFP에 쉘코드 주소가 있다면 어떻게 될까요?

이 점을 이용하는 겁니다.

 

첫번째 leave를 만나게 되면 정상적인 실행 흐름과 같이 esp를 ebp있는 곳으로 당깁니다.

하지만, SFP에 있는 값을 가지고 POP ebp를 실행하게 되면 ebp는 쉘코드가 있는 곳으로 이동합니다.

이 다음으로 RET의 값 즉, leave의 주소를 POP해서 eip가 leave로 이동하고, JMP를 실행하면 다시 leave가 실행됩니다.

 

두번째 leave에서 MOV esp, ebp로 인해 esp 또한 쉘코드가 있는 주소로 이동하게 되고, POP ebp에 의해 esp와 ebp가 +4 됩니다.

esp가 쉘코드 위에 올라갔다면 쉘코드가 실행되겠죠?

이 다음으로 RET가 실행되면서 쉘코드가 실행되는 원리입니다.

 

즉, SFP에는 buffer의 시작주소 -4, RET에는 leave의 주소가 들어가야합니다.

그리고 중요한 점은 쉘코드를 직접 작성해 사용하는 경우, buffer의 첫 시작 4바이트는 쉘코드의 시작 주소를 가리켜야 합니다.

 

이 문제를 푸는데에는 두 가지 방법이 있습니다.

첫째, 공유 라이브러리 내에 있는 system 함수와 exit 함수, "/bin/sh\x00" 문자열을 활용한다.
둘째, 직접 쉘코드를 작성한다.

 

두 가지 모두로 풀어보겠습니다.

 

직접 쉘코드 작성하기

먼저, leave의 위치를 알아봅시다.

 

 

0x80484df라고 하네요!

 

buffer의 위치를 알아볼까요?

 

 

이렇게 했습니다.

 

 

나왔네요!

buffer - 4는 0xbffffa8c이고, 쉘코드의 시작 주소는 0xbffffa94네요.

buffer의 첫 4바이트는 0xbffffa94로 채워야겠습니다.

또한, SFP는 0xbffffa8c로 채워보겠습니다.

 

payload를 작성하겠습니다.

"\x94\xfa\xff\xbf" + "\x90"*11 + "~~"(ShellCode) + "\x8c\xfa\xff\xbf" + "\xdf\x84\x04\x08"

 

 

성공!

 

공유 라이브러리 내 함수 이용하기

 

 

함수의 위치를 알아내고,

 

 

위 소스코드를 컴파일한 뒤 실행해 문자열의 위치를 알아냅니다.

 

이후에 buffer의 위치도 알아냅니다.

 

0xbffffa8c가 buffer - 4의 주소네요.

 

payload는 이렇습니다.

함수를 사용하는 경우에는 쉘코드가 없으니 buffer의 첫 4바이트에 바로 함수의 주소를 입력합니다.

"\xe0\x8a\x05\x40" + "\xe0\x91\x03\x40" + "\xf9\xbf\x0f\x40" + "\x90"*28 + "\x8c\xfa\xff\xbf" + "\xdf\x84\x04\x08"

 

 

굿굿!

'[▒] 보안 > LOB' 카테고리의 다른 글

level 18  (0) 2020.09.10
level 17  (0) 2020.09.10
level 15  (0) 2020.09.08
level 14  (0) 2020.09.08
level 13  (0) 2020.09.08

BELATED ARTICLES

more