마지막 문제다. 문제를 보면 fgets로 정상 범주안의 길이의 input을 버퍼에 입력한다.

그래서 지금까지의 오버플로우와는 다른 문제인 것 같다. printf를 자세히 보면 포맷스트링이 없다.

포맷스트링 버그가 일어날 수 있는 문제다.


일단 tmp에 공격 프로그램을 복사하고 인자로 포맷스트링을 주었다.

네번째 포맷스트링에서 처음 입력했던 AAAA의 16진수 값이 나왔다.


이제 페이로드에 필요한 것들을 준비해야한다.

먼저 쉘코드를 입력해야하는데 일단 지금까지 자주 사용했던 25바이트 쉘코드를 사용할 것이다.

근데 오버플로우를 일으켜 스택에 쉘코드를 넣을 수 없다. 하지만 포맷스트링 취약점에 대해 검색을 해본다면 dtors를 이용해 쉘코드 주소를 저장하고 실행 시킬 수 있다.

일단 dtors의 주소를 찾는 방법이다.


두가지가 있다.

1. objdump -s -j .dtors ./attackme

2. nm ./attackme | more


첫번째 방법을 이용해 주소를 찾았다. 0x08049594이다. 하지만 쉘코드를 입력해야 할 주소는 저기보다 +4바이트된 dtors_end 주소(0x08049598)이다.


그리고 이제 쉘코드를 환경변수에 저장하자.

Nop sled는 적당히 100바이트를 붙였다.


그리고 코드를 짜서 환경변수 주소를 읽어올 수 있지만 gdb로 스택에 있는 환경변수 위치를 직접 찾았다.

우리가 공략할 주소는 0xbfffbd0이다.


이제 필요한 정보를 다 얻었으니 페이로드를 작성해야한다.

페이로드는 대략 아래와 같다.

 [4바이트 더미]+[dtors 앞 주소]+[4바이트 더미]+[dtors 뒷 주소]+[%8x*3]+[쉘코드주소의 뒤 주소의 10진수 값c]+"%n"+[쉘코드주소의 앞 주소의 10진수 값c]+"%n"


일단 dtors의 앞 주소는 0x08049598이고 뒷 주소는 0x0804959a다.

그리고 쉘코드 주소의 뒤 주소의 10진수 값은 64464(0xfbd0)인데 이미 40바이트가 앞에 있으므로 64464-40인 64424바이트를 넣으면 된다.


또한 쉘코드 주소의 앞 주소의 10진수 값은 49151(0xbfff)이고 49151을 만들려면 앞에 입력된 64424바이트를 빼줘야한다. 

즉 50223바이트를 넣어주면 된다.

이제 페이로드를 완성해보자.


PAYLOAD

(python -c 'print "AAAA"+"\x98\x95\x04\x08"+"AAAA"+"\x9a\x95\x04\x08"+"%8x"*3+"%64424c"+"%n"+"%50223c"+"%n"';cat) | ./attackme


clear의 쉘과 비밀번호를 얻었다.


클리어 계정에 로그인을 했고 ftz도 올클리어를 했다. 

'Wargame > FTZ' 카테고리의 다른 글

[FTZ] level19@ftz  (0) 2017.11.26
[FTZ] level18@ftz  (0) 2017.11.26
[FTZ] level17@ftz  (0) 2017.11.25
[FTZ] level16@ftz  (0) 2017.11.25
[FTZ] level15@ftz  (0) 2017.11.23

gets함수의 길이 검증이 없어서 오버플로우가 일어나는 부분이 있다.

아주 간단하게 rtl로 풀려고 했다.


일단 메인함수를 gdb로 열어보고,


system함수의 주소도 찾고,


/bin/sh의 주소도 찾았다.


근데 막상 페이로드를 입력하고 보니 쉘을 얻었는데 level19의 쉘이 따졌다. 

정상적이라면 level20의 쉘이 따져야하는데.. 19의 쉘을 땄다. 이것이 왜인고.. 하면 

힌트 소스를 보면 setreuid가 없다..


즉 setreuid가 설정이 안된것이다.

그래서 구글링으로 setreuid가 있는 쉘코드를 찾았다.


쉘코드

\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80


그리고 쉘코드를 환경변수에 등록했다.


등록한 환경변수를 gdb로 어디에 위치했는지 찾았다.

대략 0xbffffbbc쯤 있다.


페이로드를 작성해 쉘을 얻었다.


'Wargame > FTZ' 카테고리의 다른 글

[FTZ] level20@ftz  (1) 2017.11.26
[FTZ] level18@ftz  (0) 2017.11.26
[FTZ] level17@ftz  (0) 2017.11.25
[FTZ] level16@ftz  (0) 2017.11.25
[FTZ] level15@ftz  (0) 2017.11.23

힌트 소스를 보면 파일디스크립터와 관련된 여러가지 새로운 함수들이 추가되었다.


그리고 쉘을 실행시키는 shellout이라는 함수가 선언되었다.


일반적인 오버플로우 문제랑은 조금 다르다.

오버플로우를 할 수 있는 구조가 없는 것 같다.

파일디스크립터 문서들을 읽다가 이해가 안돼서 답을 조금 봤다.


푸는 방법은 의외로 간단했다.

case 문에서 값을 비교할 때 0x08이 있을 때 count를 --하는 부분이 있다.

일단 스택 구조는 아래와 같다.


fds     : ebp-240

count : ebp-112

x       : ebp-108

check : ebp-104 <- 여기가 같아야함

string : ebp-100


그리고 배열의 인덱스 값이 음수이면 스택의 낮은 주소를 가리키게 된다. 이를 이용해 문제를 풀면 된다.


일단 stdin에 0x08을 4번 넣어주게 되면 count가 4번 -가 되므로 string[-4]를 가리킬 수 있다. string[-4]는 스택의 구조에 의해서 check변수가 위치할것이다.

string[-4]에 0xdeadbeef를 넣어주면 두번째 if문에서 check가 0xdeadbeef와 같으므로 shellout함수를 실행할 수 있다.





'Wargame > FTZ' 카테고리의 다른 글

[FTZ] level20@ftz  (1) 2017.11.26
[FTZ] level19@ftz  (0) 2017.11.26
[FTZ] level17@ftz  (0) 2017.11.25
[FTZ] level16@ftz  (0) 2017.11.25
[FTZ] level15@ftz  (0) 2017.11.23

이전 문제와 거의 흡사한데 이번엔 쉘이 실행되는 shell 함수가 없다.

RTL로 접근하려다가 환경변수를 이용해 25바이트 쉘코드로 쉽게 풀 수 있을 것 같았다.

일단 gdb로 보면 아까와 구조가 완전 같다. ebp-56이 buf의 시작주소이고, ebp-16이 call의 시작 주소다.

즉 call 함수는 40바이트를 넘긴 4바이트에 있는 주소를 호출할 수 있다.


일단 25바이트 쉘코드를 환경변수에 등록했다.


그리고 gdb로 공격할 프로그램을 실행시키고 환경변수의 위치를 파악했다.

0xbffffb5c 쯤 Nop sled가 있다. 

이 부분의 값을 call함수의 주소에 오버플로우를 시키면 쉘코드가 실행될 것이다.


쉘을 얻었다.

'Wargame > FTZ' 카테고리의 다른 글

[FTZ] level19@ftz  (0) 2017.11.26
[FTZ] level18@ftz  (0) 2017.11.26
[FTZ] level16@ftz  (0) 2017.11.25
[FTZ] level15@ftz  (0) 2017.11.23
[FTZ] level14@ftz  (0) 2017.11.21

이전 문제와 조금 비슷해보이면서 다른 것 같다.

일단 shell이라는 함수와 printit이라는 함수가 선언 되어 있다.

그리고 메인함수를 보면 포인터 변수가 printit을 가리킨다.


그리고 fgets를 사용해 stdin을 buf에 48바이트 입력한다.

이제 gdb로 확인해야겠다.


일단 변수로 할당된 버퍼의 크기는 56바이트다.

그리고 ebp-16에 printit의 주소를 mov하는것으로 보아 ebp-16이 포인터 call이 가리키는 값이 들어가는 것 같다.

일단 스택의 구조를 예상해보면 아래와 같다.

buf[20]

call[4]

crap[4]


buf[20]의 시작 위치가 ebp-56이고 call의 시작 주소는 ebp-16이다. 

56-16을 하면 40이다. 즉 40바이트가 buf에 할당된 사이즈고 그 다음 4바이트가 call이다.


call에 있는 주소를 실행하는 로직이므로 

40바이트를 무작위로 값을 주고 다음 4바이트에 실행시키고 싶은 함수의 주소를 넣어주면 되겠다.

다시말해 shell 함수의 주소로 오버플로우를 시켜주면 되겠다.


일단 shell함수의 주소를 찾았다.

이제 페이로드를 작성해 익스플로잇을 하면 된다.


클리어~


'Wargame > FTZ' 카테고리의 다른 글

[FTZ] level18@ftz  (0) 2017.11.26
[FTZ] level17@ftz  (0) 2017.11.25
[FTZ] level15@ftz  (0) 2017.11.23
[FTZ] level14@ftz  (0) 2017.11.21
[FTZ] level13@ftz  (0) 2017.11.21

+ Recent posts