responde a un register con unauthorized

pull/1/head
serxoz 2022-12-07 13:52:00 +01:00
parent 90156e3837
commit 2d22f734f5
6 changed files with 229 additions and 10 deletions

View File

@ -1,3 +1,6 @@
################################################################################
Descubrimento na rede
################################################################################
OPTIONS sip:100@127.0.0.1 SIP/2.0
Via: SIP/2.0/UDP 127.0.1.1:5061;branch=z9hG4bK-487618168;rport
Max-Forwards: 70
@ -10,6 +13,7 @@ CSeq: 1 OPTIONS
Accept: application/sdp
Content-Length: 0
SIP/2.0 404 Not Found
Via: SIP/2.0/UDP 127.0.1.1:5060;rport=65476;received=185.179.142.180;branch=z9hG4bK-3692480612
Call-ID: 953932568039675157936807
@ -24,3 +28,60 @@ Accept-Encoding: identity
Accept-Language: en
Server: Asterisk PBX 18.9.0
Content-Length: 0
################################################################################
Descubrimento extensiós
- manta register
- si devolve "unauthorized" é que existe
- si devolve "forbiden" é que non existe
################################################################################
REGISTER sip:xinu.me SIP/2.0
Via: SIP/2.0/UDP 127.0.1.1:5060;branch=z9hG4bK-569407384;rport
Max-Forwards: 70
To: "6666666666"<sip:6666666666@xinu.me>
From: "6666666666"<sip:6666666666@xinu.me>;tag=36363636363636363636013930343637323738
User-Agent: friendly-scanner
Call-ID: 1283048503
Contact: sip:6666666666@xinu.me
CSeq: 1 REGISTER
Accept: application/sdp
Content-Length: 0
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 127.0.1.1:5060;rport=65476;received=185.179.142.180;branch=z9hG4bK-569407384
Call-ID: 1283048503
From: "6666666666" <sip:6666666666@xinu.me>;tag=36363636363636363636013930343637323738
To: "6666666666" <sip:6666666666@xinu.me>;tag=z9hG4bK-569407384
CSeq: 1 REGISTER
WWW-Authenticate: Digest realm="asterisk",nonce="1670408728/f2288b61ff3e1c5a8fbad2282734a53b",opaque="37899594559ff83d",algorithm=md5,qop="auth"
Server: Asterisk PBX 18.9.0
Content-Length: 0
###
2022/12/07 11:25:28.115453 185.179.142.180:65476 -> 185.179.143.92:5063
REGISTER sip:xinu.me SIP/2.0
Via: SIP/2.0/UDP 127.0.1.1:5060;branch=z9hG4bK-457882779;rport
Max-Forwards: 70
To: "6666666667"<sip:6666666667@xinu.me>
From: "6666666667"<sip:6666666667@xinu.me>;tag=363636363636363636370133303731363137323935
User-Agent: friendly-scanner
Call-ID: 2112593047
Contact: sip:6666666667@xinu.me
CSeq: 1 REGISTER
Accept: application/sdp
Content-Length: 0
2022/12/07 11:25:28.116036 185.179.143.92:5063 -> 185.179.142.180:65476
SIP/2.0 403 Forbidden
Via: SIP/2.0/UDP 127.0.1.1:5060;rport=65476;received=185.179.142.180;branch=z9hG4bK-457882779
Call-ID: 2112593047
From: "6666666667" <sip:6666666667@xinu.me>;tag=363636363636363636370133303731363137323935
To: "6666666667" <sip:6666666667@xinu.me>;tag=z9hG4bK-457882779
CSeq: 1 REGISTER
Server: Asterisk PBX 18.9.0
Content-Length: 0

View File

@ -7,6 +7,8 @@ pub mod sip;
use crate::sip::not_found::*;
use crate::sip::options::*;
use crate::sip::register::*;
use crate::sip::unauthorized::*;
use std::error::Error;
use std::net::SocketAddr;
use std::{env, io};
@ -67,7 +69,31 @@ impl Server {
&not_found.serialize().len(),
peer
);
}
},
msg if msg.contains("REGISTER") => {
// esperar - tarpit!
sleep(Duration::from_secs(1)).await;
let register = Register::parse(&msg);
let unauthorized = Unauthorized {
command: "SIP/2.0 401 Unauthorized".to_string(),
via: register.via,
call_id: register.call_id,
from: register.from,
to: format!("{};tag={}", register.to, register.branch),
cseq: register.cseq,
www_authenticate: Some("Digest realm=\"asterisk\",nonce=\"1670408728/f2288b61ff3e1c5a8fbad2282734a53b\",opaque=\"37899594559ff83d\",algorithm=md5,qop=\"auth\"".to_string()),
server: Some("Asterisk PBX 18.9.0".to_string()),
content_length: Some(0)
};
let amt = socket.send_to(&unauthorized.serialize(), &peer).await?;
println!(
"Sent {}/{} bytes to {}",
amt,
&unauthorized.serialize().len(),
peer
);
},
_ => println!("Packet don't known, yet..."),
}
}

View File

@ -1,2 +1,4 @@
pub mod not_found;
pub mod options;
pub mod register;
pub mod unauthorized;

View File

@ -36,15 +36,16 @@ impl Options {
let mut packet = Options::new();
for line in msg.lines() {
if line.len() > 0 {
// split polos dous puntos e comprobar
// si a parte 0 conten via asignar a via e así
let parts = line.split(":").collect::<Vec<&str>>();
let header = parts[0].trim();
let mut content = "".to_owned();
for p in &parts[1..] {
content.push_str(p.trim())
}
match header {
// ata os primeiros ":" é a cabeceira e logo o contido
let header = line.chars()
.take_while(|&ch| ch != ':')
.collect::<String>();
let mut content = line.chars()
.skip(header.len()+1)
.collect::<String>();
content = content.trim().to_string();
match &header[..] {
"OPTIONS sip" => packet.command = format!("{}{}", header, content),
"Via" => packet.via = content.to_string(),
"Max-Forwards" => packet.max_forwards = content.parse::<i32>().unwrap(),

78
src/sip/register.rs Normal file
View File

@ -0,0 +1,78 @@
// Mandatory: To, From, CSeq, Call-ID, Max-Forwards, and Via;
//
#[derive(Debug)]
pub struct Register {
pub command: String, // OPTIONS sip:100@127.0.0.1 SIP/2.0
pub via: String, // SIP/2.0/UDP 127.0.1.1:5061;branch=z9hG4bK-487618168;rport
pub branch: String, // Para montar o "to", sale do branch de "Via"
pub max_forwards: i32, // 70
pub to: String, // "sipvicious"<sip:100@1.1.1.1>
pub from: String, // "sipvicious"<sip:100@1.1.1.1>;tag=37663030303030313133633401393537303038303638
pub user_agent: Option<String>, // friendly-scanner
pub call_id: Option<String>, // Call-ID: 447615548427934163033914
pub contact: Option<String>, // sip:100@127.0.1.1:5061
pub cseq: String, // 1 OPTIONS
pub accept: Option<String>, // application/sdp
pub content_length: Option<i32>, // 0
}
impl Register {
pub fn new() -> Register {
Register {
command: "REGISTER".to_string(),
via: String::new(),
branch: String::new(),
max_forwards: 0,
to: String::new(),
from: String::new(),
user_agent: Some(String::new()),
call_id: Some(String::new()),
contact: Some(String::new()),
cseq: String::new(),
accept: Some(String::new()),
content_length: Some(0),
}
}
pub fn parse(msg: &String) -> Register {
let mut packet = Register::new();
for line in msg.lines() {
if line.len() > 0 {
// ata os primeiros ":" é a cabeceira e logo o contido
let header = line.chars()
.take_while(|&ch| ch != ':')
.collect::<String>();
let mut content = line.chars()
.skip(header.len()+1)
.collect::<String>();
content = content.trim().to_string();
match &header[..] {
"REGISTER sip" => packet.command = format!("{}{}", header, content),
"Via" => {
packet.via = content.to_string();
// SIP/2.0/UDP 127.0.1.1:5061;branch=z9hG4bK-487618168;rport
let via_parts = content.split(";").collect::<Vec<&str>>();
let branch_full = via_parts[1].trim();
let branch = branch_full.split("=").collect::<Vec<&str>>();
packet.branch = branch[1].to_string();
}
"Max-Forwards" => packet.max_forwards = content.parse::<i32>().unwrap(),
"To" => packet.to = content.to_string(),
"From" => packet.from = content.to_string(),
"User-Agent" => packet.user_agent = Some(content.to_string()),
"Call-ID" => packet.call_id = Some(content.to_string()),
"Contact" => packet.contact = Some(content.to_string()),
"CSeq" => packet.cseq = content.to_string(),
"Accept" => packet.accept = Some(content.to_string()),
"Content-Length" => {
packet.content_length = Some(content.parse::<i32>().unwrap())
}
_ => println!("---> {:?} no contemplada!", header),
}
}
}
// println!("{:?}",packet);
packet
}
}

51
src/sip/unauthorized.rs Normal file
View File

@ -0,0 +1,51 @@
/*
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 127.0.1.1:5060;rport=65476;received=185.179.142.180;branch=z9hG4bK-569407384
Call-ID: 1283048503
From: "6666666666" <sip:6666666666@xinu.me>;tag=36363636363636363636013930343637323738
To: "6666666666" <sip:6666666666@xinu.me>;tag=z9hG4bK-569407384
CSeq: 1 REGISTER
WWW-Authenticate: Digest realm="asterisk",nonce="1670408728/f2288b61ff3e1c5a8fbad2282734a53b",opaque="37899594559ff83d",algorithm=md5,qop="auth"
Server: Asterisk PBX 18.9.0
Content-Length: 0
*/
#[derive(Debug)]
pub struct Unauthorized {
pub command: String, // SIP/2.0 401 Unauthorized
pub via: String, // SIP/2.0/UDP 127.0.1.1:5061;branch=z9hG4bK-487618168;rport
pub call_id: Option<String>, // Call-ID: 447615548427934163033914
pub from: String, // "sipvicious"<sip:100@1.1.1.1>;tag=37663030303030313133633401393537303038303638
pub to: String, // "sipvicious"<sip:100@1.1.1.1>
pub cseq: String, // 1 OPTIONS
pub www_authenticate: Option<String>, // WWW-Authenticate: Digest realm="asterisk",nonce="1670408728/f2288b61ff3e1c5a8fbad2282734a53b",opaque="37899594559ff83d",algorithm=md5,qop="auth"
pub server: Option<String>, // Asterisk PBX 18.9.0
pub content_length: Option<i32>, // 0
}
impl Unauthorized {
pub fn serialize(&self) -> Vec<u8> {
let mut preout = format!(
"{}
Via: {}
Call-ID: {}
From: {}
To: {}
CSeq: {}
WWW-Authenticate: {}
Server: {}
Content-Length: {}",
&self.command,
&self.via,
&self.call_id.as_ref().unwrap(),
&self.from,
&self.to,
&self.cseq,
&self.www_authenticate.as_ref().unwrap(),
&self.server.as_ref().unwrap(),
&self.content_length.unwrap().to_string(),
);
preout.push_str("\n\n\n");
// println!("{}", preout);
preout.as_bytes().to_vec()
}
}