Randomisation of Ports / IPs

One of the most requested features of RustScan is the ability to randomise the ports / IPs scanned.
Itās a lot easier for a firewall to detect ā1, 2, 3, 4, 5ā¦..ā then it is to detect ā63341, 510, 8371, 9481, 31843ā.
The first thought is to use a true random number generator, but true randomness isnāt needed for port scans.
This leads us to pseudo-randomness. Now, RustScan could have used a random library (pun intended), but we didnāt. Letās answer why.
If we needed to calculate randomised ranges of ports for every IP address, normally weād have to create an array of all 65535 ports and randomise them.
This isnāt an issue for a single IP, but imagine we are given a range of IP addresses. Letās say 20. Weād have to re-generate our array of ports and randomise them. Thatās:
65535 * 20 = 1310700
possible port randomisations. Even without every port being touched, weād still end up with 20 randomisations we donāt need.
Weāre using Linear Congruential Generator as our randomisation algorithm. Itās fast, the randomisation is so & so, but itās fast.

The algorithm as a pretty picture
Donāt worry, I wonāt explain the full algorithm here ;) But you can find it on Wikipedia here.
Because weāre using this, we can infer different orders for different IPs without storing anything besides the first pick for each IP. We donāt have to store all 65535 ports for every IP to get a random order!
To do this, we only need 1 variable. Youāll notice in the image above the algorithm has a seed. Our seed value is rather simple:
let normalized_end = end - start;
let normalized_first_pick = rng.gen_range(0, normalized_end);
Itās an incredibly cool application of a random number generator. It never occurred to me that we can roll our own RNG
Shout out to Bernardo Araujo for coming up with this algorithm, I thought Iād share it as itās a pretty cool application!
The Rise of VTubers
A couple months ago, I found myself fascinated watching Youtubers such as Omotea play Beat Saber.
Omotea is a VTuber (kind of). They do normal Youtuber things such as play video games with a cam, but their facial expressions & body movements are tracked and mapped onto, normally, an anime character.
In Omoteaās case, instead of seeing a person dancing we see an anime avatar dancing. VTubers are quite popular in the eastern world, but in the west not so much. However, they are rising meteorically to the top of the platform.
Hereās another example of an incredibly popular VTuber, Pekora.
Pekora is playing Minecraft with their ācamā in the bottom right. We can see Pekora make facial expressions or talk throughout this video, essentially living through their anime bodies, like something out of Ready Player One.

VTuberās often have typical anime backstories. Pekoraās is that she is a rabbit from a land called PekoLand, and this backstory is heavily played throughout her streams and her videos. Some other VTubers are more relaxed and donāt have these stories.
Many VTubers are sponsored by a company, which provides the software, the music, the art, and the games to them.
These companies often have multiple VTubers working for them, and they frequently collaborate together on videos.
Anime is incredibly popular all over the world. And VTubers take is to the next level. Imagine watching an anime character, and you ask them a question through a donation and they respond to you.
VTubers are likely the closet we can ever get to real anime characters, and their intimacy clearly brings in enough money to warrant multiple companies competing in the same market.
I quite like the idea of VTubers in some aspects. They donāt have to worry so much about public fame if they never reveal their true selves.
Theory Of Constraints
Recently I had the pleasure of gaining first hand experience from the Theory of Constraints.
The theory states that:
Identify the most important & limiting factor of a project (the bottleneck) and improve upon it until it is no longer a factor.
Find bottlenecks in your project, work on them. The idea is to not work on anything that isnāt a significant bottleneck in the project.
That last sentence is very important. While working on RustScan we noticed that the actual bottleneck was different from the perceived bottleneck.
Itās easy for us to look at a large module and say:
This is the largest bottleneck in the system
But more times than not, this isnāt the case. Our basis for making this presumption is based on our own experience and what we feel rather than what we know.
This led me on a quest to find out what really were the bottlenecks of RustScan.
To do this, I used a profiling tool.
Profiling tools watch your program run, and can tell you which functions take the longest time, which use the most CPU and more. It tells you where the bottlenecks are. No more guessing!
1 ā + 63.89% 0.00% rustscan [unknown] [.] 0xffffffffffffffff
ā ā
2 ā + 63.73% 0.00% rustscan rustscan [.] rustscan::main
ā ā
3 ā + 63.73% 0.00% rustscan rustscan [.] futures_executor::
ā local_pool::block_on ā
4 ā + 63.73% 0.00% rustscan rustscan [.] std::thread::local
ā ::LocalKey<T>::with ā
5 ā + 63.73% 0.04% rustscan rustscan [.] <core::future::fro
ā m_generator::GenFuture<T> as core::future::future::Future>::poll ā
6 ā + 63.67% 0.00% rustscan rustscan [.] <core::future::fro
ā m_generator::GenFuture<T> as core::future::future::Future>::poll ā
Here is the log from RustScanās profile. 63% is spent in main (no biggie, itās main after all). But other than that, we have 2 big factors in play:
block_on (async)
LocalKey<t>::with (threading
The most costly parts of RustScan is the asynchronous scanning itself.
Instead of improving some minor functions, we now know that to make RustScan faster we need to improve upon the async scanning.
If we cannot, well ā perf also gives us some other hints as to what to improve:
10 ā + 20.87% 0.03% rustscan rustscan [.] socket2::socket::S
ā ocket::connect ā
11 ā + 20.72% 0.02% rustscan libpthread-2.31.so [.] __libc_connect
Mainly the socket connections, which we are improving now.
TL;DR The theory of constraints is good, but you donāt always know what the bottlenecks are by merely looking at your code. Use tools & statistics to find these for you.
Building Nice Terminal User Interfaces
Recently I had the pleasure of redesigning the terminal user interface module for RustScan. In short, a terminal user interface is the UX / design of the terminal application.
Itās easy to look at CLI only work and assume no design goes into it, but thatās simply not true.
With web design we have all sorts of tools to make information obvious. Different shapes, buttons, images and more.
But we donāt have that in the terminal. So, hereās some thoughts on designing nice terminal applications.
RustScan

Firstly, RustScanās TUI isnāt very accessible. This is because of the ASCII banner. No worries though, thereās an option disable that (PS. if you also have an ASCII banner, please think about A11Y).
The banner displays the name of the program (in a lovely gradient), along with the slogan (Faster Nmap scanning with Rust) and then a table).
The table contains 2 links, the GitHub & the Discord.
When the user starts the program, they should understand straight away what it is.
The name (RustScan).
What it does (Faster Nmap scanning with Rust) and then a table).
The next 2 links are important. They are placed in a gradient table which contrasts the logo and the rest of the program to make them stand out. The Discord link (for support), and the GitHub page (also for support, or for finding out more about the project).
Youāll notice the quote:
āNmap? More like slowmap š¢ā
This is because hackers love cheesy quotes.
Okay, now onto the juicy stuff. The use of icons to denote information. We have 3 icons in RustScan:
[!] - warning. Warns the user about something (and is coloured red for danger).
[~] - information. Informs the user about something (blue).
[>] - output. Outputs information to the user (green).
By colour coding the outputs, the user will be easily able to distinguish between what they likely want to ignore (information), and warnings.
If it was down to me, Iād delete the information ā but itās needed for features the user may want to use.
Ciphey

Ciphey takes the opposite approach of RustScan. Minimalism. Ciphey aims to only give the information which the user will want. No extra info like āmaybe youāll want to do thisā. Only the output.
Cipheyās output is:
A list of encryption methods the cipher used. In order, new line delimited, with extra information if needed (such as cipher keys).
The output of decryption.
Note: The only colour in Cipheyās output is the exact output text. Whereas RustScan has multiple outputs by nature, Ciphey only has 1 ā the textual output.
This is partly inspired by Googleās search engine. In Google, you enter information and you get the result you wanted back. You donāt see what happens in the background to get you that information.
The same is true for Ciphey. The only information the user needs is the output and what it was encrypted with.
Lessons
Make your output extremely obvious
If you have to output a lot of information, change the physical colour of the information to make more important information stand out.
The most important information should be printed last. This is because if you output a lot of information, you donāt want the user to scroll up to see the answer.
Itās easy to overload the user with information. Only give the user information that they want.
Zero Cost Abstractions
Rust has this really cool thing called Zero Cost Abstractions. Itās also a thing in other low level languages, but being a Python Surfer Dude I havenāt come across it before.
Zero cost abstraction is:
What you donāt use, you donāt pay for. And what you do use, you couldnāt do any better if you coded by hand.
Letās talk about the 2 parts of this sentence.
What you donāt use, you donāt pay for.
The language shouldnāt have a global cost for a feature that isnāt used. Letās say to use a for loop, the language needs to have some massive 1gb file that slows down everything else. If we never use a for loop, we still pay for the for loop!
And what you do use, you couldnāt do any better if you coded by hand.
Hereās the kicker.
Say you wrote some code, a function that calculated Fibonacci numbers. And you compiled this code down into assembly.
Now letās say you hand-write assembly to do the same function ā calculate Fibonacci numbers but this time in assembly.
Handwriting it in assembly would mean we would either gain no performance, or we would lose performance.
By using zero cost abstractions, we write abstracted code (not handwritten assembly) and we couldnāt do any better if we tried to hand-write assembly. Now thatās cool!
Cool mental models I like
Okay so I was looking for mental models, and I didnāt know their name so I just googled for hours and I finally came across them. Let me share with you some cool ones!
Note: I just copied these from either here or here.
The Broken Windows Theory
The Broken Windows Theory on Wikipedia
The Broken Windows Theory suggests that visible signs of crime (or lack of care of an environment) lead to further and more serious crimes (or further deterioration of the environment).
Brookās Law
Adding human resources to a late software development project makes it later.
Metcalfeās Law
In network theory, the value of a system grows as approximately the square of the number of users of the system.
Occamās Razor
Entities should not be multiplied without necessity.
The simplest choice is often the best choice.
Personal News
I was initiated to become a mod of TryHackMe, a bustling hacker community with 150,000+ players (and growing every day)
Ciphey hit 2k stars <3 :)
I WAS IN DEFCON???

I published a new blog post on packing your rust packages
Thatās all for this week! Cya :D
P.S. Have a great week!!!! :) <3