天天看點

在NS2 AODV協定中添加blackhole attacker(黑洞攻擊)

      在NS2-3.34中添加黑洞攻擊的過程還是比較簡單的,具體過程大緻如下描述:

1. 首先我們在aodv/aodv.h中的AODV類中添加一個标志該Agent(該節點是blackhole的标志)

    class AODV: public Agent {

int blackhole; //是否是攻擊節點

}

2.修改aodv/aodv.cc以實作blackhole 攻擊

首先是在command 中定義相應的TCL “blackhole”

if (strcmp(argv[1], "blackhole") == 0) {

printf("exsits blackhole/n");

blackhole = 1;

return TCL_OK;

}

接下來根據AODV協定和blackhole attack 的特點,我們實作blackhole attack的攻擊過程(具體的攻擊手段就是

在接收到某個節點發來的路由請求後,黑洞攻擊節點不是檢視路由表是否由到達目的節點的路由,進而轉發或回複一個RREP。

取而代之的是,在它接收到一個RREQ後,立即回複一個RREP路由回複包,說他有到達目的節點的最優路徑。而且當黑洞攻擊節點

接收到資料包時,全部丢掉,進而形成一個像黑洞一樣的攻擊,資料包隻進不出。具體詳細關于黑洞攻擊請google了解):

修改aodv.cc 中的recvRequest(Packet *p)函數:

void

AODV::recvRequest(Packet *p) {

if(debug>1) printf("recvRequest/n");

struct hdr_ip *ih = HDR_IP(p);

struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);

aodv_rt_entry *rt;

/*

* Drop if:

* - I'm the source

* - I recently heard this request.

*/

if (rq->rq_src == index) {

#ifdef DEBUG

//fprintf(stderr, "%s: got my own REQUEST/n", __FUNCTION__);

#endif // DEBUG

Packet::free(p); //如果是自己發出來的就直接丢棄

return;

}

if (id_lookup(rq->rq_src, rq->rq_bcast_id)) {

#ifdef DEBUG

//fprintf(stderr, "%s: discarding request/n", __FUNCTION__);

#endif // DEBUG

// printf("我之前已經接收到了這個分組!and my id is %d /n", index);

Packet::free(p); //這個分組已經收到過

return;

}

/*

* Cache the broadcast ID

*/

id_insert(rq->rq_src, rq->rq_bcast_id);

/*

* We are either going to forward the REQUEST or generate a

* REPLY. Before we do anything, we make sure that the REVERSE

* route is in the route table.

*/

aodv_rt_entry *rt0; // rt0 is the reverse route

rt0 = rtable.rt_lookup(rq->rq_src);

if (rt0 == 0) { /* if not in the route table */

// create an entry for the reverse route.

rt0 = rtable.rt_add(rq->rq_src);

}

rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE));

if ( (rq->rq_src_seqno > rt0->rt_seqno ) ||

((rq->rq_src_seqno == rt0->rt_seqno) &&

(rq->rq_hop_count < rt0->rt_hops)) ) {

// If we have a fresher seq no. or lesser #hops for the

// same seq no., update the rt entry. Else don't bother.

rt_update(rt0, rq->rq_src_seqno, rq->rq_hop_count, ih->saddr(),

max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)) );

if (rt0->rt_req_timeout > 0.0) {

// Reset the soft state and

// Set expiry time to CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT

// This is because route is used in the forward direction,

// but only sources get benefited by this change

rt0->rt_req_cnt = 0;

rt0->rt_req_timeout = 0.0;

rt0->rt_req_last_ttl = rq->rq_hop_count;

rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;

}

/* Find out whether any buffered packet can benefit from the

* reverse route.

* May need some change in the following code - Mahesh 09/11/99

*/

assert (rt0->rt_flags == RTF_UP);

Packet *buffered_pkt;

while ((buffered_pkt = rqueue.deque(rt0->rt_dst))) {

if (rt0 && (rt0->rt_flags == RTF_UP)) {

assert(rt0->rt_hops != INFINITY2);

forward(rt0, buffered_pkt, NO_DELAY);

}

}

}

// End for putting reverse route in rt table

/*

* We have taken care of the reverse route stuff.

* Now see whether we can send a route reply.

*/

rt = rtable.rt_lookup(rq->rq_dst);

// First check if I am the destination ..

if (rq->rq_dst == index) {

#ifdef DEBUG

fprintf(stderr, "%d - %s: destination sending reply/n",

index, __FUNCTION__);

#endif // DEBUG

//printf("I am the desitination and my ip address is %d/n", index);

// Just to be safe, I use the max. Somebody may have

// incremented the dst seqno.

seqno = max(seqno, rq->rq_dst_seqno) + 1;

if (seqno % 2) seqno++;

sendReply(rq->rq_src, // IP Destination

1, // Hop Count

index, // Dest IP Address

seqno, // Dest Sequence Num

rq->rq_src,

MY_ROUTE_TIMEOUT, // Lifetime

rq->rq_timestamp); // timestamp

Packet::free(p);

}

// I am not the destination, but I may have a fresh enough route.

//Start balckhole Code

//a Blackhole attacker always say that have the route to be a sink.

else if ((rt && blackhole == 1)) {

assert(rq->rq_dst == rt->rt_dst);

//printf("I am the blackhole node and blackhole = %d/n", index);

sendReply(rq->rq_src,

1,

//rt->rt_hops, //Blackhole gravity.

rq->rq_dst,

//rt->rt_seqno + 10, //Blackhole gravity.

4294967295,

rq->rq_src,

(u_int32_t) (rt->rt_expire - CURRENT_TIME),

rq->rq_timestamp);

rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source

rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination

//printf("node ip = %d,rt->rt_hops = %d, rt->rt_seqno = %d/n",index,rt->rt_hops, rt->rt_seqno);

#ifdef RREQ_GRAT_RREP

sendReply(rq->rq_dst,

rq->rq_hop_count,

rq->rq_src,

rq->rq_src_seqno,

rq->rq_src,

(u_int32_t) (rt->rt_expire - CURRENT_TIME),

rq->rq_timestamp);

printf("ifndef RREQ_GRAT_RREP....../n");

#endif

Packet::free(p);

}

//End balckhole Code

/*Sniffer IDS 假設中間節點是不能回複RREP的,但是黑洞攻擊節點卻必須可疑回複,其實這種做法明顯是存在很大的缺陷的。

這樣即使可以有效隔離黑洞攻擊節點,但是這隻能說是路由協定的一種特殊條件的下的檢測方法。

後面我希望在此基礎上做進一步的改進,可以把這種攻擊手段擴大化,也就是更加普遍話。适應各種路由情況,而不僅限于某種特殊情況

*/

} else if ((rt && (rt->rt_hops != INFINITY2) &&

(rt->rt_seqno >= rq->rq_dst_seqno) )) {

//printf("I am not the desitination, but is may have a fresh enough route/n");

//assert (rt->rt_flags == RTF_UP);

assert(rq->rq_dst == rt->rt_dst);

//assert ((rt->rt_seqno%2) == 0); // is the seqno even?

sendReply(rq->rq_src,

rt->rt_hops + 1,

rq->rq_dst,

rt->rt_seqno,

rq->rq_src,

(u_int32_t) (rt->rt_expire - CURRENT_TIME),

// rt->rt_expire - CURRENT_TIME,

rq->rq_timestamp);

// Insert nexthops to RREQ source and RREQ destination in the

// precursor lists of destination and source respectively

rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source

rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination

#ifdef RREQ_GRAT_RREP

sendReply(rq->rq_dst,

rq->rq_hop_count,

rq->rq_src,

rq->rq_src_seqno,

rq->rq_src,

(u_int32_t) (rt->rt_expire - CURRENT_TIME),

// rt->rt_expire - CURRENT_TIME,

rq->rq_timestamp);

printf("I am not the desitination, but is may have a fresh enough route , RREQ_GRAT_RREP/n");

#endif

// TODO: send grat RREP to dst if G flag set in RREQ using rq->rq_src_seqno, rq->rq_hop_counT

// DONE: Included gratuitous replies to be sent as per IETF aodv draft specification. As of now, G flag has not been dynamically used and is always set or reset in aodv-packet.h --- Anant Utgikar, 09/16/02.

Packet::free(p);

}

/*

* Can't reply. So forward the Route Request

*/

else {

//Start Blackhole Code

if(blackhole == 1) //是黑洞攻擊節點

{

//printf("%d can't replay, but %d is a attacker, so i will replay the RREP packets/n", index, index);

sendReply(rq->rq_src, // IP Destination

1, // Hop Count

rq->rq_dst, // Dest IP Address

4294967295, // Highest Dest Sequence Num that is largest 32-bit integers from -2147483647 to +2147483647

rq->rq_src,

//rt->rt_seqno + 10,

MY_ROUTE_TIMEOUT, // Lifetime

rq->rq_timestamp); // timestamp

Packet::free(p);

}//End Blackhole Code

else

{

ih->saddr() = index;

ih->daddr() = IP_BROADCAST;

rq->rq_hop_count += 1;

// Maximum sequence number seen en route

if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno);

forward((aodv_rt_entry*) 0, p, DELA

這裡面的sendReply我是修改過了的,就是添加一個字段。這個和實作黑洞攻擊沒有關系。可以忽略!

然後實作所有的黑洞攻擊節點在接收到資料包時(自己不是目的節點),把所有接收到的資料包直接丢掉

在AODV::rt_resolve(Packet *p) 函數中添加:

//if (rt->rt_flags == RTF_UP){

if ((rt->rt_flags == RTF_UP) &&

//Start Watchdog Code

(blackhole != 1)) {

//End Watchdog Code

assert(rt->rt_hops != INFINITY2);

forward(rt, p, NO_DELAY);

// printf("%f forward this packet by not need the REQUEST, dst = %d/n and next_hop = %d/n", Scheduler::instance().clock(),ih->daddr(), rt->rt_nexthop);

}

//Start Watchdog Code

else if(blackhole == 1 && ih->daddr() != index){ //黑洞節點并且我不是目的節點

if(blackholed == 0 && packets_dropped >= PACKETS_TO_CONSIDER_AN_ATTACK){

blackholed=1;

printAttackMessage(p);

}

packets_dropped++;

drop(p, DROP_IFQ_FILTER);

return;

}

//End Watchdog Code

3.最後我們還需要在tcl/lib/ns-mobilenode.tcl中添加

#Blackhole

Node/MobileNode instproc set_Blackhole {} {

    $self instvar ragent_

        puts "Installing new blackhole...................."

        return $ragent_

}

4.這樣我們可以直接在tcl腳本中使用黑洞攻擊節點了:

set n3 [$ns node]

$n3 set X_ 372

$n3 set Y_ 400

$n3 set Z_ 0.0

$ns initial_node_pos $n3 20

$ns at 0.01 "[$n3 set ragent_] blackhole"

$ns at 0.01 "$n3 label /"blackhole node/" "

這裡就是把節點3定義為一個黑洞攻擊節點。

注:在協定中添加攻擊行為還可以使用另外一種方法進行添加,就是像建立一種新的協定過程一樣,比如說建立一種叫做blackholeAODV

整個協定的建立過程跟很多樹上描述的建立一個新的MyPing協定過程一樣。這裡面的blackholeAODV協定建立過程按照AODV協定建立過程,然後修改AODV協定,使得這個協定能夠實作黑洞攻擊。最後在tcl腳本中使用是,和使用AODV協定配置一樣。比如說你協定的定義的TCL為blackholeAODV,則可以這樣子調用:

set val(brp) blackholeAODV ;# blackhole attack in AODV

$ns node-config -adhocRouting $val(brp)

set n3 [$ns node]

$n3 set X_ 372

$n3 set Y_ 400

$n3 set Z_ 0.0

$ns initial_node_pos $n3 20

這樣同樣可以實作上面的黑洞攻擊的功能。

繼續閱讀