-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Udp Scanning #596
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Udp Scanning #596
Conversation
|
Hey @BrendanGlancy , what references did you use to construct the UDP packet? As you can probably predict I will need to read the docs to review this properly I am thinking actually take a look at it, merge it, but we don't follow Nmap's way. This will make UDP unreliable, but we'll have it. Then we can solict people to improve upon it by creating issues for specific problems we experience. I find it's better to merge incomplete features and improve upon them rather than wait an infinite amount of time to have the most perfect feature :) |
|
@bee-san Thanks for looking at this! If you're talking about If we go down the list of packets I currently have in there:
Theres pages for all of those, the one I actually found helpful for creating the packet, was https://datatracker.ietf.org/doc/html/rfc1592#section-3.1.1
Helpful in creating the packet
Found this on some medium article, cause the datatracker docs is an insane read for my smoothed over brain TLDR The packets are a problem, creating them is a pain is was a mix of handwriting and copilot Better news, looking more into nmap they are actually just sending empty packets to most ports on UDP scans, crafting specific payloads for specific well known ports. If you get a chance to look over this, and want me to change other things besides packet generation I will get on that first. |
Hey, so I could actually deploy an AWS EC2 instance and run some stuff on Docker for you to test? Since it's EC2 I believe scannigng is ok, since I (the EC2 owner) will say it's okay 🤷🏻
This is cool! We have no service probing functionality yet for TCP or UDP :)
Sure, let me take a quick look :) |
bee-san
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok heres some lil rust things :) hope that helps!
|
Thank you SO much!! Such a great PR :) It is crazy you consider yourself a junior developer. I would not even expect this type of code from senior developers 😂 |
typo Co-authored-by: Autumn (Bee) <github@skerritt.blog>
|
@bee-san This is like, in the direction of what you were suggesting. I'm just not good enough at Rust currently to make payload generation that great. I'm pushing to work on this on a different PC and to "merge incomplete features and improve upon them rather than wait an infinite amount of time to have the most perfect feature " because there's a lot of TODOs that keep popping up with everything I add. Thank you so much for all the help. It has made this super fun to work on, and I am learning a lot. I'd be interested in the EC2 thing unless it's going to cost you money. As always, I'm going to continue to work on this. If you have any more suggestions, I'll work on those. I appreciate the input :) |
Nonsense! This code looks fine to me :)
Will find time to do that :) I have not read your updates yet but I did some reading. I am thinking version 0.0.1 of this could just be the empty UDP packets like you talked about, and then we can add new packet types for specific things in the future. One per PR would be nice :) A common pattern I do is to break the problem down and then build out the absolute minimum viable solution for it (in this case, just empty packets). But I write the code anticipating the need that there will be more packets in the future. However I think here it'll be ok to mostly not do that.... I am not sure how we'd match ports up to specific packets, we'd need a hashmap of port:function() 🤔 I am thinking:
|
That is fine, that would just a matter of commenting out some code. When we UDP::bind then => Connect, std::net handles creating the UDP packet headers for us
Yes, I can start with the top 100.
I am not sure besides building what I mention below.
[https://nmap.org/book/nmap-payloads.html] I think having some kind of parser for something like this wouldn't be that difficult. The more difficult part is building out some kind of library to make it easier to hard code these payloads, for example theres a bunch of different versions of SNMP payloads they all share the same structure. I can begin to work on this. Also, I am probably reiterating stuff you already know, for the purpose of making it easier for me to keep track of TODOs on this feature. |
|
want me to review / merge? |
Bump clap from 4.5.4 to 4.5.6 (bee-san#600)
|
@bee-san yeah sure! |
PsypherPunk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of minor quibbles with typos. and a couple of questions but this is very, very nice.
src/scanner/mod.rs
Outdated
| async fn scan_socket(&self, socket: SocketAddr) -> io::Result<SocketAddr> { | ||
| let tries = self.tries.get(); | ||
| if self.udp { | ||
| let waits = vec![0, 51, 107, 313]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: can I check where these values have come from?
Are they particularly meaningful? And worth documenting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, they were 50, 100, 300.
bee-san suggested
Suggestion: Make the times less even? A firewall would pick up on even timing. Ideally we'd use random times
but it's slow and should be in a --quiet option (one for another PR)
Just doing things like 0, 51, 107, 313 etc would be good :)
Would've never thought of this myself
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@PsypherPunk Because of the way UDP works we don't know how long to wait to assume failure. Normally TCP would always get back to us, and if it doesn't we wait 1 second I think.
We need to tell UDP how long to wait for before moving on, I was thinking if we send multiple UDP packets at even timestamps the firewall would easily pick up on it. Uneven doesn't help so much but it's slightly better than nothing.
Something I realised is we have 0 here. Reading the code:
Does this imply we wait 0 seconds before assuming it's closed?
And thinking more about it do we need a vector of timeouts here at all?
The normal TCP scan waits 1.5 seconds:
https://github.com/RustScan/RustScan/blob/52bfcf048db5e10bcdd887abb350c85606331760/src/input.rs#L116
I think you should actually parse the timeout input down here and use that instead? That way in the future we can update this to a random timeout if we want to :)
Sorry, only just caught this 🙈
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes actually thinking about this more, there's other functions which use the timeout given at the argparsing level so I think we should not include this vector and just parse the timeout from the argparsing part (like the other tcp scanner does)
and I think a nice lil feature would be some code that can alter that timeout more in depth, like randomised timeouts
src/tui.rs
Outdated
| "I scanned ports so fast, even my computer was surprised.", | ||
| "RustScan: Where '404 Not Found' meets '200 OK'.", | ||
| "RustScan: Exploring the digital landscape, one IP at a time.", | ||
| "DeathStarMafia was here 🚀", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: is this suitable?
One for @bee-san: is this okay to add? Not sure there are other, named individuals/orgs. in this list…?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lol that's my CTF team (I did not name it), but I'll change this. But yes the 0day guy added himself to this but maybe he's an exception as he's tiktok famous
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't realise "0day" was a person; thought it was a reference to the thing. Shows what I know.
Kudos on the CTF team name though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@PsypherPunk
@BrendanGlancy yes, 0day is one of my friends. his dog passed away sadly and i wanted to commemorate him (Ollie), 0day put in a PR to add his own name so I thought it'd be ok 😅
@BrendanGlancy I will let you add your name here if you add 3 more networking related / hacking jokes 😉
|
@BrendanGlancy are you in my discord? http://discord.skerritt.blog got an ec2 instance you can scan for udp but dont want to publish the IP to the public haha |
FWIW, I've been spinning up a quick UDP socket via Python to test this (or at least making sure it picks up the right port): import socket
UDP_IP = "127.0.0.1"
UDP_PORT = 5005
sock = socket.socket(
socket.AF_INET,
socket.SOCK_DGRAM,
)
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024)
print(f"Received message: {data}") |
|
@bee-san Yes I just joined, but I already got in trouble with the mod. hopefully, I'll have a commit with the requested changes tonight @PsypherPunk Sorry about all the typos, I've never had a real software engineering job where someone reviews my code I didn't realize I was that sloppy Really appreciate all the feedback from the both of you :) |
Ahh it's okay! It's good code :) I really think that after you update it to use the timeout from the args we can get this merged, I see no other issues @PsypherPunk ? |
One outstanding typo. in |
|
Hopefully this is what you meant async fn scan_socket(&self, socket: SocketAddr) -> io::Result<SocketAddr> {
if self.udp {
let payload = cust_payload(socket.port());
let tries = self.tries.get();
for _ in 1..=tries {
match self.udp_scan(socket, &payload, self.timeout).await {
Ok(true) => return Ok(socket),
Ok(false) => continue,
Err(e) => return Err(e),
}
}
return Ok(socket);
} |
Amazing!! 1 small thing, you have this: This looks like a user defined argument, but:
And I think it'd be better named something like If I'm wrong let me know, it's early for me but this looks good! |
| /// Formats and prints the port status | ||
| fn fmt_ports(&self, socket: SocketAddr) { | ||
| if !self.greppable { | ||
| if self.accessible { | ||
| println!("Open {socket}"); | ||
| } else { | ||
| println!("Open {}", socket.to_string().purple()); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ticket to make in the future, we need to move all of this printing stuff into its own macro in the TUI file :)
|
Ok, CI is failing the lint check and I'm wrong, we have tries here: |
|
ok for me just CI needs to pass and we can merge :) CI runs cargo lint && cargo test && cargo clippy if all 3 pass locally then you are good! |
|
Wow! Crazy! UDP!!! 🥳 Merged!!!! |
|
You both have been awesome to work with. Thank you |
|
@BrendanGlancy feel free to make more PRs, this was fantastic 🥳 |



So I am new to Rust programming and a junior-level developer, at best, in any language.
#22 This is an attempt to add this feature to Rust Scan, but there are definitely some problems.
From what I have gathered, nmap does a couple of things for a UDP scan; they try different packet types as well as different wait times in waiting for a response from a UDP port. This makes things very slow, as I am sure you have noticed -sU scans take forever
What I am looking for in submitting this pull request is not for it to be merged, but for suggestions from people much smarter than me so I can improve the functionality of this.
Also for the automatic nmap scan that runs after every rustscan, I imagine it would be good to change it from
call_format = "nmap -vvv -p {{port}} {{ip}}"tocall_format = "sudo nmap -vvv -p {{port}} {{ip}} -sU"but I couldn't figure out how to do this based on the state of my sudp flag