2019. 4. 4. 11:48ㆍSystem Hacking/[LOB] Hacker School
안녕하세요!
오늘은 LOB 14번 문제인
bugbear 문제풀이를 해보도록 하겠습니다!
소스는 아래와 같습니다!
소스가 좀 길어지긴 했네요!
근데 사실 별거는 없습니다!
주석으로 된 부분(execve구하는 코드)이 길어서 그런거죠
간단하게 보자면 똑같이 버퍼는 40byte입니다
그 뒤에 다양한 포인터들 선언되는데
그건 프로그램이 execve의 정확한 주소 구하는데 사용되는 거구요!
argument 개수 2개 보다 작으면 안되고
컴퓨터가 아래의 주석처럼 코드가 쭉 실행되서
execve 함수의 주소를 execve_addr에 담죠!
그 다음에 저희가 argv[1]에 입력한 45~48번째 값들을
ret 변수에 담습니다!
그리고 execve_addr이랑 ret 변수 값이랑 같으면 통과!
다르면 exit!
그 다음에는 strcpy로 항상 그렇듯
취약점이 터지는 구간이죠!
한마디로 이 문제는 ret 주소를 execve로 고정했습니다!
= 잔 생각말고 execve로 exploit 해라
그러면 execve 함수에 대해서 간략하게
알아봐야겠죠?
구글에 검색해보니 다음과 같이 잘 정리된 표가 있어서
그중에 일부를 발췌해왔습니다!
저도 잘 몰라서 찾아보니
shell을 execve로 실행시키면!
execve( "/bin/sh", ( "/bin/sh", 0 ), 0 )
이런 형태를 갖더라구요!
좀 더 이해하기 쉽게 설명해드리면!
execve 첫 번째 인자엔
/bin/sh 문자열의 주소를 넣으시면 되구요!
(strings 명령어로 확인가능)
두 번째 인자엔 "/bin/sh", 0 의 주소 값이 순서대로
들어가 있는 주소 값을 넣으면 되구요!
세 번째 인자엔 0만 있는 메모리 주소 값(NULL)을
넣으면 됩니다!
자!! 저도 두 번째 인자에서
언급한
"주소 값의 메모리 주소 값"
이놈 때문에 한참동안 헷갈려 했습니다!
1) 이렇게 줘야 하는 이유는 execve 함수에서
1번째 인자는 그냥 포인터이지만
2번째 인자는 더블 포인터이기 때문입니다!
*path => 그냥 포인터
char *const argv[ ] => 더블 포인터 (argv도 포인터이기 때문)
더블포인터 => 일반 포인터와 다르게 주소 값을 한번 더 줘야한다!
좀 더 자세하게 설명하자면!
일반 포인터의 경우(*path) : 주소 2 -----> 값 참조
더블 포인터의 경우 (char *const argv[ ]) : 주소 1 ----> 주소 2 -----> 값 참조
뭐 그렇기 때문에 저렇게만 잘 주면
이 문제는 풀립니다!
문제힌트에서 RTL로 적혀있으니
RTL로 execve 함수 실행하면 되겠죠?
그래서 이제 차례대로
값을 구해보겠습니다!
위에서 ldd로 라이브러리 의존성을 확인하구요!
nm 명령어를 통해서
execve 함수 주소 먼저 구해봤습니다!
그 다음에 gdb로
프로그램을 까봐서
어디에 유용한 게 있을지
확인해봤습니다!
제가 breakpoint를 main+6에 걸어버린 이유는!
좀 더 뒤에다가 걸면 execve 주소를 알맞게 입력하지 않으면
프로그램이 종료되잖아요!
그래서 저기에 멈추고 스택 맨 끝에서부터
뭐라도 건져올려 볼라고
확인해보니!!!
제가 복사한 파일의 이름인 big가 보이네요!
파일의 이름이 메모리에 올라간다는건!
심볼릭링크로 이름을 바꿔서
메모리에 올릴 수 있다는 것!
(=간단하게 말하면... 이름을 바꿀 수 있다)
이 위치에 이름이
위치해 있네요!
이건 x/10s 문자열로 출력 한거고!
x/10x로 출력을 하면!
big 문자열의 주소 값이 나오겠죠!!
0xbffffff7 -> big 문자열 주소 -> big
그리고 "/bin/sh" , 0에서
0도 바로 뒤에 있어야 하는데
아래와 같이
/big바로 뒤에
모두 빈칸이네요!
뭐 준비가 다 끝난거 같네요!
/bin/sh의 문자열은
strings 명령어로 찾아 주고요!
/lib/libc.so.6 주소에서
/bin/sh 위치를 더하니!
아래와 같이 /bin/sh 주소 값이 나오게 됩니다!
그리고 마지막으로 확인 차
검증 들어갑니다!
심볼릭링크로 /bin/sh의 주소 값인
0x40100778의 이름으로 링크를 하나
생성합니다!
그리고 gdb에서 확인해보면!
메모리 맨 끝에서 두 번째 자리에!
0x40100778(=/bin/sh 주소)가
들어간 게 보이시죠?
0x40100778의 /bin/sh 주소 값은
0xbffffff7에 담겨 있구요! (더블포인터용으로)
그럼 바로 원래 파일에다가
심볼릭링크를 걸죠!
저희가 넣을 payload에서
execve 함수 인자에 대한
정리를 해봤습니다!
RTL 할 때
execve 함수 인자 순으로 입력해주시면 돼요!
(함수 인자 push 될 때 맨 끝 인자부터 push 돼서요)
그래서 아래와 같이 최종 payload을 작성했습니다!
더미 44개 + execve 함수 주소로 리턴 + 더미 값 4개 + (execve 첫 번째 인자) /bin/sh 주소+ (두 번째 인자) 주소의 주소 값 0xbffffff7 + (세 번째 인자) NULL인 0xbffffffb(gdb에서 마지막 주소)
이렇게 주니 바로
exploit이 완료되고
비밀번호가 보이네요!
고생하셨습니다!
'System Hacking > [LOB] Hacker School' 카테고리의 다른 글
[어설픈] LOB 16번 assassin 문제풀이 (0) | 2019.04.08 |
---|---|
[어설픈] LOB 15번 giant 문제풀이 (0) | 2019.04.06 |
[어설픈] LOB 13번 darkknight 문제풀이 (0) | 2019.04.02 |
[어설픈] LOB 12번 golem 문제풀이 (0) | 2019.03.30 |
[어설픈] LOB 10번 vampire 문제풀이 (0) | 2019.03.28 |