0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ステルス・スキャン あるいは カリグラム的プログラム

Last updated at Posted at 2023-08-20

前回のプログラムでカリグラム的なことをしてみました。

ステルス・スキャンなので「隠」の一字です。

const TO:u64=5000;const M:[&str;4]=["open","closed","timeout","unknown"];use pnet::{
ipnetwork::IpNetwork as IN,packet::{ip::IpNextHeaderProtocols::Tcp, ipv4::Ipv4Packet
as I4P,  Packet,  tcp :: { ipv4_checksum  as  ic,           MutableTcpPacket as MTP,
TcpFlags:: {ACK, RST, SYN},  TcpOption as TOP,             TcpPacket as TP},ethernet
:: {EtherTypes as ET,  EthernetPacket as EP}},                  datalink::{Channel::
Ethernet as E,NetworkInterface as NI, {channel                 as chn, interfaces as
ifcs }}, transport:: { transport_channel as tc,               TransportChannelType::
Layer4 as L4,TransportProtocol::Ipv4}};use rand              ::Rng; use std::{net::{
IpAddr  as     IA,     Ipv4Addr as I4A},str::               FromStr,  sync::mpsc:: {
channel as ch,          RecvError   as   MRE,             RecvTimeoutError as MRTE},
thread::{                sleep,spawn},time          ::Duration as D};const SA:u8=SYN
+ACK;const                RA:u8=RST+ACK;fn       main(){if let Err(e)=run(){eprintln
!(                        "[Error] {:?}",e)  }}fn run()->Result<(),ME>{let args:Vec<
String                    >=std::env::args()   .collect();if args.len()<2{return Ok(
eprintln                  !(                    "Usage: {} interface ip:port",args[0
]))                      ;}if   args.len()<3      {return         Err(ME::TFAE);}let
ifcn=      &args         [1];let tgt:&str=&            args[2       ];Ok(pr(tgt,prc(
ifcn.to_string          (),tgt    )?))}fn pr         (tgt:&str       ,ff:u8){println
!("[Result]");          println     !("{}: {}"       ,tgt,M[          match ff{SA=>0
,RA=>1,0=>2,_          =>3,}])       ;}fn prc        (ifcn:          String,tgt:&str
)->Result<u8,         ME>{let(ri      ,rp)=sip       (tgt)?           ;let r=ifcs().
into_iter().          find(|ifc         |ifc.        name==       ifcn);if r.is_none
(){return Err        (ME::UIE);          }let       ifc=r          .unwrap();println
!(                  "Interface: {}"      ,ifc.name  );let         mut li:Option<I4A>
=None;for ip        in&ifc.ips{if         let IN:: V4(v4         )=ip{li=Some(v4.ip(
));break;}}        if li.is_none(         ){return Err         (ME::LIE);}let li=li.
unwrap();let      mut rng=rand::          thread_rng(        );let lp=rng.gen_range(
32768..=60999    );let ff=SYN; let        seq:u32=        rand::random();let ack:u32
=0;    println    !("Local:  {}:{}",li   ,lp);           println!("Remote: {}:{}",ri
,rp     );s_r     (ifc,lp,rp,li,ri,ff,seq,ack)             }fn s_r(ifc:NI,lp:u16,rp:
u16     ,li:I4A    ,ri:I4A,ff:u8,seq:u32,ack                   :u32,)->Result<u8,ME>
{let     (mut       tx,_)=tc(4096,L4(                               Ipv4(Tcp)))?;let
mut      bb:[u8       ;24]=[0;24];let                                p=th(&mut bb,lp
,rp       ,li,ri       ,ff,seq,ack)?                   ;let(          t,r)=ch(); let
h =       spawn (       move||{t.send             (match recv          (ifc,lp,rp,li
,ri       ){Err(e)       =>{eprintln          !("[Error] {:?}"         ,e);0u8}Ok(ff
)=>       ff, } ).       unwrap();});   sleep(D::from_millis           (100));   tx.
send_to    (p,IA::         V4(ri))?; pth( "[Sent]", ff, seq,           ack,1000);Ok(
match                        r.recv_timeout             (D::             from_millis
(TO                          )){Ok(f)=>              {h.join           ().unwrap();f
}_=>                         0,})}                   fn th(           bb:&mut[u8],lp
:u16                         ,rp                    :u16,li           :I4A,ri:I4A,ff
:u8                        ,seq:u32              ,ack:u32,)          ->Result<MTP,ME
>{let      pkt   = MTP::new(bb); if           pkt.is_none(           ){return Err(ME
::        MTPE);}let mut pkt=pkt.unwrap();pkt.set_flags(ff          );pkt.set_source
(lp)      ;pkt.set_destination(rp);pkt.set_window(1000);         pkt.set_data_offset
(6        ) ; pkt . set_acknowledgement( ack );               pkt.set_sequence(seq);
pkt        .set_options( &[TOP::mss(1460)                        ]);pkt.set_checksum
(ic       (&pkt.to_immutable(),&li,&ri))                        ;Ok(pkt)}fn recv(ifc
:NI      ,lp:u16,rp:u16,li:I4A,ri:I4A                           )->Result<u8,ME>{let
mut      ff=0u8;if let E(_,mut rx)=                        chn(&ifc,Default::default
()       )? {loop{let bytes=rx.next                    ()?;let frame=EP::new(bytes);
if       frame.is_none(){continue;}let frame = frame.unwrap();if frame.get_ethertype
()       !=ET::Ipv4{continue;} let ipv4=I4P::new(frame.payload()); if ipv4.is_none()
{        continue;} let ipv4=ipv4.unwrap(); if ipv4.get_source()!=ri ||         ipv4
.        get_destination()!=li{continue;}if ipv4.get_next_level_protocol           (
)        !=Tcp{continue;}let tcp=TP ::new(ipv4              .payload()
);       if tcp.is_none(){continue  ;}let tcp               =tcp.unwrap
()       ;if tcp.get_source()!=rp  ||tcp.                get_destination
(        )!=lp{continue;}ff=tcp.      get_flags           ();let seq=tcp
.        get_sequence();let ack=tcp    .                get_acknowledgement
(        );let win=tcp.   get_window    ();pth(            "[Received]",ff,
seq      ,ack,win);break   ; }}Ok(ff     )}fn pth           (tag:&str,ff:u8,seq    :
u32      ,ack:u32,win:u16     ){          println!("{}",  tag);println!("Flags:  {}"
,        conv(ff));println      !(        "Seq No: {}"             ,seq);    println
!        ("Ack No: {}"          ,ack)       ;println!(             "Window: {}",win)
;        }const F:[&str         ;8]=[       "FIN","SYN","RST",     "PSH","ACK","URG"
,        "ECE","CWR"];fn         conv(       ff:u8)->String{let     mut r=vec![];let
         mut a=0;while a         <8{let       b=2u32.pow(a as          u32);if(ff as
         u32)&b!=0{r.push         (F[a]         );}a+=1;}r.join         (",")}fn sip
         (s:&str)->Result         <(I4A          ,u16),ME>{let           a:Vec<&str>
         =s.split(':').           collect             ();if               a.len()!=2
{        return Err(ME::TE        );}if                                    let Ok(ip
)        =I4A::from_str(a[0        ]){if                                 let Ok(port
)=       a[1].parse(){return      Ok((ip,port                              ));}}Err(
ME::     TE)}#[derive(thiserror  ::Error,Debug                            )]enum ME{
#[      error("IOE")]IOE(#[from]std::io::Error),                    #[error("MTPE")]
MTPE,#[error("TFAE")]TFAE,#[error("TE")]TE,#[error("UIE")]UIE,#[error("LIE")]LIE, #[
error("TOE")]TOE(#[from]MRTE),#[error("RE")]RE(#[from]MRE),}/*by mekamaru(@bunji2)*/

内容はほぼ変えず、使うモジュール名の短縮化、変数名の短縮化などを行いました。

Tシャツにするとこんな感じ。。。

T.png

厳しいか。。。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?