본문으로 바로가기

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

category Wargame/LOB 2018. 8. 13. 13:05

darkelf --- kernel crashed



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





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



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





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


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



1
extern char **environ                                                              
cs



지역변수를 선언한다.



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



인자가 없으면 "argv error\n"를 출력하고 종료한다.



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



파일이름(argv[0])의 길이가 77 byte가 아니면 "argv[0] error\n"를 출력하고 종료한다.



1
2
3
4
5
if(strlen(argv[0]) != 77)
{
    printf("argv[0] 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 byte 이상이면 "argument is too long!\n"을 출력하고 종료한다.



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



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




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



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





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



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





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


orge를 분석해본 결과 환경변수, 버퍼, 스택에서 RET이 저장된 뒷 공간을 사용할 수 없다.


orge는 인자의 개수에 제한이 없기 때문에 인자로 쉘코드를 전달해 쉘코드를 실행할 것이다.


다만 argv[0]==77 이 되어야한다는것을 확인하자.


argv[0] 의 길이를 조절하기 위해 심볼릭 링크를 사용하였다.


argv[2]에 쉘코드를 삽입하기 때문에 argv[2]의 주소가 필요하다.


소스코드를 수정하여 argv[2]의 주소를 구한다.





심볼링 링크를 이용해 77글자수를 맞춰야한다.





지금까지 orgecp를 심볼릭링크를 이용해서 공격했으니 orge 파일을 대상으로 심볼릭링크를 적용해 공격해보자.




마찬가지로 심볼릭 링크를 이용해서 orge 권한을 얻을 수 있다.