Skip to main content

Port Scanner in C (and some updates)

 It's been a while since I last updated this blog. School and CCDC have really been eating at my time. Contrary to the earlier style of the blog, I plan on keeping things more informal and casual. I'm transitioning this into more of an archival type of thing. A place to keep track of my notes and projects, as well as a place to document my thoughts at the time. Posts will be infrequent and likely quite random. For this post, I'm going to write about a little port scanner I wrote for an entry-level C course. As a little background, the only experience I have with C comes from C++ in a high school course some 7 years ago. So I was fairly excited to start this class and dig in a bit deeper. 


The Project

For our final project, we needed to create a program and present on it. I wanted to combine what I was doing in my networking class and my C class, so I went with something I thought would be simple enough. A port scanner. 

Turns out, writing a port scanner when the most advanced concept you've been taught is arrays, is kind of difficult. If I was smart, I'd have waited until beyond the 3rd week to start my project, but, well, I'm not that smart. Later on, we'd learn about linked lists, stacks, how to handle memory, stuff that would be very useful when working on something like this. But, I wanted to get an early start on my project, so I went full steam ahead and started drafting out what I thought it should look like. 

First, I set up some basic goals. I wanted to be able to scan an entire subnet, scan specific addresses, and generate reports with recommendations on what steps to take to secure a port. For the most part, I hit those goals. It was definitely challenging at first. I had never worked with sockets before, and I only had a very basic understanding of networking. I think I had 10 or so different versions of the code at one point. Things like portscanner[connects!] and portscanner[broken]. I still have a folder that's full of portscanner_vx, with different versions of various functionality. 

Eventually, with a great amount of help from StackOverflow, I was able to get a functional prototype that could tell me if port 80 was open on any address in my internal network. This was great, I was able to specify an address and port, and it would report back if it could make a connection. Honestly, I'm still not certain my method of doing this is correct, or the best way, but I was still able to fulfill one of my basic goals. I had a (semi) functional port scanner. 

Enter a few days of massive backtracking and redesigning. While I had been able to make a connection to a hard-coded address/port, I wasn't able to get my loops or other functions to work. I realized that the way I had set up the socket creation functions wasn't ideal. Once a socket was created and connected, it never closed. On top of that, I was also trying to use the same socket for different things. Without ever re-connecting it or resetting it. So when I tried to cycle to the next address, it would stall or abort, or throw out some weird errors I didn't understand. Eventually, I realized I wasn't handling my sockets correctly, and I rewrote the function that handled sockets into 2 different functions. One to handle creation, and one to handle connection. I also made sure to go through and close every socket after it was done being used. 

Queue the second major issue. This one still remains unresolved, unfortunately. My code is slow. Extremely slow. I couldn't figure out why it wasn't working after throwing in the loops that handle addressing when scanning an entire subnet, so I fired up Wireshark to see if it was making connections, or if I had more socket function issues. What I found, was that there was no timeout on connection attempts, outside of the default TCP timeout/retry which is specific for each platform. On my mac, this meant that I was facing about a minute and 15 seconds(1:15) between each scan. If I was to scan a whole subnet, this would take quite some time. Looking into it a bit, I found that most of the solutions to this were either too high level for me to understand at the time or platform-specific quick fixes. I did try some things out, but nothing ever seemed to work. Eventually, given the deadline of the project, I had to give up my attempts to solve this problem, and just accept that scans involving multiple addresses were just going to be incredibly slow. 

After accepting my fate, I started to implement the other features I wanted to include. Report generation and multiple port scanning. At this point, my code was only able to scan multiple addresses for the same port. Thankfully, adding the ability to scan multiple ports wasn't too difficult. Mainly, because I had decided early on that I only wanted to scan for the most commonly attacked ports. I didn't want to try and scan every single port out there. So I threw in a function that created a socket array and attempted connections on them. All hardcoded, so there weren't any issues with that. 

I mainly chose to go with only 14 ports, because I didn't want to spend so much time writing out descriptions to throw into the report that was generated. By focusing on only 14 ports, I thought it would be much more manageable. It's kind of funny looking back because I saved the contents of the report until the end. I waited until just before the project was due to go back and fill those out. I actually ended up copping out and just throwing together a simple message along the lines of "This is what this port does, go to this link for more info". In a sense, it still fulfilled my goal of report generation. 

Overall, the project actually went fairly well. If I had started it further into the class, I definitely could have avoided some of the early confusion and rewrites, and I probably would've been able to add some more functionality to the code as well. Either way, I'm still mostly happy with how it turned out, and I've been thinking of ways to improve it. Although, given my track record of going back to old projects, I don't know if I'll ever get to rewriting and improving it. 

The code and related documentation/presentation can be found on my github. And here is a direct link to the project itself. Be warned, it is very messy code, and certainly not as clean as some of my other projects.


Closing notes,

I'm planning to do another post at some point about my CCDC experiences so far, but I'm not quite sure when I'll have the time to write about that. Hopefully, I'll get some time to write about it over the winter break, but I'll also be trying to get some travel in during that time as well, so it might be a bit tricky to work everything out. Maybe I'll make a post about some of the places I go while I'm out and about in the big wide world. That could always be fun. Hopefully, Omicron doesn't end up being as bad as Delta, and travel stays open during the holidays. With that, I'm signing off for now.


Liam Powell [Bajiri]


Comments

Popular posts from this blog

Using PGPy to encrypt and decrypt files and messages

 PGPy is a library for python that enables the creation, storage, and encryption/decryption of PGP keys and files in python. Recently, in a small project to reacquaint myself with python, I used PGPy for key generation and encryption and decryption. That project can be found in my github at  https://github.com/lpowell . The goal of the project was to use command-line switches to control the program, and to provide basic encryption and decryption capabilities, along with rot13 and base64 encoding.  First, to load in a key use key, _ = pgpy.PGPKey.from_file(keyfilename) . This loads the key from either a binary or ASCII armored file. You can swap out .from_file for .from_blob , if you plan on using a key stored in a string or bytes object rather than a file. In my example code, I pull the key from a file, as I found it to be the simpler method.  Next, you'll need to open a file or create a string or bytes object that contains the message you wish to encrypt. We'll call this file

Using the Ubertooth One to sniff and intercept Bluetooth packets

While researching for my individual video project I came across this tool which allows for the sniffing and interception of bluetooth packets. This article covers some of the basic functionality of an Ubertooth One.  It's really quite interesting to see all the possibilities with devices like these. The tech behind them is very interesting as well. Hopefully, I'll be able to integrate some of this technology into my project video and include a demo of some of the interesting things it can do.

Installing the Ubertooth on the Mac mini M1

 For my video project, one of the demonstrations included using an Ubertooth One to scan for Bluetooth and BLE packets. This blog post will cover the installation of the Ubertooth One on the Mac mini M1. The official install guide for Mac devices didn't work very well for me, and I had to install some extra tools in order to get it to work. The examples assume you are using Python 3, and have homebrew installed.  To begin, follow the instructions found here:  https://github.com/greatscottgadgets/ubertooth/wiki/Build-Guide . Additionally, you may find that you need to install pytq5, numpy, and qtpy. To do this, simply run Python3 pip install pyqt5, numpy, qtpy. This will install the required libraries needed to run the Ubertooth tools. There are multiple ways to install pip on an OS X device, but I suggest using homebrew to install python3, which should install pip as well. Next, you will need to update the firmware of the device. When downloading the tools, a firmware directory sh