Created
February 27, 2018 09:06
-
-
Save tg12/0dd615c42f706c52fcbb12111ae7e3f7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket | |
class Server(object): | |
def __init__(self,host,port): | |
self._host = host | |
self._port = port | |
def __enter__(self): | |
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) | |
sock.bind((self._host,self._port)) | |
sock.listen(10) | |
self._sock = sock | |
return self._sock | |
def __exit__(self,*exc_info): | |
if exc_info[0]: | |
import traceback | |
traceback.print_exception(*exc_info) | |
self._sock.close() | |
if __name__ == '__main__': | |
host = 'localhost' | |
port = 23 | |
with Server(host,5566) as s: | |
while True: | |
conn, addr = s.accept() | |
msg = conn.recv(1024) | |
conn.send(msg) | |
conn.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from ctypes import * | |
import socket | |
import struct | |
# ref: IP protocol numbers | |
PROTO_MAP = { | |
1 : "ICMP", | |
2 : "IGMP", | |
6 : "TCP", | |
17: "UDP", | |
27: "RDP"} | |
class IP(Structure): | |
''' IP header Structure | |
In linux api, it define as below: | |
strcut ip { | |
u_char ip_hl:4; /* header_len */ | |
u_char ip_v:4; /* version */ | |
u_char ip_tos; /* type of service */ | |
short ip_len; /* total len */ | |
u_short ip_id; /* identification */ | |
short ip_off; /* offset field */ | |
u_char ip_ttl; /* time to live */ | |
u_char ip_p; /* protocol */ | |
u_short ip_sum; /* checksum */ | |
struct in_addr ip_src; /* source */ | |
struct in_addr ip_dst; /* destination */ | |
}; | |
''' | |
_fields_ = [("ip_hl" , c_ubyte, 4), # 4 bit | |
("ip_v" , c_ubyte, 4), # 1 byte | |
("ip_tos", c_uint8), # 2 byte | |
("ip_len", c_uint16), # 4 byte | |
("ip_id" , c_uint16), # 6 byte | |
("ip_off", c_uint16), # 8 byte | |
("ip_ttl", c_uint8), # 9 byte | |
("ip_p" , c_uint8), # 10 byte | |
("ip_sum", c_uint16), # 12 byte | |
("ip_src", c_uint32), # 16 byte | |
("ip_dst", c_uint32)] # 20 byte | |
def __new__(cls, buf=None): | |
return cls.from_buffer_copy(buf) | |
def __init__(self, buf=None): | |
src = struct.pack("<L", self.ip_src) | |
self.src = socket.inet_ntoa(src) | |
dst = struct.pack("<L", self.ip_dst) | |
self.dst = socket.inet_ntoa(dst) | |
try: | |
self.proto = PROTO_MAP[self.ip_p] | |
except KeyError: | |
print "{} Not in map".format(self.ip_p) | |
raise | |
host = '0.0.0.0' | |
s = socket.socket(socket.AF_INET, | |
socket.SOCK_RAW, | |
socket.IPPROTO_ICMP) | |
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) | |
s.bind((host, 0)) | |
print "Sniffer start..." | |
try: | |
while True: | |
buf = s.recvfrom(65535)[0] | |
ip_header = IP(buf[:20]) | |
print '{0}: {1} -> {2}'.format(ip_header.proto, | |
ip_header.src, | |
ip_header.dst) | |
except KeyboardInterrupt: | |
s.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3.6 | |
""" | |
Based on RFC-793, the following figure shows the TCP header format: | |
0 1 2 3 | |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| Source Port | Destination Port | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| Sequence Number | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| Acknowledgment Number | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| Data | |U|A|P|R|S|F| | | |
| Offset| Reserved |R|C|S|S|Y|I| Window | | |
| | |G|K|H|T|N|N| | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| Checksum | Urgent Pointer | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| Options | Padding | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| data | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
In linux api (uapi/linux/tcp.h), it defines the TCP header: | |
struct tcphdr { | |
__be16 source; | |
__be16 dest; | |
__be32 seq; | |
__be32 ack_seq; | |
#if defined(__LITTLE_ENDIAN_BITFIELD) | |
__u16 res1:4, | |
doff:4, | |
fin:1, | |
syn:1, | |
rst:1, | |
psh:1, | |
ack:1, | |
urg:1, | |
ece:1, | |
cwr:1; | |
#elif defined(__BIG_ENDIAN_BITFIELD) | |
__u16 doff:4, | |
res1:4, | |
cwr:1, | |
ece:1, | |
urg:1, | |
ack:1, | |
psh:1, | |
rst:1, | |
syn:1, | |
fin:1; | |
#else | |
#error "Adjust your <asm/byteorder.h> defines" | |
#endif | |
__be16 window; | |
__sum16 check; | |
__be16 urg_ptr; | |
}; | |
""" | |
import sys | |
import socket | |
import platform | |
from struct import unpack | |
from contextlib import contextmanager | |
un = platform.system() | |
if un != "Linux": | |
print(f"{un} is not supported!") | |
sys.exit(1) | |
@contextmanager | |
def create_socket(): | |
''' Create a TCP raw socket ''' | |
s = socket.socket(socket.AF_INET, | |
socket.SOCK_RAW, | |
socket.IPPROTO_TCP) | |
try: | |
yield s | |
finally: | |
s.close() | |
try: | |
with create_socket() as s: | |
while True: | |
pkt, addr = s.recvfrom(65535) | |
# the first 20 bytes are ip header | |
iphdr = unpack('!BBHHHBBH4s4s', pkt[0:20]) | |
iplen = (iphdr[0] & 0xf) * 4 | |
# the next 20 bytes are tcp header | |
tcphdr = unpack('!HHLLBBHHH', pkt[iplen:iplen+20]) | |
source = tcphdr[0] | |
dest = tcphdr[1] | |
seq = tcphdr[2] | |
ack_seq = tcphdr[3] | |
dr = tcphdr[4] | |
flags = tcphdr[5] | |
window = tcphdr[6] | |
check = tcphdr[7] | |
urg_ptr = tcphdr[8] | |
doff = dr >> 4 | |
fin = flags & 0x01 | |
syn = flags & 0x02 | |
rst = flags & 0x04 | |
psh = flags & 0x08 | |
ack = flags & 0x10 | |
urg = flags & 0x20 | |
ece = flags & 0x40 | |
cwr = flags & 0x80 | |
tcplen = (doff) * 4 | |
h_size = iplen + tcplen | |
#get data from the packet | |
data = pkt[h_size:] | |
if not data: | |
continue | |
print("------------ TCP_HEADER --------------") | |
print(f"Source Port: {source}") | |
print(f"Destination Port: {dest}") | |
print(f"Sequence Number: {seq}") | |
print(f"Acknowledgment Number: {ack_seq}") | |
print(f"Data offset: {doff}") | |
print(f"FIN: {fin}") | |
print(f"SYN: {syn}") | |
print(f"RST: {rst}") | |
print(f"PSH: {psh}") | |
print(f"ACK: {ack}") | |
print(f"URG: {urg}") | |
print(f"ECE: {ece}") | |
print(f"CWR: {cwr}") | |
print(f"Window: {window}") | |
print(f"Checksum: {check}") | |
print(f"Urgent Point: {urg_ptr}") | |
print("--------------- DATA -----------------") | |
print(data) | |
except KeyboardInterrupt: | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment