본문으로 바로가기

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

category Wargame/LOB 2018. 8. 12. 12:57

orc --- cantata



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





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



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





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


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



1
extern char **environ;                                        
cs



지역 변수를 선언한다.



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



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



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"를 출력하고 프로그램을 종료한다.



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



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



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



buffer를 0으로 초기화한다.



1
memset(buffer, 040);                                                                
cs




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




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



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





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



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





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


wolfman은 환경변수와 buffer를 초기화하기 때문에 기존의 방법을 사용할 수 없다.


새로운 공격 방법, 혹은 쉘코드를 삽입할 수 있는 공간을 찾아야한다.


1. 스택 영역에 RET이 저장된 뒷 공간을 이용해 공격을 진행할 것이다.





0xbf414141은 RET 의 위치이고 0xbffffa90부터 우리가 임의적으로 사용할 수 있는 공간이다.


따라서 이 공간에 "\x90"으로 적절히 패딩을 한 뒤 쉘 코드를 삽입할 것이다.

RET을 "0xbffffad4"로 수정해 쉘 코드를 실행시킬 것이다.


공격 코드는 아래와 같이 사용하면 될 것이다.


44 byte의 NOP 패딩 + 쉘 코드의 주소 + 적절한 NOP 패딩 + 쉘 코드