본문으로 바로가기

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

category Wargame/LOB 2018. 8. 12. 11:26

goblin --- hackers proof



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





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



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





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


environ는 리눅스 내부적으로 환경변수 리스트의 포인터이다.

따라서 environ을 통해 모든 환경변수에 접근 할 수 있다.


$man 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



환경변수를 0으로 mapping 한다.



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
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



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




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



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





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


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





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


goblin은 시작되자마자 환경변수를 초기화하기 때문에 환경변수를 이용한 bof 공격은 불가능하다.

따라서 40 byte 공간의 buffer에 쉘코드를 삽입 한 뒤 buffer의 주소를 이용해서 공격을 진행할 것이다.



우선 buffer의 주소를 찾기위해 gdb를 통한 분석을 진행한다.





buffer의 주소는 0xbfffab0 인것을 확인할 수 있다.


공격코드는 아래와 같이 작성할 수 있다.


25byte 의 쉘코드 + 19 byte의 NOP 패딩 + buffer의 주소


공격하면 아래와 같이 공격에 실패할 것이다.



gdb에서 보인 buffer의 주소가 실제 주소와 다를 수 있기 때문이다.


따라서 orc.c를 복사해 buffer의 주소를 확인하는 소스를 추가한 뒤 컴파일하여 실제 주소를 확인해보자.




다음과 같이 orccp.c를 이용해서 buffer의 실제 주소가 0xbffffac0인것을 확인했다.


buffer의 주소를 0xbffffac0로 바꾸어 공격을 진행하면 성공할 수 있다.