본문으로 바로가기

해커스쿨 LOB wolfman 풀이, write-up

category Wargame/LOB 2018. 8. 13. 11:18

wolfman --- love eyuna



우선 wolfman의 디렉터리를 확인한다.





darkelf라는 의심스러운 파일이 존재한다. darkelf는 darkelf의 권한을 가지고 있고, setuid가 걸려있는 파일이다.



darkelf.c를 가지고 darkelf 파일을 만들었을 가능성이 있기 때문에 darkelf.c 파일을 본 뒤 어떤 취약점을 가지고 있는지 확인해보자.





환경변수 리스트의 포인터를 선언한다.


environ는 환경변수 리스트의 포인터이다.



1
extern char **environ;                                                
cs



지역 변수를 선언한다.



1
2
char buffer[40];                                                                
int i;                                    
cs



만일 인자가 없다면 "argv error\n"를 출력하고 프로그램을 종료한다.



1
2
3
4
if(argc < 2){
        printf("argv error\n");                                                        
        exit(0);
    }        
cs



environ을 통해 모든 환경변수를 0으로 초기화 한다.



1
2
for(i=0; environ[i]; i++)
    memset(environ[i], 0, strlen(environ[i]));                                        
cs



첫 번째 인자의 48번째 문자가 '\xbf'가 아니면 "stack is still your friend.\n"를 출력하고 프로그램을 종료한다.



1
2
3
4
5
if(argv[1][47!= '\xbf')
{
        printf("stack is still your friend.\n");                                    
        exit(0);
}    
cs



첫 번째 인자의 길이가 48보다 크면 "argument is too long!"을 출력하고 프로그램을 종료한다.



1
2
3
4
5
if(strlen(argv[1]) > 48)
{
        printf("argument is too long!\n");                                                            
        exit(0);
}                            
cs



첫 번째 인자를 buffer에 저장하고 출력한다.



1
2
strcpy(buffer, argv[1]); 
printf("%s\n", buffer);                                                                                
cs



buffer를 0으로 초기화 한다.



1
memset(buffer, 040);                                                                               
cs




darkelf의 메모리 구조를 예상해보면 아래와 같이 그릴 수 있다.





실제 배열과 변수가 할당되면서 사이 사이에 gcc가 최적화를 위해 자동적으로 dummy를 생성할 수 있다.



gdb를 이용해서 darkelf를 분석해보자. darkelf를 gdb로 실행하는 도중 permission denied가 발생하면 cp 명령을 이용해 파일을 복사하면 현재 user의 권한으로 똑같은 파일을 가질 수 있다.





위와 같이 wolfman의 권한으로 darkelf 파일이 복사된 것을 확인할 수 있다.



dummy가 생성되었는지 gdb를 통해 확인해보자.





dummy가 추가적으로 생성되지 않고 정확히 44(0x2C) byte가 생성된 것을 확인 할 수 있다.


darkelf는 분석해본 결과 환경변수, 버퍼, 스택에서 RET의 뒷 공간을 사용할 수 없다.


그렇다면 어느 공간에 쉘 코드를 삽입해 공격을 시도해야할까?


darkelf는 인자의 개수에 제한이 없다.

따라서 이번에는 인자에 쉘 코드를 삽입하여 RET을 쉘코드의 주소로 수정하여 공격을 진행할 것이다.


번째 인자의 주소를 찾기 위해 소스코드를 약간 수정하자





따라서 우리의 공격 코드는 아래와 같이 작성하면 된다.

./darkelf  NOP 패딩 44byte + argv[2]의 주소  쉘코드



argv[2]의 주소가 0xbffffc39 라는것을 확인했고, 공격결과 성공했다. 하지만 darkelfcp파일에 공격을 해서 darkelf의 권한을 얻지 못했다.


darkelf 파일을 공격해보자.




공격에 실패한것을 확인할 수 없다. 왜냐하면 우리는 darkelfcp 를 gdb로 분석했기 때문에 argv[2]의 주소가 정확하지 않을 수 있다. 따라서 성공 확률을 높이기 위해 NOP padding을 추가하여 공격한다.