본문 바로가기

보안/DreamHack

Dreamhack Format String Bug

changeme의 값이 1337이 될때까지 반복하며 buf에 0x20이내의 문자열을 입력받고 printf로 출력하는 반복문이다. 

printf문에서 formatstring으로 buf를 출력하는 것이 아닌 buf에 직접 접근해서 출력을 하므로 Format String Bug 취약점이 존재한다. 

 

해당 문제를 풀기 위해서는 changeme 변수의 주소를 찾고 %n을 통해 해당 변수의 값을 1337로 만들면 된다.

 

우선 changeme 변수의 주소를 찾아보자

 

바이너리에 ASLR + PIE가 걸려있으므로 changeme 변수의 주소는 실행을 할 때마다 바뀐다.

 

따라서 FSB 취약점을 이용해서 PIE base 주소를 먼저 구한 후 changeme의 offset을 더해서 changeme의 주소를 구할 수 있다. 

 

우선 gdb를 통해 FSB가 일어나는 printf까지 가서 rsp 근처 스택의 값을 살펴보자

 

여기서 맨 아래 오른쪽에 0x0000555555555293값에 집중을 해야 한다. 왜냐하면

 

해당 바이너리가 매핑된 영역에 포함되는 주소이기 때문이다.

 

0x0000555555555293가 어떤 값인지는 중요하지 않다. 단지 PIE가 걸려서 PIE base의 주소가 계속 바뀔 것이고 0x0000555555555293의 값도 바뀌는 PIE base 주소에 따라 바뀔 것이기 때문이다.

 

중요한 것은 printf가 실행되기 전 rsp+0x48에 있는 값에서 0x1293을 빼면 PIE base의 주소를 구할 수 있다는 것이다.

 

이렇게 구한 PIE base 주소에다가 changeme의 offset을 더하면 changeme의 실제 주소가 나오므로 changeme의 주소를 구할 수 있다. 

 

그럼 첫번째 반복문에 있는 read에서 printf 직전 rsp+0x48의 값을 추출하려면 포맷스트링에 해당하는 rdi를 제외한 rsi, rdx, rcx, r8, r9, rsp, rsp+0x8, rsp+0x10, ....rsp+0x48에서 15번째인 rsp+0x48을 %15$p를 입력하면 된다.

 

이후에는 changeme의 주소를 구해서 %1337c%8$nABCDEF + &changeme를 입력하면 rsp+0x10에 해당하는 changeme에 1337을 대입할 수 있다. ABCDEF는 8byte 단위로 패딩을 하기 위한 임의의 값이다

 

이를 적용해 payload를 작성하면 다음과 같다.

 

FSB 취약점을 이용해 변수에 원하는 값을 입력하는 기초 문제였지만 쉽지는 않았던 문제였다.

'보안 > DreamHack' 카테고리의 다른 글

Dreamhack Recover  (1) 2024.12.06
Dreamhack basic_exploitation_002  (0) 2024.12.04
Dreamhack out of bound  (0) 2024.10.30
Dreamhack hook  (0) 2024.10.28
Dreamhack oneshot  (0) 2024.10.18