assassin --- pushing me away
문제 풀기 전에 아래의 명령어를 반드시 쳐야한다.
$export SHELL=/bin/bash2
$/bin/bash2
우선 assassin의 디렉터리를 확인한다.
zombie_assassin이라는 의심스러운 파일이 존재한다. zomebie_assassin은 zombie_assassin의 권한을 가지고 있고, setuid가 걸려있는 파일이다.
zombie_assassin.c를 가지고 zombie_assassin elf 파일을 만들었을 가능성이 있기 때문에, zombie_assassin 파일을 본 뒤 어떤 취약점을 가지고 있는지 확인해보자.
지역 변수를 선언한다.
1 | char buffer[40]; | cs |
인자의 개수가 없으면 "argv error\n"를 출력하고 종료한다.
1 2 3 4 5 | if(argc < 2) { printf("argv error\n"); exit(0); } | cs |
첫 번째 인자의 48번째 문자가 '\xbf'이면 "stack retbayed you!\n"를 출력하고 종료한다.
1 2 3 4 5 | if(argv[1][47] == '\xbf') { printf("stack retbayed you!\n"); exit(0); } | cs |
첫 번째 인자의 48번째 문자가 '\x40'이면 "library retbayed you, too!\n"를 출력하고 종료한다.
1 2 3 4 5 | if(argv[1][47] == '\x40') { printf("library retbayed you, too!!\n"); exit(0); } | cs |
첫 번째 인자 중 최대 48 byte만 buffer에 저장하고 출력한다.
1 2 | strncpy(buffer, argv[1], 48); pritnf(*%s\n", buffer); | cs |
zombie_assassin의 메모리 구조를 예상해보면 아래와 같다.
실제 변수가 할당될 때, gcc가 최적화를 위해 자동적으로 dummy를 생성할 수 있다.
gdb를 이용해여 zombie_assassin을 분석해보자. zombie_assassin을 gdb로 실행하는 도중 permission denied가 발생하면 cp 명령을 이용하여 파일을 복사하면 된다. 현재 user의 권한으로 똑같은 파일을 가질 수 있기 때문이다.
위와 같이 zombie_assassin가 assassin의 권한으로 복사된 것을 확인할 수 있다.
dummy가 생성되었는지 gdb를 통해 확인해보자.
dummy가 추가적으로 생성되지 않고 정확히 40(0x28) byte가 생성된 것을 확인할 수 있다.
zombie_assassin을 보면 FEBP를 힌트로 주었다.
FEBP는 Fake EBP라는 뜻이므로 FEBP에 대해 공부 해야 한다.
Stack 영역과 shared library 영역을 사용할 수 없고 strncpy() 함수로 인해, 최대 48 byte를 복사할 수 있다.
이번에도 중요한 개념은 에필로그에 대한 개념이다.
함수의 에필로그는 두 개의 어셈블리 명령어로 이루어져 있다.
leave
ret
leave와 ret은 각각 두 개의 어셈블리 명령을 수행하는 명령어이다.
leave
move esp, ebp
pop ebp
ret
pop eip
jmp eip
FEBP의 공격은 아래와 같은 payload로 진행된다.
40byte의 더미 + 공격하고 싶은 주소 - 4 + leave
첫 leave 명령어를 만나면 mov esp, ebp를 하고 나서, pop ebp를 한다.
leave 명령어의 mov esp, ebp는 딱히 의미가 없고 pop ebp를 하면 ebp에 (&주소-4)이 저장된다.
ret 명령어를 통해 EIP에 leave의 주소가 저장되어있기 때문에 leave가 한 번 더 실행된다.
두 번째 leave 명령어를 만나면 mov esp, ebp를 하고 나서, pop ebp를 한다.
여기서 ebp에 (&주소-4)이 저장되어 있기 때문에 esp는 (&주소-4)가 저장된다.
pop ebp를 통해 어떠한 값이 ebp에 저장되고, esp가 +4증가(esp = &주소)한다.
ret 명령어를 통해 &주소를 실행한다.
우리는 쉘코드를 buffer에 삽입할 것이다. buffer의 주소는 아래와 같이 구할 수 찾을 수 있다.
buffer의 시작주소는 0xbffffa90이다. leave의 주소는 0x80484df이다.
약간의 조정과 함께 clear할 수 있다.
'Wargame > LOB' 카테고리의 다른 글
해커스쿨 LOB succubus 풀이, write-up (0) | 2018.10.12 |
---|---|
해커스쿨 LOB zombie_assassin 풀이, write-up (0) | 2018.09.20 |
해커스쿨 LOB giant 풀이, write up (0) | 2018.09.16 |
해커스쿨 LOB bugbear 풀이, write up (0) | 2018.09.14 |
해커스쿨 LOB darkknight 풀이, write-up (0) | 2018.09.14 |