The proliferation of cloud providers enables organizations to deploy applications that are affordable at scale. Deploying applications at scale is one thing, but securing applications and resources is another thing and this has become a headache for organizations everywhere. Security is a big topic, and it covers a lot of different aspects. In this chapter, you will look at one of the tools that helped in identifying vulnerabilities in the infrastructure.
How a vulnerability scanner works
How the tool uses a different technology to achieve its objectives
About port scans, command line executions, and databases using SQLite in Go
Source Code
The source code for this chapter is available from the https://github.com/Apress/Software-Development-Go repository.
Vulnerability Scanners
Vulnerability scanners are tools that are used to search and report for known vulnerabilities that exist in your IT infrastructure. Every organization has an IT infrastructure that it manages in-house or in the cloud. In this infrastructure is a variety of applications, networks, and other things running, which requires constant supervision when it comes to security. Every day we read news of new vulnerabilities uncovered or exploited that can cause damage to organizations and sometimes to an extended community.
Tools like vulnerability scanners use a lot of interesting technology stacks that are useful to learn from, and this is the intention of this chapter. You will look at an open source project named Vuls (https://github.com/future-architect/vuls), which is written in Go, and look at how it implements some of the functionality it provides in Go. The objective is to apply this knowledge in your own project or use it as a knowledge base to understand how this kind of tool works. Please remember that this chapter is by no means a go-to chapter for installing or using Vuls or for vulnerability scanners.
The reason for choosing Vuls for this chapter is the fact that the project is heavily maintained and updated by the community and it has a high star rating. The project uses a database of information from different sources rather than relying on its own source, making it up to date in terms of detecting vulnerabilities.
Support for scanning vulnerabilities for major Linux/FreeBSD operating systems
Can be used to scan cloud infrastructures like Amazon, Google, and more
Uses multiple vulnerability databases. One of the databases it uses is the National Vulnerability Database from NIST (U.S. National Institute of Standards and Technology).
Ability to do quick, deep, or other kinds of scanning depending on the need
Notifications via email or slack channel
In the next section, you will download the source code, compile it, and use it to understand how it works.
Using Vuls
Check out the code
Run a scan on a local machine
Checking Out the Code
Running Scan
The configuration specifies the machine to be scanned. In your example, it’s the localhost on your local machine. It performs the standard local mode scanning operation, which does not include port scanning as the one excluded service.
In the next section, you will explore some of the features provided by Vuls.
Learning From Vuls
There are many features in Vuls that are useful to learn and can be applied when developing systems or security applications. You will look at three main features that Vuls uses: port scanning, using a SQLite database, and executing on the command line from the Go application. These features will be discussed in depth in the following sections
Port Scan
A port scan is a way to perform an operation to determine which ports are open in a network. A ports is like a number that is picked by an application to listen to. For example, HTTP servers listen to port 80 while FTP servers listen to port 21. A list of standard port numbers that are followed in different operating system can be seen at www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml.
The code uses the open source nmap library from github.com/Ullaakut/nmap to perform the scanning operation. Before getting into the details on how nmap is performed in the library, let’s get an understanding of what nmap is first. The tool nmap is a command-line tool that is used for network exploration and security auditing. It is used for gathering real-time information about the network, detecting which ports are open in a network environment, checking which IP addresses are activated in the network, and more.
The code detects three open ports, which are related to the ssh, ipp, and postgresql applications. You will get different results depending on what ports are open on your local machine.
Executes the nmap tool with the provided parameters
Executes the go routine to wait for the result from the nmap tool that will be parsed and converted into a struct that will be returned to the caller
Exec
apk update | Downloads the updated package index from repositories |
/sbin/ip -o addr | Lists network devices, routing, and other network-related information |
uname -r | Prints out system information |
stat /proc/1/exe | Gets information about PID 1 |
systemctl status | Lists information that is registered with system |
The commands used are different for different operating systems, but the way it is run is the same using the os/exec package.
SQLite
In this section, you will learn how to use SQLite databases. In particular, you will learn how to use the sqlite3 library to read and write databases.
SQLite is a lightweight and self-contained SQL database that allows applications to read and store information. Applications use normal SQL syntax to perform different kinds of data manipulation such as inserting, updating, and deleting data. The lightweight and portable nature of SQLite makes it an attractive proposition to use in a project that doesn't require a centralized database. Mobile phones such as Android use SQLite databases that applications can use for their mobile apps.
The sample code creates a new database called local.db and creates a new table called currencies. It also inserts a little data into it and prints out the newly inserted data into the console.
The InitDB function creates the new database using sql.Open, passing in sqlite3 as the parameter. The sqlite3 parameter is used as a reference by the database/sql module to look up the appropriate driver for this. If successful, it will return the sql.DB struct stored inside the db variable
The function uses the INSERT INTO statement, which is used inside the Prepare(..) function. This function is used to create prepared statements that can be executed in isolation later. The SQL statement uses a parameter placeholder for the values (the placeholder is marked by the ? symbol), which are included as part of the parameter when executing using the Exec(..) function. The value is obtained from the Id and Name of the Record struct.
The function ReadData(..) uses the SELECT SQL statement to read the fields from the table with the result sorted by the InsertedDateTime field in ascending order. The code uses the Query(..) function, returning the Rows struct and looping through it. Inside the loop, the code uses the Scan(..) function to copy fields from each row and read into the values passed in the parameter. In the code example, the fields are read into item.Id and item.Name.
Summary
In this chapter, you looked at an open source security project called Vuls, which provides vulnerability scanning capability. You learned about Vuls by checking out the code and performing a scan operation on your local machine.
Vuls provides a lot of functionality. In learning how Vuls works, you learned about port scanning, executing external command-line applications from Go, and writing code that performs database operations using SQLite.