FINAL 0번 본문
#include "../common/common.c"
#define NAME "final0"
#define UID 0
#define GID 0
#define PORT 2995
char *get_username()
{
char buffer[512];
char *q;
int i;
memset(buffer, 0, sizeof(buffer));
gets(buffer);
/* Strip off trailing new line characters */
q = strchr(buffer, '\n');
if(q) *q = 0;
q = strchr(buffer, '\r');
if(q) *q = 0;
/* Convert to lower case */
for(i = 0; i < strlen(buffer); i++) {
buffer[i] = toupper(buffer[i]);
}
/* Duplicate the string and return it */
return strdup(buffer);
}
int main(int argc, char **argv, char **envp)
{
int fd;
char *username;
/* Run the process as a daemon */
background_process(NAME, UID, GID);
/* Wait for socket activity and return */
fd = serve_forever(PORT);
/* Set the client socket to STDIN, STDOUT, and STDERR */
set_io(fd);
username = get_username();
printf("No such user %s\n", username);
}
소문자 입력 시 대문자로 출력해주는 코드이다.
gets의 취약점을 이용하여 bof를 일으켜 return의 주소를 수정하여 shellcode를
실행하게 한다.
background process가 실행되어 도중에 gdb가 막힌다.
그래서 서버측의 코어 파일을 분석한다.
ret의 위치를 파악한다.
a를 512개 넣고 그이후의 패턴을 구해 위치를 확인한 결과 20byte가 나온다.
offset은 532로 하면 된다.
페이로드는 shellcode + a*532-len(shellcode) + ret로 하면 될 것 같다.
코드 중 serve_forever이 있는데 클라이언트를 수신 대기하는 함수이다.
bind_shell code를 이용해야 한다.
이런식으로 생성할 수 있다. 하지만 코드에서는 소문자를 대문자로 바꿔버린다.
그래서 그냥 exploit database에서 찾아서 썼다.
ret 자리에는 call eax의 머신 코드를 넣었다.
직접 버퍼 시작 위치를 찾아서 0xbffffa48로 넣어도 쉘이 실행되었다.
Comments