Skip to content

epixoip/kotlin-akka-portscan

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kotlin-akka-portscan

A toy program to help me (and you!) learn Kotlin + Akka.

butwhy.gif

When I want to learn a new language, I've found it helpful to attempt to write a silly toy program while I study the documentation and other people's code. More often than not, what I end up writing is a port scanner.

Why a port scanner? Well, I'm certainly not trying to compete with Nmap. It's something I started doing over 20 years ago: I wanted to learn Visual Basic, and I stumbled across a port scanner someone wrote in VB4, which was right up my alley. So I started hacking on it until there was virtually none of the original code remaining. I then ported it to VB5, VB6, Python, and Perl. After learning C, I wanted to learn socket programming, and I could think of no better project than a port scanner that can do SYN scans with raw sockets. I then ported that program to C++ and C#. As a port scanner touches on a majority of the concepts one must learn to write in a language, I've found it to be kind of the perfect toy program and thus have kept the tradition going with virtually every language I've learned since.

So here's a toy port scanner I wrote to help me learn Kotlin + Akka, which you can also hack on to help learn these two amazing technologies as well!

About the program

Kotlin is a super terse and concise language that combines object-orient and functional programming. Writing in Kotlin is extremely fun, and is sort of like a blend of Java, Scala, and Groovy. Kotlin can be compiled to run on everything from bare metal (Kotlin/Native) to the JVM (Kotlin/JVM), mobile devices, the web browser as JavaScript (Kotlin/JS), and can even share code between multiple platforms (Kotlin Multiplatform). This makes Kotlin an extremely attractive language for full stack development, as your back-end, front-end, mobile apps, and desktop apps can all share a common code base. The majority of Kotlin adopters are currently targeting Android, but I've primarily been using Kotlin for server-side and desktop applications over the past year.

Akka is a Scala library that implements reactive programming via the actor model, and is heavily inspired by Erlang. Instead of calling functions and spawning threads, we create independent actors that react to messages, much like an actor on a stage waits for and reacts to their cues. Akka does not explicitly have support for Kotlin, but as Akka runs on the JVM, we can utilize Akka with Kotlin/JVM. Akka also makes it trivial to cluster nodes to build a reactive system where actors can run on any number of nodes, although this particular program does not implement clustering.

The main function in Main.kt creates our actor system with ActorSystem.create, then spawns an actor for the Reporter class. It then loops through each of the hosts and ports, spawning up to 1024 simultaneous actors from the Scanner, class and sending each a Scan message containing the host and port that actor is to scan. These actors will execute in parallel, so the 1024 limit is used to throttle (via CountDownLatch) the number of open connections.

When each Scanner actor receives a Scan message, they send a message to Akka's TCP Manager actor to connect to their designated hosts and ports. If the connection is successful, the TCP Manager actor will send a Tcp.Connected message to the Scanner actor. The Scanner actor then sends a Report message to the Reporter actor, identifying the port as being OPEN. The Scanner actor will then send a series of payloads to the TCP Manager actor to send to the open port, and if any data is returned, the TCP Manager actor will send a Tcp.Received message to the Scanner actor, and the Scanner actor will then send a Report message to the Reporter actor, informing it of the returned data. If the connection attempt is unsuccessful, the TCP Manager actor will send a Tcp.CommandFailed message to the Scanner actor, which we can then parse to determine if the port is closed (packet rejected) or filtered (packet dropped). The Scanner actor will then inform the Reporter actor of the port's status via a Report message. Once a connection has been closed, the actor will kill itself, allowing us to spawn more actors until all ports have been scanned. In other words, the Scanner actors are basically Meeseeks, dying immediately after accomplishing their one task.

Once all the ports have been scanned, we send a GetReport message to the Reporter actor to collect the status and banners from all the ports we just scanned, and then print the results in an attractive tree format. If you're on Windows, you unfortunately will not see the pretty colors :(

Compiling

mvn clean:clean kotlin:compile resources:resources assembly:single jar:jar exec:java

Executing

java -jar target/kotlin-akka-portscan-0.1.jar

Hacking

There's a lot you can do with this program! Make it accept command line arguments for hosts & ports, including CIDR notation and IP ranges, as well as port ranges. Implement Akka Cluster and make this a distributed scanner. Add UDP support. Rewrite everything until none of my code is left!

About

A toy port scanner to help me (and you!) learn Kotlin + Akka.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages