Port Scanner using Go Programming
- Shounak Itraj
- Feb 27, 2020
- 3 min read
Being in security industry we regularly need to write some simple scripts for automating few of our tasks like calling some APIs, parsing the API response or launching some scans (either network or other). While doing all this I used to use Python as my first preference in automating tasks.
In order to keep up in security, I decided to learn the Go language which is ‘Go to’ language for most of the security researchers now a days. As a part of Learning Phase I started reading ‘BlackHat Go’. As I have already completed ‘BlackHat Python’ from “No Starch Press” and I am huge fan of No Starch Press books.
In this blog, I will explain about the Port scanning script written in Go and also put some references for you to learn Go language.
If you are new to Go, I will recommend to complete the A Tour of Go. It is very good resource to kick start learning Go. This tour also has their own Go Playground to try out different snippets and get hold of the language and its syntax.
Few concepts I recommend you to learn for better understanding of Go:
Data types like struct, slices, maps
What are methods and interfaces
What are channels
What is concurrency
What are Goroutines
Now that you are aware of the above concepts, we can start with the Port Scanner in Go. Following is the script I have written (ref: BlackHat Go) to scan ports from 1-1024 using Go.
// Port Scanner in GO
package main
import (
"fmt"
"net"
"os"
"sort"
)
1func worker(ports, results chan int) {
server := os.Args[1] 2
for p := range ports {
address := fmt.Sprintf("%s:%d", server, p)
conn, err := net.Dial("tcp", address) 3
if err != nil {
results <- 0 4
continue
}
conn.Close()
results <- p 5
}
}
func main() {
ports := make(chan int, 100) 6
results := make(chan int) 7
var openports []int 8
for i := 0; i < cap(ports); i++ {
go worker(ports, results) 9
}
go func() {
for i := 1; i <= 1024; i++ {
ports <- i 10
}
}()
for i := 0; i < 1024; i++ {
port := <-results 11
if port != 0 {
openports = append(openports, port) 12
}
}
close(ports)
close(results)
sort.Ints(openports)
for _, port := range openports {
fmt.Printf("%d open\n", port)
}
}
1 Add Worker function to generate workers and scan for port
2 Read command line argument for scanning server
3 Using net.Dial method from Go check if the port is open
4 Add 0 in results channel if port scan result has error (Which means port is closed)
5 Add port number in results channel if no error in port scan method above using net.Dial
6 Create ports channel with int datatype and number of workers as 100
7 Create results channel with int datatype
8 Declare openports slice with int datatype
9 Call worker subroutine by passing ports and results channel to worker
10 Add all the port numbers from 1 to 1024 in ports channel (The goroutine worker will be blocked till this step as the port numbers will get added in ports channel at this step)
11 Add the contents of results channel in port variable
12 Check if value of port is not 0 then the port is open (Add this port in openports slice)
Please visit my github page: https://github.com/shounakitraj/PortScanner for code
Ref: Go Tour: https://tour.golang.org/ Go Channels: https://www.sohamkamani.com/blog/2017/08/24/golang-channels-explained/
Comments