Python/2.7 information

scapy 기초.

qkqhxla1 2015. 2. 9. 18:53
지인의 scapy 사용을 보고 해보려다가...
윈도우용 scapy를 파이썬 2.7버전에 깔려다가 실패했다. 설치는 잘 된다. 다만 scapy안에서 
dnet관련해서 에러뜨는 부분이 존재해서 삽질을 몇일동안 하다가 그냥 포기한다. 
나 말고 고집이 생겨서 설치해보려는 사람이 있으면 진짜 꼭 필요한 상황이 아니고서는 시도해 보지 않기를 바람.... (아니면 2.6버전에 깔던지.) 
일부 모듈중에 패치가 안된 모듈을 mingw까지 깔아서 재컴파일해봤지만 시간만 날렸....
포기하고 리눅스에서 설치해봤는데 1분도 안걸려서 설치됬다. 
앞으로 다시는 scapy를 윈도우에 설치하지 않겠습니다.
설명과 그림이 잘 나와있다.

간단하게 스니핑툴로 패킷 캡쳐를 위해(tcpdump나 와이어샤크처럼) 일단 채팅하는 상황을 구현해보았다. 에코 서버를 만들었다. 에코 서버는 클라이언트에서 무한정 메시지를 보내면 받은 메시지를 다시 보내준다. 클라이언트(vmware 리눅스 쪽의 소스)


!/usr/bin/python
import socket,random,time

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('192.168.219.103',6666))
chat = ['hi','fuck you','good night','hello world','who are you?','my name is gds']
while 1:
        c = chat[random.randint(0,5)]
        print c
        s.sendall('client : '+c)
        print s.recv(1000)
        time.sleep(0.5)


서버(윈도우쪽의 소스)

# -*- encoding: cp949 -*-
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('192.168.219.103',6666))
s.listen(5)
conn,addr = s.accept()
while 1:
    read = conn.recv(1000)
    print read
    conn.sendall('server : '+read)


초 경량으로 구현했다. 돌려보면 무한이 잘 보내고, 잘 받음을 확인할수 있다. 이제 스니핑툴로 기본 동작을 알아보자.

클라이언트(vm리눅스)에서 scapy를 킨 후 packet = sniff(filter="host 192.168.219.103", count=10)

처럼 192.168.219.103으로 가는 패킷 10개를 스니핑하라고 인자를 주면 알아서 10개를 가져온다.

packet[0]처럼 출력해보면 raw부분에 메시지를 볼 수 있다.


summary()함수로 간단히 보는것도 가능하다.

>>> packet[4].summary()

'Ether / IP / TCP 192.168.253.100:44711 > 192.168.219.103:6666 PA / Raw'


filter에 와이어샤크처럼 다양한 옵션을 주는게 가능하다.

a=sniff(filter="tcp and ( port 25 or port 110 )",


또 출력 형식도 파이썬 함수로 작성할수 있다. prn이라는 인자로 주면 된다.

>>> packet = sniff(filter='host 192.168.219.103' ,prn=lambda x:x.summary())

Ether / IP / TCP 192.168.253.100:44711 > 192.168.219.103:6666 PA / Raw

Ether / IP / TCP 192.168.219.103:6666 > 192.168.253.100:44711 A / Padding

Ether / IP / TCP 192.168.253.100:44711 > 192.168.219.103:6666 PA / Raw

Ether / IP / TCP 192.168.219.103:6666 > 192.168.253.100:44711 A / Padding


raw부분의 데이터만 뽑아오려면 역시 정규식으로 알아서 잘 변경하면 될듯 싶다.

>>> packet[2]

<Ether  dst=00:50:56:ed:ed:96 src=00:0c:29:d9:bf:72 type=0x800 |<IP  version=4L ihl=5L tos=0x0 len=51 id=31382 flags=DF frag=0L ttl=64 proto=tcp chksum=0x6611 src=192.168.253.100 dst=192.168.219.103 options=[] |<TCP  sport=44711 dport=6666 seq=3740889586L ack=585110039 dataofs=5L reserved=0L flags=PA window=5840 chksum=0x5e70 urgptr=0 options=[] |<Raw  load='hello world' |>>>>

>>> re.findall('\x00\x00(\D+)',str(packet[2]))[0]

'hello world'


패킷이 잘 보인다.


arp스푸핑을 할 수도 있다. arpcachepoison이라는걸 이용하는데,

인자는 target,victim,interval이다.

내가 253.100이고 scapy를 이용해 서버에게 내가 클라이언트(253.139)라는 패킷을 보냈다.

arpcachepoison('192.168.253.137', '192.168.253.139',interval=60)

해당 서버쪽에서 arp -a로 경로를 검색했을때 공격자와 클라이언트의 mac주소가 같아진걸 확인할수있다.





mitm까지 시연해보려다가 귀찮아서 여기서 멈춤.