Yersinia:一款支持多協(xié)議的底層攻擊檢測工具
Yersinia是一款底層協(xié)議攻擊入侵檢測工具。它能實(shí)施針對多種協(xié)議的多種攻擊。例如奪取生成樹的根角色(生成樹協(xié)議:Spanning Tree Protocol),生成虛擬CDP(Cisco發(fā)現(xiàn)協(xié)議:Cisco Discovery Protocol)鄰居、在一個HSRP(熱等待路由協(xié)議:Hot Standby Router Protocol)環(huán)境中虛擬成一個活動的路由器、制造假DHCP反饋,以及其它底層攻擊。
下載鏈接:http://down.51cto.com/data/155576
>>去網(wǎng)絡(luò)安全工具百寶箱看看其它安全工具
支持的協(xié)議
* Spanning Tree Protocol (STP) : 生成樹協(xié)議 : 該協(xié)議可應(yīng)用于環(huán)路網(wǎng)絡(luò),通過一定的算法實(shí)現(xiàn)路徑冗余,同時將環(huán)路網(wǎng)絡(luò)修剪成無環(huán)路的樹型網(wǎng)絡(luò),從而避免報(bào)文在環(huán)路網(wǎng)絡(luò)中的增生和無限循環(huán)
* Cisco Discovery Protocol (CDP) : 思科發(fā)現(xiàn)協(xié)議 : 基本上是用來獲取相鄰設(shè)備的協(xié)議地址以及發(fā)現(xiàn)這些設(shè)備的平臺
* Dynamic Trunking Protocol (DTP) : 動態(tài)中繼協(xié)議 : VLAN 協(xié)議組中思科專有協(xié)議,主要用于協(xié)商兩臺設(shè)備間鏈路上的中繼及中繼封裝(如 802.1Q)類型
* Dynamic Host Configuration Protocol (DHCP) : 動態(tài)主機(jī)分配協(xié)議 : 它分為兩個部份:一個是服務(wù)器端,而另一個是客戶端。所有的 IP 網(wǎng)絡(luò)設(shè)定數(shù)據(jù)都由 DHCP 服務(wù)器集中管理,并負(fù)責(zé)處理客戶端的 DHCP 要求;而客戶端則會使用從服務(wù)器分配下來的IP環(huán)境數(shù)據(jù)
* Hot Standby Router Protocol (HSRP) : 熱備份路由器協(xié)議 : HSRP 的設(shè)計(jì)目標(biāo)是支持特定情況下 IP 流量失敗轉(zhuǎn)移不會引起混亂、并允許主機(jī)使用單路由器,以及即使在實(shí)際第一跳路由器使用失敗的情形下仍能維護(hù)路由器間的連通性
* IEEE 802.1Q
* IEEE 802.1X
* Inter-Switch Link Protocol (ISL) : 交換鏈路內(nèi)協(xié)議 : 是思科私有協(xié)議,主要用于維護(hù)交換機(jī)和路由器間的通信流量等 VLAN 信息
* VLAN Trunking Protocol (VTP) : vlan干道協(xié)議 : VTP通過網(wǎng)絡(luò)(ISL幀或cisco私有DTP幀)保持VLAN配置統(tǒng)一性。VTP在系統(tǒng)級管理增加,刪除,調(diào)整的VLAN,自動地將信息向網(wǎng)絡(luò)中其它的交換機(jī)廣播
支持的操作系統(tǒng)
* OpenBSD 3.4 ( 注意 : 需要升級 pcap 庫 至少到 0.7.2)
* Linux 2.4.x and 2.6.x
* Solaris 5.8 64bits SPARC
* Mac OSX 10.4 Tiger (Intel)
HACKER YERSINIA
1.簡介 : 作者將引導(dǎo)我們一步步添加解析VRRP協(xié)議的代碼到 Yersinia 中
2.注冊協(xié)議 : 在創(chuàng)建vrrp.c和vrrp.h文件后第一件事就是注冊該協(xié)議,然后Yersinia就可以用我們提供的協(xié)議進(jìn)行攻擊,當(dāng)然也便于Yersinia提供給我們協(xié)議感興趣的數(shù)據(jù)
跳到 protocols.c::protocol_register_al() 的函數(shù)
- void
- protocol_register_all(void)
- {
- { extern void xstp_register(void); xstp_register(); }
- { extern void cdp_register(void); cdp_register(); }
- { extern void dtp_register(void); dtp_register(); }
- { extern void dhcp_register(void); dhcp_register(); }
- { extern void hsrp_register(void); hsrp_register(); }
- { extern void dot1q_register(void); dot1q_register(); }
- { extern void isl_register(void); isl_register(); }
- { extern void vtp_register(void); vtp_register(); }
- { extern void arp_register(void); arp_register(); }
- { extern void dot1x_register(void); dot1x_register(); }
- { extern void vrrp_register(void); vrrp_register(); }
- }
- 由此推測我們也需要自己的注冊函數(shù),在vrrp.c中定義下列函數(shù)
- void vrrp_register(void)
- {
- protocol_register(PROTO_VRRP, "VRRP", "Virtual Router Redundancy Protocol",
- "vrrp", sizeof(struct vrrp_data), vrrp_init_attribs, NULL,
- vrrp_get_printable_packet, vrrp_get_printable_store,
- vrrp_load_values, vrrp_attack,
- vrrp_update_field,
- vrrp_features, vrrp_comm_params, SIZE_ARRAY(vrrp_comm_params),
- NULL, 0, NULL, vrrp_init_comms_struct, PROTO_VISIBLE, vrrp_end);
- }
它又調(diào)用了 protocols.c::protocol_register()函數(shù)
- int8_t protocol_register(
- u_int8_t proto, : 協(xié)議標(biāo)識 我們把它定義到 protocol.h 中 #define PROTO_VRRP 10
- const char *name, : 協(xié)議字符串名稱
- const char *desc, : 協(xié)議的簡單描述
- const char *name_comm, : 通俗點(diǎn)的名稱
- u_int16_t size, : vrrp_data 結(jié)構(gòu)體 的大小
- init_attribs_t init, : 初始化協(xié)議的回調(diào)函數(shù),函數(shù)聲明:int8_t vrrp_init_attribs(struct term_node *node);
- learn_packet_t learn, : 得到數(shù)據(jù)包時調(diào)用該函數(shù),我們需要把數(shù)據(jù)復(fù)制到 vrrp_data 結(jié)構(gòu)中,函數(shù)聲明:vrrp_learn_packet(struct attacks *attacks, char *iface, u_int8_t *stop, void *data, struct pcap_pkthdr *header, struct pcap_data *pcap_aux);
- get_printable_packet_t packet, : 把數(shù)據(jù)包解釋成可讀的一個字符串
- get_printable_store_t store, :
- load_values_t load, : 解析接收到的數(shù)據(jù)包( 作者不太明白 vrrp_learn_packet()與vrrp_load_values()的區(qū)別 )
- struct attack *attacks, : 該協(xié)議中所有可用的攻擊類型
- update_field_t update_field, : 看起來這個回調(diào)函數(shù)是用來在用戶輸入一個命令行參數(shù)(比如源IP或目錄MAC...)時更新這個數(shù)據(jù)包中的某些字段
- struct proto_features *features, : 作者也不太明白,在 protcols.h 中定義
- struct commands_param *param, : 存放需要提供給用戶的命令行及默認(rèn)值
- u_int8_t nparams, : 同上
- struct commands_param_extra *extra_parameters, : 置空之
- u_int8_t extra_nparams, get_extra_field_t extra, : 置空之
- init_commands_struct_t init_commands, :
- u_int8_t visible, : 設(shè)置為 PROTO_VISIBLE
- end_t end) : 翻譯資源的回調(diào)函數(shù)
- {
- .....code.....
- }
3.填充協(xié)議 : 注冊協(xié)議時我們填充了許多回調(diào)函數(shù)和結(jié)構(gòu)體,現(xiàn)在開始詳細(xì)填充之
vrrp_data : 該結(jié)構(gòu)體用來存放該協(xié)議的頭和以太網(wǎng)頭
void vrrp_init_attribs(struct term_node *node) : 該回調(diào)函數(shù)接收一個 term_node 類型的數(shù)據(jù),因?yàn)樵摵瘮?shù)是回調(diào)函數(shù),所以
應(yīng)該是被調(diào)用的,term_node數(shù)據(jù)也已經(jīng)填充好,我們需要取出其中數(shù)據(jù)去填充 vrrp_data ,比如版本號,源/目的端口號
char **hsrp_get_printable_packet(struct pcap_data *data) : 該回調(diào)函數(shù)用來把數(shù)據(jù)包解析成可閱讀形式的字符串 data 是捕獲
的數(shù)據(jù)包,我們從這個函數(shù)中分配一塊內(nèi)存用來存放字符串#p#
int8_t vrrp_load_values(struct pcap_data *data, void *values) : 該函數(shù)每次捕獲到數(shù)據(jù)包時都被調(diào)用,data指向數(shù)據(jù)包,
可以被我們用來填充 vrrp_data , 也就是說我們應(yīng)該從這解析該協(xié)議
struct attack { ... } : 這就是我們模塊的核心
- struct attack {
- int16_t v; : 記錄攻擊的次數(shù)
- char *s; : 對該攻擊的一些描述
- int8_t type; : 是否為 (DOS) 攻擊
- int8_t single; : 我們是一次發(fā)一個還是洪水般發(fā)送
- void (*attack_th_launch)(void *); : 我們發(fā)動攻擊的回調(diào)函數(shù)
- const struct attack_param *param; : 上邊函數(shù)的參數(shù)
- u_int8_t nparams; : 上邊函數(shù)的參數(shù)個數(shù)
- };
這就是我們一開始等待的東西,這就是我們的攻擊功能的模塊的核心,在 fot1q.h 中有詳細(xì)的介紹 :
- -----------------------------------------------------------------------------------------
- #define DOT1Q_ATTACK_SEND 0
- #define DOT1Q_ATTACK_DOUBLE 1
- #define DOT1Q_ATTACK_POISON 2
- static struct attack dot1q_attack[] = {
- { DOT1Q_ATTACK_SEND, "sending 802.1Q packet", NONDOS, SINGLE, dot1q_th_send, NULL, 0 },
- { DOT1Q_ATTACK_DOUBLE, "sending 802.1Q double enc. packet", NONDOS, SINGLE, dot1q_double_th_send, NULL, 0 },
- { DOT1Q_ATTACK_POISON, "sending 802.1Q arp poisoning", DOS, CONTINOUS, dot1q_th_poison,
- dot1q_arp_params, SIZE_ARRAY(dot1q_arp_params) },
- { 0, NULL, 0, 0, NULL, NULL, 0 }
- };
- void dot1q_th_send(void *);
- void dot1q_th_send_exit(struct attacks *);
- void dot1q_double_th_send(void *);
- void dot1q_double_th_send_exit(struct attacks *);
- void dot1q_th_poison(void *);
- void dot1q_th_poison_exit(struct attacks *);
- -----------------------------------------------------------------------------------------
- 從上可以看出傳遞到registration函數(shù)的是一個attack結(jié)構(gòu)體數(shù)組,xxxxx,下面介紹結(jié)構(gòu)體中的各字段
- - v: 好像是每個 attack 的ID : 0,1,2 ...
- - s: 一些 attack 的描述
- - type: 是否為拒絕服務(wù)式的攻擊(DOS)
- - single: 我們是發(fā)送一個數(shù)據(jù)包(SINGLE) 還是發(fā)送洪水?dāng)?shù)據(jù)包(CONTINUOUS)
- - attack_th_launch: 我們將要調(diào)用的函數(shù),比如在這個函數(shù)中完成這次攻擊
- - param, nparams: 傳遞給上述函數(shù)的參數(shù)和參數(shù)個數(shù)
- 下面看下 dot1q.c 和 terminal-defs.h 文件
- -----------------------------------------------------------------------------------------
- struct attacks
- {
- u_int8_t up; /* active or not */
- THREAD attack_th;
- THREAD helper_th;
- u_int16_t attack; /* attack number */
- list_t *used_ints; /* interfaces used */
- u_int8_t mac_spoofing;
- void *data; /* packet */
- void *params; /* Parameters */
- u_int8_t nparams; /* How many params */
- };
- void dot1q_th_send(void *arg)
- {
- struct attacks *attacks=NULL;
- sigset_t mask;
- struct dot1q_data *dot1q_data;
- attacks = arg;
- pthread_mutex_lock(&attacks->attack_th.finished);
- pthread_detach(pthread_self());
- sigfillset(&mask);
- if (pthread_sigmask(SIG_BLOCK, &mask, NULL))
- {
- thread_error("dot1q_th_send pthread_sigmask()",errno);
- dot1q_th_send_exit(attacks);
- }
- dot1q_data = attacks->data;
- dot1q_data->tpi1 = ETHERTYPE_VLAN;
- dot1q_data->tpi2 = ETHERTYPE_IP;
- dot1q_send_icmp(attacks,0);
- dot1q_th_send_exit(attacks);
- }
- void dot1q_th_send_exit(struct attacks *attacks)
- {
- if (attacks) attack_th_exit(attacks);
- pthread_mutex_unlock(&attacks->attack_th.finished);
- pthread_exit(NULL);
- }
- int8_t dot1q_send_icmp(struct attacks *attacks, u_int8_t double_encap)
- {
- .....code.....
- }
- -----------------------------------------------------------------------------------------
注意 attacks 結(jié)構(gòu)體和 attack 結(jié)構(gòu)體是完全不一樣的,attacks 對象是傳遞給函數(shù) dot1q_th_send 的,還有參數(shù)(arg),每個attack都含很多有用的信息,比如 thread-id(每個attack都在一個單獨(dú)的線程中) , dot1q_data(數(shù)據(jù)) ,還有參數(shù)及參數(shù)的個數(shù)等 . 然后我們在 dot1q_th_send() 中創(chuàng)建一個互斥體 , 然后調(diào)用 pthread_detach() (與主線程分享) ,然后調(diào)用 dot1q_send_icmp(attacks,0) , 然后調(diào)用 dot1q_th_send_exit(attacks) 函數(shù)