본문으로 바로가기

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

category Wargame/LOB 2018. 8. 14. 11:41

troll - aspirin



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





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



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





지역 변수를 선언한다.



1
char buffer[40];                                                    
cs



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



1
2
3
4
5
if(argc < 2)
{
    printf("argv error\n");                                        
    exit(0);
}                
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



첫 번째 인자의 47번째 문자가 '\xff'이면 "but it's not forever!\n"를 출력하고 종료한다.



1
2
3
4
5
if(argv[1][46!= '\xff')
{
    printf("but it's not forever.\n");                                            
    exit(0);
}
cs



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



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




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





실제 배열이 할당될 때 gcc가 최적화를 위해 자동적으로 dummy를 생성할 수 있다.



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





위와 같이 vampirecp가 troll의 권한으로 복사된것을 확인할 수 있다.



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





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


우리가 RET에 수정할 수 있는 주소는 0xbffeffff 이하 부분이다. 

공격을 이해하기 위해 메모리 구조를 조금 더 자세히 그려보면 아래와 같다.



인자의 개수와, 환경변수 사용에 제한을 두지 않는다. 

stack은 거꾸로 자라나는 구조이기 때문에 인자, 환경변수에 충분한 dummy값으로 mapping을 하면 0xbffeffff번지에 도달할 수 있다.


다음과 같이 인자2를 dummy로 mapping 하고 인자1에 쉘코드를 삽입하고 주소를 구한다.





vampirecp에 공격을 성공했으니 vampire에 공격을 해보자. 성공을 높이기 위해 앞에 NOP padding을 한다.