Building a TCP-Connect Port Scanner using C

The first step in any hacking methodology is reconnaissance. In this step, the hacker enumerates information related to their target. This includes IP addresses, DNS information (through Whois lookup), open ports and services, OS type and version, and really anything else that helps the hacker choose an appropriate exploit.



In this post, I'll focus on fundamentals required to build a simple program in C which scans a target and reports the open ports on it.

Disclaimer: Scanning remote networks without permission is a crime. Be very careful with the knowledge that you learn from this post. I'll not be held responsible for any malicious activities that you may be involved in.

What exactly are we trying to build?

Nmap is the de-facto tool for scanning networks for open ports and services. Here's an example of nmap scanning the top 100 ports using TCP Connect:

nikhilh@ubuntu:~/projects/hades_scanner/src$ nmap -sT -F scanme.nmap.org

Starting Nmap 7.01 ( https://nmap.org ) at 2018-07-14 12:02 PDT
Nmap scan report for scanme.nmap.org (45.33.32.156)
Host is up (0.26s latency).
Other addresses for scanme.nmap.org (not scanned): 2600:3c01::f03c:91ff:fe18:bb2f
Not shown: 99 filtered ports
PORT   STATE SERVICE
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 21.04 seconds

The program that we're coding tries to determine port states like nmap did above.


What is TCP Connect?

TCP Connect is one of the techniques used to identify a port state. When two systems connect to each other using TCP they go through what is called a three-way handshake process.

Say, we have two systems Sys-A and Sys-B and Sys-A is trying to connect to Sys-B using TCP. The following are the steps involved in a three-way handshake process:
  1. Sys-A sends a SYN packet to Sys-B.
  2. On receipt of the SYN packet, Sys-B sends a SYN+ACK packet to Sys-A.
  3. On receipt of the SYN+ACK packet, Sys-A sends an ACK packet to Sys-B.

This is the connection methodology used by the TCP Connect technique. If our program is able to successfully connect to a port on the target, that port is deemed open, else it is closed. (There is also a technique called TCP Stealth which does not execute step 3 of the three-way handshake process but that is for another post.)

Let the coding begin!


Parsing command line options

Our program will use two required options - host and scan_type - and one flag - verbose (for debugging). We'll be using GNU long options through getopt.h to parse the passed options.

#include <getopt.h>
struct option cmdline_options[] = {
        {"host", required_argument, 0, 'h'},
        {"scan_type", required_argument, 0, 's'},
        {"verbose", no_argument, &VERBOSE,1},
        {0, 0, 0, 0}

};
opt = getopt_long(argc, argv, "h:s:", cmdline_options, &long_index);

opt contains the ASCII value of the option it is parsing. optarg variable contains the value of the parsed option. A switch-case block can be used to execute code based on the value of opt. For more information on getopt_long, refer to https://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Options.html#Getopt-Long-Options


Resolving the hostname into an IP address (if required)

The host can be specified as a hostname or an IP address. If we have a hostname on our hands, we would need to resolve it to a network address in network byte order (most significant byte first) to make it compatible with socket creation/connection.

For hostname resolution we'll use gethostbyname() defined in netdb.h

#include <netdb.h>
struct hostent *he;
struct in_addr **addr_list;
he = gethostbyname(*HOST);
addr_list = (struct in_addr **) he->h_addr_list;

addr_list is of type char **. To store the IP address in *HOST as a string, we'll use inet_ntoa()which is defined in arpa/inet.h

strcpy(*HOST, inet_ntoa(*addr_list[index]))

Creating the structure for storing target information

We'll be storing the target information in a sockaddr_in structure. AF_INET determines the domain of the socket and is being used since we're communicating over an internet socket.

struct sockaddr_in server_address;
server_address.sin_family = AF_INET;

Since the sin_addr member of sockaddr_in structure is of type of struct in_addr, we'll use a cast to get the IP address from HOST in the correct manner. We'll use inet_aton() which is defined in arpa/inet.h as well.

inet_aton(*HOST, (struct in_addr*) &server_address.sin_addr.s_addr);

Creating a socket

Socket creation is very simple and uses socket() from sys/socket.h
The first argument to socket() is the domain of the socket. In this case, since we're using an internet socket, we'll use AF_INET. The second argument is SOCK_STREAM which is the type of socket being created and is being used since we're creating a TCP type socket.

int net_socket = socket(AF_INET, SOCK_STREAM, 0);

socket() returns -1 if socket creation is unsuccessful.

Creating a connection using the socket

Since we're scanning all the ports of the target, we'll use a for loop as a port number counter. Each time we create a connection, we'll set the port number in the server_address structure. htons() ensures that the port numbers are stored in memory in network byte order. If you're working on a big-endian machine, there would be no need for using htons(). Many devices, however, store numbers in little endian format (LSB first).

server_address.sin_port = htons(port);

We'll then use connect() from sys/socket.h to create a connection to the target.

int conn_status = connect(net_socket, (struct sockaddr *)&server_address, sizeof server_address);

connect() returns -1 if the connection wasn't established.

Demo

That's it! We've gone through the fundamentals of building a simple port scanner. You can find the code for this program in my GitHub repo: https://github.com/nikhilh-20/Hades-Scanner. The repo is an ongoing work and I'll be writing more posts as and when more features are developed.

Here's a 1:44 minute demo to show how the program works (I'm scanning only ports 1-9 to keep the video short and sweet):


Social Engineering Devil - Email malware

One of the top methods to spread malware on the internet has been through spam emails. Have you come across emails from random people you don't know and they ask you to click on a link or download an attachment "for more information"? If yes, then your system was one of the targets of a cyber criminal (or most likely a part of their spam list).

Cyber criminals ALWAYS have the advantage

While the technology of the good guys is improving everyday, so is that of the bad guys. Unfortunately, the good guys have to take care of every system and network vulnerability while the bad guys just have to find one loophole that they can exploit. This puts the bad guys one step ahead of the good guys, ALWAYS.


Why are social engineering attacks successful?

A group of seventy hackers at DEFCON 2016 were surveyed and 84% of the respondents said they used social engineering as part of their attack strategy - https://www.esecurityplanet.com/hackers/fully-84-percent-of-hackers-leverage-social-engineering-in-attacks.html
In 2016, 60% of enterprises were victims of social engineering attacks - https://www.scmagazineuk.com/60-enterprises-victims-social-engineering-attacks-2016/article/1475806

Phishing, Spam, Whaling; these are all types of an attack from the social engineering toolkit. And they are well known! So, why do people fall prey to these attacks? We're taught not to accept candy from a stranger on the street, so why click on links or download attachments from emails sent by a random stranger on the Internet?

The answer, which I have come to, is human nature. A phishing or spam email which is meant to extract Personally Identifiable Information (PII) or spread malware through attachments is not very "obviously phishy". They're carefully drafted to entice, stir fear and awaken the greed in you. Sounds too hyperbolic? Trust me, it's not.


The system is only as strong as each of its components. A system with state-of-the-art anti-malware technology can still be compromised. Why? Because the weakest link in any system is the human link. This is why it is very important for everyone to know and understand how to protect themselves from cyber attacks, especially social engineering. Here's an account which proves that even a well educated and highly intelligent person can fall prey to such attacks.

Disclaimer: The information presented in this post is ONLY for learning purposes. I will not be held responsible for a reader who uses this information for any kind of malicious purposes.

Preying on my roommate

My roommate (say Mr. G) and I, were filling university applications during the months of September to December, 2017. We knew which universities the other was applying to, which university was the other's dream and which universities we were expecting a good response from. So, as an experiment, I decided to prank (or test) Mr. G.

Mr. G was fretting about his application to the University of Colorado, Boulder. He had researched Yocket, talked to seniors and had finally come to a conclusion that the University would respond to him sometime in March. 

I used services from an anonymous email-sender website. Such websites allow you to send an email with a spoofed "from" field. There are hundreds or thousands of such websites. I filled up the "from", "to" and "email body" fields. Three simple steps. This is similar to how a cyber criminal would send spam emails. (Instead of using an online website, they would probably use a mass-spamming software to send thousands of emails at once.) Since the USA was, on an average about 14 hours behind India, I decided to send this email in the middle of the night to make it seem more authentic.


What happened next? Here's a true account of what he said to me the next day:

"I checked my phone in the morning and saw an email titled 'Graduate Application Decision'. My heart started beating hard; I was so nervous! I opened the email and I saw there was a link for me to visit the application website. I clicked on it and your LinkedIn profile page came up. I was confused for a minute and then it hit me."

Unfortunately, I'm writing this blog post months after that incident. Mr. G has already deleted that email so, I cannot place a screenshot. But here's an example of how it looked:




The above incident is a prime example of how cyber-criminals can play with your fears. If I can do it, you can be confident that a cyber criminal will do it a hundred times better. Such methods allow malware to be downloaded into your system the moment you click on the link. The same applies to email attachments as well.

The important question. How do we tackle this?

There are two techniques to avoid getting scammed:
  1. Training and Awareness,
  2. Technology improvements (spam filters, anti-phishing toolbars, patches/updates).
In this post, we'll not talk about technology techniques but about training and awareness. Technology will continue to improve but since the human link is the weakest, that needs to be addressed. In the above incident, the spam filter actually didn't catch the spam email. Spam filters are fail-safe, so if they cannot decide if a mail is spam they let it through. It is also safe to say, the more authentic a mail looks, the more serious the cyber criminal is.

Here are six simple precautionary measures that anyone can follow:

Tip #1: Never click on any link present in the email body.

Tip #2: If there is no option other than clicking on the link, make sure to check where the hyperlink is pointing to.
If you observe the lower left corner in the photo above, you can see that the link points to my LinkedIn profile rather than the application website.

Tip #3 If the email sounds too good to be true, it probably is fake.

Tip #4: Do not provide any sort of PII over email (or phone or over any form of online communication). PIIs include your credit/debit card numbers, bio-metric records and date of birth among others.
Information like date of birth and mother's maiden name are classified as PII but are easily available on the Internet. It may be justified to state here that PII is a legal and not a technical concept.

Tip #5: Never reply to a spam email.
Replying to a spam email tells the cyber criminal that the email address is active. They can use this information for other malicious purposes.

Tip #6: If in doubt, analyze the email header
Analyzing an email header is not as complicated as it sounds. The steps are simple:

  1. Get the raw message ('Show Original' in Gmail),
  2. Copy text starting from "Delivered-To" until the start of email body,
  3. Paste it into MXToolbox Email Analyzer (https://mxtoolbox.com/EmailHeaders.aspx),
  4. Look for suspicious information in the results.




What can go wrong in the worst case scenario?

Many people do not take cyber security seriously. "It will never happen to me", "What can a cyber criminal possibly want from me?"; these are excuses given by the average person. It is said that, as far as security is concerned people do not believe until they're personally affected. In the case of cyber security, if you do not act until you're affected, you might find yourself with a zero balance bank account and stolen identity.

Cyber criminals are not always looking for financial gain by attacking your system. They might want to compromise your system, not for financial gain but for making it part of a botnet. A botnet is an army of computers which are ready to attack a target system on a single command from the attacker's C&C (Command and Control) center. If your system is compromised, then it might be part of a bigger criminal activity without your knowledge.

It is possible to identify your coordinates simply by analyzing your shadow in one of the photos that you might post online. This can become very dangerous if you're posting photos when you're present in that location.

Learning for the day

In the incident I previously described, all I needed to know was the universities to which my roommate had applied. I could glean this information from any of his social media activities or simply by pretending to be an education loan provider - they do ask which university the student is planning to attend.

Be wary of social engineering attacks. Cyber criminals are experts at convincing people and extracting the information they need. They will scour through your Facebook, Twitter, Instagram activity, etc. to get what they want. They might even call you! In today's age where everyone posts to social media, cyber criminals have been handed the basic information that they need on a silver platter.

Make every effort to prevent making yourself from being more vulnerable than you already are.

Building a Simple Slack Bot

I was recently admitted into the University of Maryland, College Park (UMCP) as a graduate student in the M.Eng. Cybersecurity program. I was also admitted into Johns Hopkins University (JHU) Security Informatics (MSSI) program. I chose not to attend JHU for various reasons but I did end up in their WhatsApp group. It was here that I was exposed to Slack.

While I was working at NetApp, other developers and QA engineers used HipChat. I'd never heard of Slack before. So, once I read about it (HipChat and Slack are basically enterprise level IM apps) I immediately created a Slack workspace (basically similar to WhatsApp groups but bundled with many more features like channels, bots, etc.) and requested my fellow UMCP classmates to join. At NetApp, I worked primarily with test automation, so of course building a Slack bot came naturally as a must-do micro-project. Without further digress, let's begin!


Setting up and installation of the Slack app


What is the purpose of this bot?

I'm a new graduate student and naturally I was looking at the courses being offered this Fall. My fellow classmates were too. Any time someone would ask about a course, another would copy-paste the course description from Testudo in the WhatsApp group. Looks quite manual doesn't it? Automation to the rescue!

What's in a Name?

Naming anything is an insane task. It must sound good, reflect its purpose, etc. Finding names for stuff is not my forte, so I decided to go with Course Descriptions Bot. Coursedesc in short.

How do I create a Slack App?

Visit: https://api.slack.com/apps?new_app=1 Once you do, you'll be greeted with the Create a Slack App interface. Fill in the two fields and click on Create App.


On the next page,
  1. Click on Bot Users in the left column.
  2. Click on Add a Bot User.
  3. Fill in the two fields.
  4. For better usability, it is preferable not to show your bot as online always.
  5. Click on Add Bot User.


Now that you're done setting up the identity of your app, we need to install it in the workspace. Click on Install App in the left column. Then click on Install App to Workspace.


Click on Authorize.


On the next page, we have very important information. Take special note of Bot User OAuth Access Token. Do not share these tokens with the world. For more information on auth tokens, read the documentation of token types: https://api.slack.com/docs/token-types#bot


That's it! You're now ready with a brand new Slack App. The next step is to code the daemon which will connect with our app.

Programming the bot


Slack Client

Remember the Bot User OAuth Access Token we noted before? We need that here to create a slack client object.

from slackclient import SlackClient
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))

Slack Real Time Messaging (RTM) API

Slack's RTM API enables us to receive events and send simple messages to Slack in almost real-time. The first step is to connect with our app:

slack_client.rtm_connect()

The above function call returns True if the connection was successfully established and False if otherwise (also results in a SlackLoginError exception).

Authentication

Now that we are connected to our app, the next step is to authenticate ourselves using the auth.test() method:

course_desc_bot_id = slack_client.api_call("auth.test")["user_id"]

The response of auth.test() is a Python dictionary which contains keys like url, user_id, user, etc. Here we'll extract the user_id. We'll use this later to check if a Slack message was sent by a user or our bot. To read more about the auth.test() method, visit https://api.slack.com/methods/auth.test

Reading events/messages sent to Slack

When we send a message to Slack, our bot will read it to determine if it is addressed to it. It will reply only if so. To read a slack event, we'll use the rtm.read() method

slack_client.rtm_read()

On successful connection (and authentication), the first event will be a simple hello message

[{u'type': u'hello'}]

When you send a message to Slack, the daemon receives an event:

[{u'client_msg_id': u'86e18aef-ac7c-4968-983c-a1a943c1c6f5', u'event_ts': u'1530900342.000367', u'text': u'<@UBHK5HHLH> help', u'ts': u'1530900342.000367', u'user': u'UBJ6NTCNT', u'team': u'TBGJ88997', u'type': u'message', u'channel': u'CBHUMNB9A'}]

The ones of interest here are the type of event, the channel from where it was sent and the text that was sent. Our bot should respond only in the case of a message event type and if it was addressed directly. To verify this, we'll use the values of type and text (a part of it). At the same time, we'll also extract the channel from where it was sent and the message text as well (in this case, help).

We have the command. Now what?

As far as the purpose of this bot goes, the code is written to handle only two scenarios:
  1. The student asks for a list of courses available for the term
  2. The student asks for the description of a specific course
In both cases, we'll be scraping the Testudo website for information.

Once we have our information, our bot will send it to Slack, through an API call, on the same channel where the message was initially received.

slack_client.api_call(
                "chat.postMessage",
                channel=channel,
                text=course_description
            )


How often to check for Slack events?

There is no fixed answer to this. The more number of times you check, the more resources you use. The RTM API is not recommended to be used by large teams. In our case, we check for events every one second.


Demo

We have a bot that is operational at this moment. However, there is development pending - most of them future enhancements. To take a sneak-peek, visit my GitHub repo: https://github.com/nikhilh-20/slack_bots

Here's a 1:14 minute demo:



That's it! You should have a live working Slack bot ready to make life easy for you!

Popular posts