From 071d7d092f33be4b20a737206434ec873805ad4b Mon Sep 17 00:00:00 2001 From: chn <897331845@qq.com> Date: Fri, 10 Jan 2020 15:31:50 +0800 Subject: [PATCH] --- README.md | 5 --- src/rkpManager.h | 2 +- src/rkpMap.h | 90 ++++++++++++++++++++++++++++++++++++++++++++--- src/rkpPacket.h | 30 ++++++++++++---- src/rkpSettings.h | 26 ++++++++++++++ src/rkpStream.h | 18 +++------- 6 files changed, 141 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index f0d1f94..f28f18b 100644 --- a/README.md +++ b/README.md @@ -143,8 +143,3 @@ flush 函数,关闭超时的流。 用比较宽松的方案去处理。当找不到需要的流的时候去新建而不是寻找三次握手的首包。当扫描到 User-Agent: 后再捕获包、分析、修改,避免不是 HTTP 流量的包被捕获。如果捕获过程中读到 psh,即使没有读到 UA 末尾也要提交。UA 的长度也需要作假设;可以假定为最多两个包。 -接下来需要修改的文件有: - -c -Manager -Stream \ No newline at end of file diff --git a/src/rkpManager.h b/src/rkpManager.h index 564c421..b45937e 100644 --- a/src/rkpManager.h +++ b/src/rkpManager.h @@ -3,7 +3,7 @@ struct rkpManager { - struct rkpStream* data[256]; // 按照首包的两端口之和的低 8 位放置 + struct rkpStream* data[256]; // 按照两端口之和的低 8 位索引 spinlock_t lock; // 线程锁 struct timer_list timer; // 定时器,用来定时清理不需要的流 }; diff --git a/src/rkpMap.h b/src/rkpMap.h index 20876a3..a288dd8 100644 --- a/src/rkpMap.h +++ b/src/rkpMap.h @@ -3,13 +3,95 @@ #include "rkpPacket.h" struct rkpMap +// 以相对序列号记录应用层数据中需要修改的部分的位置,提供修改的函数 { - int32_t left, right; + int32_t begin, length; // begin 为绝对 struct rkpMap *prev, *next; }; struct rkpMap* rkpMap_new(int32_t, int32_t); -void rkpMap_delete(int32_t, int32_t); +void rkpMap_delete(struct rkpMap*); -unsigned char rkpMap_map(int32_t); -void rkpMap_modify(struct rkpPacket*); +unsigned char __rkpMap_map(const struct rkpMap*, int32_t); // 返回某个序列号对应的映射后的值。假定参数是合法的。第一个参数实际上没有用。 +void rkpMap_modify(const struct rkpMap*, struct rkpPacket**, int32_t); // 对一列序列号连续且递增的包进行修改 + +void rkpMap_insert_begin(struct rkpMap**, struct rkpMap*); // 在开头位置插入一个映射 +void rkpMap_insert_end(struct rkpMap**, struct rkpMap*); +void rkpMap_refresh(struct rkpMap**, int32_t, int32_t); // 对于一列序列号递增的映射, + +struct rkpMap* rkpMap_new(int32_t begin, int32_t length) +{ + struct rkpMap* rkpm = (struct rkpMap*)rkpMalloc(sizeof(struct rkpMap)); + if(rkpm == 0) + return 0; + rkpm -> begin = begin; + rkpm -> length = length; + rkpm -> prev = rkpm -> next = 0; + return rkpm; +} +void rkpMap_delete(struct rkpMap* rkpm) +{ + rkpFree(rkpm); +} + +unsigned char __rkpMap_map(const struct rkpMap* rkpm, int32_t seq) +{ + int32_t offset = seq - rkpm -> begin; + if(offset < strlen(str_uaRkp)) + return str_uaRkp[offset]; + else + return ' '; +} +void rkpMap_modify(const struct rkpMap* rkpm, struct rkpPacket** rkppl, int32_t doff) +{ + int32_t seql = rkpPacket_seq(rkpp, doff), seqr = seql + rkpPacket_appLen(rkpp); + unsigned char *pl = rkpPacket_appBegin(rkpp), *pr = rkpPacket_appEnd(rkpp); + if(seql >= rkpm -> begin + rkpm -> length || seqr <= rkpm -> begin) + return; + if(seqr > rkpm -> begin + rkpm -> length) + { + unsigned doff = seqr - (rkpm -> begin + rkpm -> length); + seqr -= doff; + pr -= doff; + } + if(seql < rkpm -> begin) + { + unsigned doff = rkpm -> begin - seql; + seql += doff; + pl += doff; + } + for(;seql < seqr; seql++, pl++) + *pl = __rkpMap_map(rkpm, seql); +} +void rkpMap_move(struct rkpMap* rkpm, int32_t doff) +{ + rkpm -> begin += doff; +} + +void rkpMap_insert_begin(struct rkpMap** rkpml, struct rkpMap* rkpm) +{ + rkpm -> next = *rkpml; + rkpm -> prev = 0; + *rkpml = rkpm; + if(rkpm -> next != 0) + rkpm -> next -> prev = rkpm; +} +void rkpMap_refresh(struct rkpMap** rkpml, int32_t seq) +{ + struct rkpMap* rkpm = *rkpml; + while(rkpm != 0) + { + if(rkpm -> begin + rkpm -> length <= seq) + { + struct rkpMap* rkpm2 = rkpm -> next; + if(rkpm -> prev != 0) + rkpm -> prev -> next = rkpm -> next; + if(rkpm -> next != 0) + rkpm -> next -> prev = rkpm -> prev; + rkpMap_delete(rkpm); + rkpm = rkpm2; + } + else + rkpm = rkpm -> next; + } +} \ No newline at end of file diff --git a/src/rkpPacket.h b/src/rkpPacket.h index db02b4d..77cd182 100644 --- a/src/rkpPacket.h +++ b/src/rkpPacket.h @@ -8,9 +8,10 @@ struct rkpPacket struct sk_buff* skb; u_int8_t sid; u_int32_t lid[3]; + bool ack; }; -struct rkpPacket* rkpPacket_new(struct sk_buff*); +struct rkpPacket* rkpPacket_new(struct sk_buff*, bool); void rkpPacket_send(struct rkpPacket*); void rkpPacket_delete(struct rkpPacket*); void rkpPacket_drop(struct rkpPacket*); @@ -19,13 +20,14 @@ unsigned char* rkpPacket_appBegin(const struct rkpPacket*); unsigned char* rkpPacket_appEnd(const struct rkpPacket*); unsigned rkpPacket_appLen(const struct rkpPacket*); int32_t rkpPacket_seq(const struct rkpPacket*, const int32_t); -int32_t rkpPacket_ack(const struct rkpPacket*, const int32_t); +int32_t rkpPacket_seqAck(const struct rkpPacket*, const int32_t); u_int32_t rkpPacket_sip(const struct rkpPacket*); u_int32_t rkpPacket_dip(const struct rkpPacket*); u_int16_t rkpPacket_sport(const struct rkpPacket*); u_int16_t rkpPacket_dport(const struct rkpPacket*); bool rkpPacket_psh(const struct rkpPacket*); bool rkpPacket_syn(const struct rkpPacket*); +bool rkpPacket_ack(const struct rkpPacket*); void rkpPacket_csum(struct rkpPacket*); bool __rkpPacket_makeWriteable(struct rkpPacket*); @@ -43,17 +45,27 @@ void rkpPacket_sendl(struct rkpPacket**); void rkpPacket_deletel(struct rkpPacket**); void rkpPacket_dropl(struct rkpPacket**); -struct rkpPacket* rkpPacket_new(struct sk_buff* skb) +struct rkpPacket* rkpPacket_new(struct sk_buff* skb, bool ack) { struct rkpPacket* rkpp = rkpMalloc(sizeof(struct rkpPacket)); if(rkpp == 0) return 0; rkpp -> prev = rkpp -> next = 0; rkpp -> skb = skb; + rkpp -> ack = ack; rkpp -> sid = (rkpPacket_sport(rkpp) + rkpPacket_dport(rkpp)) & 0xFF; - rkpp -> lid[0] = rkpPacket_sip(rkpp); - rkpp -> lid[1] = rkpPacket_dip(rkpp); - rkpp -> lid[2] = (rkpPacket_sport(rkpp) << 16) + rkpPacket_dport(rkpp); + if(!ack) + { + rkpp -> lid[0] = rkpPacket_sip(rkpp); + rkpp -> lid[1] = rkpPacket_dip(rkpp); + rkpp -> lid[2] = (rkpPacket_sport(rkpp) << 16) + rkpPacket_dport(rkpp); + } + else + { + rkpp -> lid[0] = rkpPacket_dip(rkpp); + rkpp -> lid[1] = rkpPacket_sip(rkpp); + rkpp -> lid[2] = (rkpPacket_dport(rkpp) << 16) + rkpPacket_sport(rkpp); + } if(!__rkpPacket_makeWriteable(rkpp)) { rkpFree(rkpp); @@ -96,7 +108,7 @@ int32_t rkpPacket_seq(const struct rkpPacket* p, const int32_t offset) { return (int32_t)ntohl(tcp_hdr(p -> skb) -> seq) - offset; } -int32_t rkpPacket_ack(const struct rkpPacket* p, const int32_t offset) +int32_t rkpPacket_seqAck(const struct rkpPacket* p, const int32_t offset) { return (int32_t)ntohl(tcp_hdr(p -> skb) -> ack) - offset; } @@ -124,6 +136,10 @@ bool rkpPacket_syn(const struct rkpPacket* rkpp) { return tcp_hdr(rkpp -> skb) -> syn; } +bool rkpPacket_ack(const struct rkpPacket* rkpp) +{ + return tcp_hdr(rkpp -> skb) -> ack; +} void rkpPacket_csum(struct rkpPacket* rkpp) { diff --git a/src/rkpSettings.h b/src/rkpSettings.h index 65bf8c5..87e01fe 100644 --- a/src/rkpSettings.h +++ b/src/rkpSettings.h @@ -11,6 +11,8 @@ static unsigned n_str_preserve = 0; module_param_array(str_preserve, charp, &n_str_preserve, 0); static unsigned mark_capture = 0x100; module_param(mark_capture, uint, 0); +static unsigned mark_ack = 0x200; +module_param(mark_ack, uint, 0); static unsigned time_keepalive = 1200; module_param(time_keepalive, uint, 0); static unsigned len_ua = 2; @@ -21,6 +23,7 @@ static bool debug = false; module_param(debug, bool, 0); bool rkpSettings_capture(const struct sk_buff*); +bool rkpSettings_ack(const struct sk_buff*); bool rkpSettings_capture(const struct sk_buff* skb) { @@ -30,6 +33,8 @@ bool rkpSettings_capture(const struct sk_buff* skb) } else { + if(rkpSettings_ack(skb)) + return true; if(ip_hdr(skb) -> protocol != IPPROTO_TCP) return false; else if(ntohs(tcp_hdr(skb) -> dest) != 80) @@ -40,4 +45,25 @@ bool rkpSettings_capture(const struct sk_buff* skb) else return true; } +} +bool rkpSettings_ack(const struct sk_buff* skb) +{ + if(!autocapture) + { + return (skb -> mark & mark_ack) == mark_ack; + } + else + { + if(ip_hdr(skb) -> protocol != IPPROTO_TCP) + return false; + else if(ntohs(tcp_hdr(skb) -> source) != 80) + return false; + else if((ntohl(ip_hdr(skb) -> daddr) & 0xFFFF0000) != (192 << 24) + (168 << 16) + || (ntohl(ip_hdr(skb) -> saddr) & 0xFFFF0000) == (192 << 24) + (168 << 16)) + return false; + else if(tcp_hdr(skb) -> ack) + return true; + else + return false; + } } \ No newline at end of file diff --git a/src/rkpStream.h b/src/rkpStream.h index e60a3c7..12d3d56 100644 --- a/src/rkpStream.h +++ b/src/rkpStream.h @@ -17,6 +17,7 @@ struct rkpStream bool active; // 是否仍然活动,流每次处理的时候会置为 true,每隔一段时间会删除标志为 false(说明它在这段时间里没有活动)的流,将标志为 true 的流的标志也置为 false。 unsigned scan_headEnd_matched, scan_uaBegin_matched, scan_uaEnd_matched; // 记录现在已经匹配了多少个字节,由 __rkpStream_scan 设置,但可以由其它过程置零 unsigned char *scan_uaBegin_p, *scan_uaEnd_p; // 记录扫描的一些结果,由 __rkpStream_scan 设置,但可以由其它过程置零 + struct rkpMap* map; struct rkpStream *prev, *next; }; @@ -47,6 +48,7 @@ struct rkpStream* rkpStream_new(const struct rkpPacket* rkpp) rkps -> active = true; rkps -> scan_headEnd_matched = rkps -> scan_uaBegin_matched = rkps -> scan_uaEnd_matched = 0; rkps -> scan_uaBegin_p = rkps -> scan_uaEnd_p = 0; + rkps -> map = 0; rkps -> prev = rkps -> next = 0; return rkps; } @@ -55,18 +57,8 @@ void rkpStream_delete(struct rkpStream* rkps) struct rkpPacket* rkpp; if(debug) printk("rkpStream_delete\n"); - for(rkpp = rkps -> buff_scan; rkpp != 0;) - { - struct rkpPacket* rkpp2 = rkpp; - rkpp = rkpp -> next; - rkpPacket_drop(rkpp2); - } - for(rkpp = rkps -> buff_disordered; rkpp != 0;) - { - struct rkpPacket* rkpp2 = rkpp; - rkpp = rkpp -> next; - rkpPacket_drop(rkpp2); - } + rkpPacket_deletel(&rkps -> buff_scan); + rkpPacket_deletel(&rkps -> buff_disordered); rkpFree(rkps); } @@ -85,7 +77,7 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct rkpPacket* rkpp) rkps -> active = true; // 接下来从小到大考虑数据包的序列号的几种情况 - // 已经发出的数据包,直接忽略 + // 已经发出的数据包,使用已有的映射修改 if(rkpPacket_seq(rkpp, rkps -> seq_offset) < 0) { if(debug)