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

Frag Attacks - A critical Wifi vulnerability

Wifi fragmentation and aggregation attacks (FragAttacks) are a new collection of vulnerabilities in which a threat actor can exfiltrate data or attack victims within radio range. Mathy Vanhoef, a postdoctoral researcher at New York University Abu Dhabi, recently published his paper, Fragment and Forge: Breaking Wi-Fi through Frame Aggregation and Fragmentation , detailing several attack vectors and examining the intricacies of the aggregation vulnerabilities that have been part of the 802.11 standards since the inception in 1997.  Quite interestingly, every device tested was susceptible to one or more of the FragAttacks. While several 802.11 standards make these attacks harder to perform, they can be executed on all devices across all standards. It's a good thing then, that there was a nine-month embargo on information related to these attacks, allowing manufacturers to provide security updates to affected devices. Mathy Vanhoef has also created a website documenting the FragAttack

Malware analysis series by John Hammond

John Hammond, a YouTuber and Cybersecurity researcher, has a series on Youtube where he analyses malware artifacts and discerns their purpose and method of attack. For most of these, he gets access to known malware files, and then blindly goes through them, de-obfuscating and cleaning them up, in order to present a readable version that can be analyzed. I personally find these videos very exciting and entertaining, as well as incredibly educating. He also has several other series and interesting videos on his channel that I highly recommend for anyone interested in software security and other general security topics.  Link:  https://www.youtube.com/watch?v=MJBKxs8UnFE