ftz.hackerschool.org 의 이미지를 사용하여 실습했습니다.
-Level6
별 생각없이 ctrl+c 만 눌러서 떡하니 있는 password 파일을 열어 level7의 암호를 알아냈다.
로그인하자마자 실행되는 파일들과 프로그램 설정방법과 시그널신호를 제어하는 방법에 대해 분석해 본다.
[level6@ftz level6]$ ls -al
|
합계 104 drwxr-xr-x 4 root level6 4096 3월 5 2003 . drwxr-xr-x 35 root root 4096 8월 19 2014 .. -rw-r--r-- 1 root root 245 9월 24 2000 .Xdefaults -rw------- 1 root root 1 1월 15 2010 .bash_history -rw-r--r-- 1 root root 12 11월 24 2000 .bash_login -rw-r--r-- 1 root root 24 2월 24 2002 .bash_logout -rw-r--r-- 1 root root 224 2월 24 2002 .bash_profile -rw-r--r-- 1 root root 163 3월 5 2003 .bashrc -rw-r--r-- 1 root root 400 9월 24 2000 .cshrc -rw-r--r-- 1 root root 4742 9월 24 2000 .emacs -r--r--r-- 1 root root 319 9월 24 2000 .gtkrc -rw-r--r-- 1 root root 100 9월 24 2000 .gvimrc -rw-r--r-- 1 root root 226 9월 24 2000 .muttrc -rw-r--r-- 1 root root 367 9월 24 2000 .profile -rw-r--r-- 1 root root 1 5월 7 2002 .viminfo -rw-r--r-- 1 root root 4145 9월 24 2000 .vimrc -rw-r--r-- 1 root root 72 11월 23 2000 hint -rw-r----- 1 root level6 36 3월 24 2000 password drwxr-xr-x 2 root level6 4096 5월 16 2005 public_html drwxrwxr-x 2 root level6 4096 1월 14 2009 tmp -rwxr-x--- 1 root level6 14910 3월 5 2003 tn
|
|
[참고] 로그인하자마자 실행되는 파일
/etc/profile -> 모든 사용자가 이 파일을 확인한다.
> level5 이전의 사용자로 로그인 할 때는 아무런 동작을 하지 않았으므로 /etc/profile은 확인하지 않아도 된다.
[level6@ftz level6]$ cat .bash_profile
|
# .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi # User specific environment and startup programs PATH=$PATH:$HOME/bin BASH_ENV=$HOME/.bashrc export BASH_ENV PATH unset USERNAME |
|
> 특별한 것이 없는 것 같다.
[level6@ftz level6]$ cat .bashrc
|
# .bashrc # User specific aliases and functions # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi export PS1="[\u@\h \W]\$ " ./tn logout |
|
> ./tn 이라는 프로그램을 실행하고 프로그램이 끝나면 logout 된다.
[level6@ftz level6]$ file tn
|
tn: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), not stripped |
|
> 실행 파일로 되어있다.
[level6@ftz level6]$ gdb tn
|
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux-gnu"... (gdb) disas main Dump of assembler code for function main: 0x080484f8 <main+0>: push %ebp 0x080484f9 <main+1>: mov %esp,%ebp 0x080484fb <main+3>: sub $0x8,%esp 0x080484fe <main+6>: sub $0xc,%esp 0x08048501 <main+9>: push $0x80486f2 0x08048506 <main+14>: call 0x8048384 <system> 0x0804850b <main+19>: add $0x10,%esp 0x0804850e <main+22>: call 0x8048354 <getchar> 0x08048513 <main+27>: sub $0xc,%esp 0x08048516 <main+30>: push $0x80486fb 0x0804851b <main+35>: call 0x8048384 <system> 0x08048520 <main+40>: add $0x10,%esp 0x08048523 <main+43>: sub $0xc,%esp 0x08048526 <main+46>: push $0x8048720 0x0804852b <main+51>: call 0x80483c4 <printf> 0x08048530 <main+56>: add $0x10,%esp 0x08048533 <main+59>: sub $0xc,%esp 0x08048536 <main+62>: push $0x8048760 0x0804853b <main+67>: call 0x80483c4 <printf> 0x08048540 <main+72>: add $0x10,%esp 0x08048543 <main+75>: sub $0xc,%esp 0x08048546 <main+78>: push $0x80487a0 ---Type <return> to continue, or q <return> to quit--- 0x0804854b <main+83>: call 0x80483c4 <printf> 0x08048550 <main+88>: add $0x10,%esp 0x08048553 <main+91>: sub $0xc,%esp 0x08048556 <main+94>: push $0x8048760 0x0804855b <main+99>: call 0x80483c4 <printf> 0x08048560 <main+104>: add $0x10,%esp 0x08048563 <main+107>: sub $0xc,%esp 0x08048566 <main+110>: push $0x8048760 0x0804856b <main+115>: call 0x80483c4 <printf> 0x08048570 <main+120>: add $0x10,%esp 0x08048573 <main+123>: sub $0xc,%esp 0x08048576 <main+126>: push $0x80487e0 0x0804857b <main+131>: call 0x80483c4 <printf> 0x08048580 <main+136>: add $0x10,%esp 0x08048583 <main+139>: sub $0xc,%esp 0x08048586 <main+142>: push $0x8048820 0x0804858b <main+147>: call 0x80483c4 <printf> 0x08048590 <main+152>: add $0x10,%esp 0x08048593 <main+155>: sub $0xc,%esp 0x08048596 <main+158>: push $0x8048760 0x0804859b <main+163>: call 0x80483c4 <printf> 0x080485a0 <main+168>: add $0x10,%esp 0x080485a3 <main+171>: sub $0xc,%esp ---Type <return> to continue, or q <return> to quit--- 0x080485a6 <main+174>: push $0x8048860 0x080485ab <main+179>: call 0x80483c4 <printf> 0x080485b0 <main+184>: add $0x10,%esp 0x080485b3 <main+187>: sub $0x8,%esp 0x080485b6 <main+190>: push $0x80484e0 0x080485bb <main+195>: push $0x2 0x080485bd <main+197>: call 0x8048374 <signal> 0x080485c2 <main+202>: add $0x10,%esp 0x080485c5 <main+205>: sub $0xc,%esp 0x080485c8 <main+208>: push $0x80488a0 0x080485cd <main+213>: call 0x80483c4 <printf> 0x080485d2 <main+218>: add $0x10,%esp 0x080485d5 <main+221>: sub $0x8,%esp 0x080485d8 <main+224>: lea 0xfffffffc(%ebp),%eax 0x080485db <main+227>: push %eax 0x080485dc <main+228>: push $0x80488c3 0x080485e1 <main+233>: call 0x8048394 <scanf> 0x080485e6 <main+238>: add $0x10,%esp 0x080485e9 <main+241>: cmpl $0x1,0xfffffffc(%ebp) 0x080485ed <main+245>: jne 0x80485ff <main+263> 0x080485ef <main+247>: sub $0xc,%esp 0x080485f2 <main+250>: push $0x80488c6 0x080485f7 <main+255>: call 0x8048384 <system> ---Type <return> to continue, or q <return> to quit--- 0x080485fc <main+260>: add $0x10,%esp 0x080485ff <main+263>: cmpl $0x2,0xfffffffc(%ebp) 0x08048603 <main+267>: jne 0x8048615 <main+285> 0x08048605 <main+269>: sub $0xc,%esp 0x08048608 <main+272>: push $0x80488db 0x0804860d <main+277>: call 0x8048384 <system> 0x08048612 <main+282>: add $0x10,%esp 0x08048615 <main+285>: cmpl $0x3,0xfffffffc(%ebp) 0x08048619 <main+289>: jne 0x804862b <main+307> 0x0804861b <main+291>: sub $0xc,%esp 0x0804861e <main+294>: push $0x80488f1 0x08048623 <main+299>: call 0x8048384 <system> 0x08048628 <main+304>: add $0x10,%esp 0x0804862b <main+307>: cmpl $0x1,0xfffffffc(%ebp) 0x0804862f <main+311>: je 0x804864d <main+341> 0x08048631 <main+313>: cmpl $0x2,0xfffffffc(%ebp) 0x08048635 <main+317>: je 0x804864d <main+341> 0x08048637 <main+319>: cmpl $0x3,0xfffffffc(%ebp) 0x0804863b <main+323>: je 0x804864d <main+341> 0x0804863d <main+325>: sub $0xc,%esp 0x08048640 <main+328>: push $0x8048920 0x08048645 <main+333>: call 0x80483c4 <printf> 0x0804864a <main+338>: add $0x10,%esp ---Type <return> to continue, or q <return> to quit--- 0x0804864d <main+341>: leave 0x0804864e <main+342>: ret 0x0804864f <main+343>: nop End of assembler dump. |
|
> 길어 보이지만 printf 문이 많기 때문에 겁먹지 말자.
|
0x08048501 <main+9>: push $0x80486f2 0x08048506 <main+14>: call 0x8048384 <system> |
|
|
(gdb) x/s 0x80486f2 0x80486f2 <_IO_stdin_used+46>: "cat hint" |
|
> 프로그램이 시작하자마자 힌트파일을 보여준다.
|
0x0804850b <main+19>: add $0x10,%esp 0x0804850e <main+22>: call 0x8048354 <getchar> |
|
> 문자 입력을 받는다.(문자 입력을 기다린다.) --> 힌트파일을 보여주고 기다린 이유가 여기에 있다.
|
0x08048516 <main+30>: push $0x80486fb 0x0804851b <main+35>: call 0x8048384 <system> |
|
|
(gdb) x/s 0x80486fb 0x80486fb <_IO_stdin_used+55>: "clear" |
|
> 화면을 싹 정리한다.
|
##################################### ## ## ## 텔넷 접속 서비스 ## ## ## ## ## ## 1. 하이텔 2. 나우누리 ## ## 3. 천리안 ## ## ## ##################################### 접속하고 싶은 bbs를 선택하세요 : |
|
> 실행 했을 때를 확인해보면 뒤에 이어진 printf 명령은 아마 이런것을 출력하는 문장일 것이다.
|
0x080485a6 <main+174>: push $0x8048860 0x080485ab <main+179>: call 0x80483c4 <printf> |
|
|
(gdb) x/s 0x8048860 0x8048860 <_IO_stdin_used+412>: " ", '#' <repeats 37 times>, "\n" |
|
> 마지막 printf 문만 확인해보니 #을 37번 반복하는 줄이다.
|
0x080485b6 <main+190>: push $0x80484e0 0x080485bb <main+195>: push $0x2 0x080485bd <main+197>: call 0x8048374 <signal> |
|
> 2번 시그널을 입력하면 핸들러가 동작하도록 되어있는 것 같다.
|
접속하고 싶은 bbs를 선택하세요 : Can't use ctrl+c |
|
> 그 핸들러는 아마 Can't use ctrl+c 를 출력해주는 함수일 것이다.
# man signal
|
NAME signal - ANSI C signal handling SYNOPSIS #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); |
|
# man 7 signal
|
Signal Value Action Comment ------------------------------------------------------------------------- SIGHUP 1 Term Hangup detected on controlling terminal or death of controlling process SIGINT 2 Term Interrupt from keyboard SIGQUIT 3 Core Quit from keyboard SIGILL 4 Core Illegal Instruction SIGABRT 6 Core Abort signal from abort(3) SIGFPE 8 Core Floating point exception SIGKILL 9 Term Kill signal SIGSEGV 11 Core Invalid memory reference SIGPIPE 13 Term Broken pipe: write to pipe with no readers SIGALRM 14 Term Timer signal from alarm(2) SIGTERM 15 Term Termination signal SIGUSR1 30,10,16 Term User-defined signal 1 SIGUSR2 31,12,17 Term User-defined signal 2 SIGCHLD 20,17,18 Ign Child stopped or terminated SIGCONT 19,18,25 Cont Continue if stopped SIGSTOP 17,19,23 Stop Stop process SIGTSTP 18,20,24 Stop Stop typed at tty SIGTTIN 21,21,26 Stop tty input for background process SIGTTOU 22,22,27 Stop tty output for background process |
|
|
0x080485c8 <main+208>: push $0x80488a0 0x080485cd <main+213>: call 0x80483c4 <printf> |
|
|
(gdb) x/s 0x80488a0 0x80488a0 <_IO_stdin_used+476>: "\n접속하고 싶은 bbs를 선택하세요 : " |
|
> 마지막 출력문이다.
|
0x080485db <main+227>: push %eax 0x080485dc <main+228>: push $0x80488c3 0x080485e1 <main+233>: call 0x8048394 <scanf> |
|
> scanf 로 1,2,3중 하나를 입력을 받는다.
|
0x080485e9 <main+241>: cmpl $0x1,0xfffffffc(%ebp) 0x080485ed <main+245>: jne 0x80485ff <main+263> 0x080485ef <main+247>: sub $0xc,%esp 0x080485f2 <main+250>: push $0x80488c6 0x080485f7 <main+255>: call 0x8048384 <system> ---Type <return> to continue, or q <return> to quit--- 0x080485fc <main+260>: add $0x10,%esp 0x080485ff <main+263>: cmpl $0x2,0xfffffffc(%ebp) 0x08048603 <main+267>: jne 0x8048615 <main+285> 0x08048605 <main+269>: sub $0xc,%esp 0x08048608 <main+272>: push $0x80488db 0x0804860d <main+277>: call 0x8048384 <system> 0x08048612 <main+282>: add $0x10,%esp 0x08048615 <main+285>: cmpl $0x3,0xfffffffc(%ebp) 0x08048619 <main+289>: jne 0x804862b <main+307> 0x0804861b <main+291>: sub $0xc,%esp 0x0804861e <main+294>: push $0x80488f1 0x08048623 <main+299>: call 0x8048384 <system> 0x08048628 <main+304>: add $0x10,%esp 0x0804862b <main+307>: cmpl $0x1,0xfffffffc(%ebp) 0x0804862f <main+311>: je 0x804864d <main+341> 0x08048631 <main+313>: cmpl $0x2,0xfffffffc(%ebp) 0x08048635 <main+317>: je 0x804864d <main+341> 0x08048637 <main+319>: cmpl $0x3,0xfffffffc(%ebp) 0x0804863b <main+323>: je 0x804864d <main+341> 0x0804863d <main+325>: sub $0xc,%esp 0x08048640 <main+328>: push $0x8048920 0x08048645 <main+333>: call 0x80483c4 <printf> |
|
> 딱 봐도 조건문이다. if / else if / else if / else 문 일 수도 있고 switch-case 구문일 수도 있다.
|
(gdb) x/s 0x80488c6 0x80488c6 <_IO_stdin_used+514>: "telnet 203.245.15.76" |
|
> 1을 누르면 나왔던 IP로 telnet 을 시도한다.
> 나머지도 다 같은 형식이다.
|
(gdb) x/s 0x8048920 0x8048920 <_IO_stdin_used+604>: "잘못 입력하셨습니다. 접속을 종료합니다.\n" |
|
> 잘못 입력하면 종료된다.
- 의사코드
|
#include <stdio.h> #include <signal.h> void sig_func(int signo) { printf("Can't use ctrl+c\n"); } int main() { char input; int select, i; system("cat hint"); input = getchar(); system("clear"); printf("#####################################\n"); printf("## ##\n"); printf("## 텔넷 접속 서비스 ##\n"); printf("## ##\n"); printf("## 1. 하이텔 2. 나우누리 ##\n"); printf("## 3. 천리안 ##\n"); printf("## ##\n"); printf("#####################################\n"); signal( SIGINT, sig_func ); printf("\n접속하고 싶은 bbs를 선택하세요 : "); switch(input) { case 1: system("telnet 203.245.15.76"); break; case 2: system("telnet 203.238.129.97"); break; case 3: system("telnet 210.120.128.180"); break; default: if(input !=1 && input !=2 && input !=3) printf("잘못 입력하셨습니다. 접속을 종료합니다.\n"); } return 0; } |
|
> 빨간색으로 표시한 라인을 다음과 같이 바꿔주는 것이 좋다.
|
for(i=1; i<32; i++) { if(i == SIGINT) signal(i, sig_func); else signal(i, SIG_IGN); } |
|
> 시그널을 제어할때는 다른 모든 번호들도 막아두는 것이 좋다.
> 2번 시그널만 sig_func를 실행하고 나머지는 무시(SIG_IGN)한다.
'Security > 리버싱' 카테고리의 다른 글
Level7 문제 응용 (ASCII) (0) | 2017.11.30 |
---|---|
Level7 문제 해결 (0) | 2017.11.30 |
Level6 문제 해결 (0) | 2017.11.29 |
Level5 문제 분석 -의사 코드 (0) | 2017.11.29 |
Race Condition(레이스 컨디션) (0) | 2017.11.29 |