feat: added modified TCP packet parser
checksum generation code is different, to allow for some sneaky tricks with regards to identifying the sparse session but binding to the same port multiple times
This commit is contained in:
@@ -452,13 +452,14 @@ impl TCPPacket {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct TCPPacketBuilder {
|
||||
srcport: u16,
|
||||
dstport: u16,
|
||||
seqnumber: u32,
|
||||
srcport: Option<u16>,
|
||||
dstport: Option<u16>,
|
||||
seqnumber: Option<u32>,
|
||||
acknumber: u32,
|
||||
flags: u8,
|
||||
window: u16,
|
||||
window: Option<u16>,
|
||||
urgent_ptr: u16,
|
||||
options: Vec<u8>,
|
||||
}
|
||||
@@ -478,17 +479,17 @@ macro_rules! declare_flag {
|
||||
|
||||
impl TCPPacketBuilder {
|
||||
pub fn srcport(mut self, port: u16) -> Self {
|
||||
self.srcport = port;
|
||||
self.srcport = Some(port);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn dstport(mut self, port: u16) -> Self {
|
||||
self.dstport = port;
|
||||
self.dstport = Some(port);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn seqnumber(mut self, num: u32) -> Self {
|
||||
self.seqnumber = num;
|
||||
self.seqnumber = Some(num);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -507,7 +508,7 @@ impl TCPPacketBuilder {
|
||||
declare_flag!(fin, 0x01);
|
||||
|
||||
pub fn window(mut self, window: u16) -> Self {
|
||||
self.window = window;
|
||||
self.window = Some(window);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -531,6 +532,93 @@ impl TCPPacketBuilder {
|
||||
|
||||
let protocol = &[0x00u8, 0x06u8];
|
||||
|
||||
let tcp_length = data.len() + self.options.len() + 32;
|
||||
let tcp_length = (data.len() + self.options.len() + 20) as u16;
|
||||
|
||||
let srcport = self.srcport.unwrap();
|
||||
let dstport = self.dstport.unwrap();
|
||||
let seqnumber = self.seqnumber.unwrap();
|
||||
let window = self.window.unwrap();
|
||||
|
||||
let len: u8 = (self.options.len() / 4 + 5).try_into().unwrap();
|
||||
let len = len << 4;
|
||||
|
||||
let mut bytes = [
|
||||
&source.octets()[..],
|
||||
&dest.octets(),
|
||||
protocol,
|
||||
&tcp_length.to_be_bytes(),
|
||||
&srcport.to_be_bytes()[..],
|
||||
&dstport.to_be_bytes(),
|
||||
&seqnumber.to_be_bytes(),
|
||||
&self.acknumber.to_be_bytes(),
|
||||
&[len],
|
||||
&[self.flags],
|
||||
&window.to_be_bytes(),
|
||||
&[0, 0],
|
||||
&self.urgent_ptr.to_be_bytes(),
|
||||
&self.options,
|
||||
&data,
|
||||
]
|
||||
.concat();
|
||||
|
||||
let checksum = bytes
|
||||
.chunks(2)
|
||||
.map(|pair| {
|
||||
if pair.len() == 1 {
|
||||
(pair[0] as u32) << 8
|
||||
} else {
|
||||
(pair[0] as u32) << 8 | (pair[1] as u32)
|
||||
}
|
||||
})
|
||||
.fold(0u32, |acc, e| acc + e)
|
||||
+ 30;
|
||||
// + 30 to intentionally deviate from
|
||||
// the RFC, to make it so that I can identify the packets as sparse
|
||||
// packets
|
||||
|
||||
let checksum = (checksum >> 16) + (checksum & 0xffff);
|
||||
let checksum = ((checksum >> 16) as u16) + (checksum as u16);
|
||||
let checksum = dbg!(!checksum).to_be_bytes();
|
||||
|
||||
//bytes[16] = checksum[0];
|
||||
//bytes[17] = checksum[1];
|
||||
bytes[28] = checksum[0];
|
||||
bytes[29] = checksum[1];
|
||||
|
||||
TCPPacket {
|
||||
data: bytes[12..].to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
#[test]
|
||||
fn test_tcp_checksum() {
|
||||
let srcip = Ipv4Addr::new(127, 0, 0, 1);
|
||||
let dstip = srcip.clone();
|
||||
|
||||
let packet = super::TCPPacketBuilder::default()
|
||||
.srcport(36916)
|
||||
.dstport(54248)
|
||||
.seqnumber(0xFD65_CA26)
|
||||
.syn(true)
|
||||
.window(65495)
|
||||
.options(vec![
|
||||
0x02, 0x04, 0xff, 0xd7, 0x04, 0x02, 0x08, 0x0a, 0xce, 0x4e, 0xad, 0x04, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x03, 0x03, 0x07,
|
||||
])
|
||||
.build(srcip, dstip, vec![]);
|
||||
|
||||
assert_eq!(
|
||||
&packet.data,
|
||||
&vec![
|
||||
0x90, 0x34, 0xd3, 0xe8, 0xfd, 0x65, 0xca, 0x26, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02,
|
||||
0xff, 0xd7, 0xfe, 0x30, 0x00, 0x00, 0x02, 0x04, 0xff, 0xd7, 0x04, 0x02, 0x08, 0x0a,
|
||||
0xce, 0x4e, 0xad, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x07
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user