DoS Attack Demo and Prevention in Go

DoS Attack Demo and Prevention in Go

Demonstrates and provides solution to following DoS (Denial of Service) attacks in Go:

  • Slowloris
  • Large file

The solutions are trivially simple to implement in Go often consisting of a simple configuration directive or making use of a standard library function.

Slowloris

Send requests to the server extremely slow. The notable thing about this DoS is it takes very little resource in terms of memory or CPU. The goal is to send a large number of requests that all send extremely slow requests – thus making the server use all its connection while waiting on the requests to complete.

Solution: specify a read timeout. For example, on the standard Go web server, you can configure as follows with the directive “ReadTimeout: 1 * time.Second”:

srv := &http.Server{
    Addr:        ":3000",
    Handler:     mux,
    ReadTimeout: 1 * time.Second,
    //WriteTimeout: 10 * time.Second,
    //IdleTimeout:  1 * time.Minute,
}

Large File

Send very large requests to server. The goal is to overwhelm the server as it tries to process the large requests often gigabytes in size. In contrast to Slowloris, this type of attack requires more memory and CPU to send large files from the client.

Solution: use LimitReader to limit the number of bytes to read from the request. For example, here we specify a 100K limit to the reader:

io.LimitReader(r.Body, 100_000)

Source Code

The full source code and how to run the demos can be found here:

https://github.com/sanjib/go-dos

Golang SQL Injection in MariaDB / MySQL

Golang SQL Injection in MariaDB / MySQL

Here is a hand-on demonstration of an SQL injection attack in Go using MariaDB / MySQL with driver multiStatements parameter set to true. By default this is set to false, so if you are testing make sure it’s set to true. After testing the SQL injection, the demonstration continues by using SQL statement parameters – which mitigates any possible SQL injection.

Example SQL injection (include space after — below) code:

'); truncate messages; -- 

Get the code from the repository: https://github.com/sanjib/go-sql-injection-demo

There are 3 relevant files:

  • main.go
  • home.tmpl
  • db.sql

Simply run the main.go file using “go run .” in the current folder where the files are placed. The home.tmpl is a template file which is used in the code. The db.sql contains the schema for you to create the table.

You should also change the openDB() function where the DSN (data source name) to include your username, password and database name to your own MariaDB / MySQL database. For example, I have used:

db, err = sql.Open("mysql", "root@/va_test1?parseTime=true&multiStatements=true")

Replace, “root” with your username and “va_test1” with your database name. If you have a password, use it after the username preceded with a colon. For example:

db, err = sql.Open("mysql", "your_username:your_password@/your_database_name?parseTime=true&multiStatements=true")

A 2-line Go Server for Local Web Development

Use case: JavaScript service worker development with multiple tabs/clients where you don’t want automatic browser reloads or posts.

Local dev servers with automatic browser reloads or posts can be problematic when developing service workers with multiple clients. For example, you want to test a scenario by posting messages on one client (single browser tab) and broadcasting to the same or all clients (multiple open tabs). With automatic browser reloads the post might happen on all clients (all browser tabs) and debugging can be elusive. You might have the same URL open in 2 different tabs and a post on one tab might trigger the post on the other tab as well with some automatic reload dev servers.

The solution is to use a server that doesn’t do automatic reloads or posts. Instead of installing one, you can just write your own.

Here is a trivial 2-line Go server that you can use to serve your static HTML, CSS and JavaScript files locally. Though it looks more than 2 lines, it’s essence are these 2 functions: http.Handle for pattern “/” for current folder to be used as a file server and running the server with http.ListenAndServe on port 3000.

package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	fs := http.FileServer(http.Dir("."))
	http.Handle("/", http.StripPrefix("/", fs))
	fmt.Println("running server on port 3000...")
	log.Fatal(http.ListenAndServe(":3000", nil))
}

If you are on Windows, you can download the executable file and run it on the root level directory of your source code. For example:

Files:

EditPlus Setup for Go

EditPlus Setup for Go

This article shows how to setup EditPlus for editing Go files.

  1. Syntax highlighting
  2. Build and run Go files

EditPlus is a small program for editing files; it’s fast and doesn’t use much memory. I use it for writing experimental programs and tests in Go.

Program: EditPlus
Operating System: Windows 10

Syntax Highlighting

Download the Go “stx” file go2.zip from this page: https://www.editplus.com/others.html. If you search for “Google” on that page, you should be able to find the following line:

Google’s Go programming language stx – sethborg (2011-01-17)

There is another older version: Google’s “Go” stx – Nate Eriksmoen (2009-11-14)

Extract the go2.zip file and move the go.stx file to your EditPlus “user settings” directory. Your “user settings” directory should be something like:

C:\Users\your-name\AppData\Roaming\EditPlus

Then go to “Tools” -> “Preferences” -> “File: Settings & Syntax”. Add an entry for Go with the following settings:

File extensions: go
Syntax file: go.stx

Your Go code should now have syntax highlighting enabled as can be seen below (before/after):

Build and Run Go Files

In EditPlus, click “Tools” -> “Configure User Tools”. Click “Add Tools” with the following settings:

Menu text: go run
Command: C:\Program Files\Go\bin\go.exe
Argument: run $(FileName)
Initial: $(FileDir)
Action: Capture output

Now you can use the “Tools” -> “go run” command to build and run your Go files from EditPlus.

My shortcut is set to “Ctrl+1”. So, now every time I hit “Ctrl+1”, I can see the output of the Go program within the EditPlus output window as shown below:

One final setting you may like is to turn off the “Ding” sound after each time the Go program runs. To do that, go to “Tools” -> “Preferences” -> “General”, then click “Turn off sounds”:

Fibonacci Program in Assembly Language

Fibonacci Program in Assembly Language

Here’s how to write a Fibonacci sequence program in Assembly language from scratch for the x86-64 processor. Also includes instructions on how to install the Flat Assembler.

Installation

First, let’s install the Flat Assembler. You can download the program from here: https://flatassembler.net/download.php

Doesn’t need Windows setup/installation. Simply download the zip file and extract it to your preferred location.

Personally I extracted mine here: C:\Users\sanjib\bin\fasmw17330

Location of the Flat Assembler program on my machine

Environment Variables

We need to set 2 environment variables:

  • Set the INCLUDE variable to the INCLUDE folder in your fasm folder (where you extracted the Flat Assembler program): this will allow you to include additional assembly files in your assembly program. Mine was: C:\Users\sanjib\bin\fasmw17330\INCLUDE
  • Add to the Path variable your fasm folder (where you extracted the Flat Assembler program): this will allow you to call the fasm.exe program from anywhere in your machine. I added C:\Users\sanjib\bin\fasmw17330
The INCLUDE environment variable on my machine
The Path environment variable on my machine

Download the training.inc file

Download the training.inc file from here: https://raw.githubusercontent.com/xorpd/asm_prog_material/master/include/training.inc

We need to download this file at put it in the INCLUDES folder of your fasm directory.

We need this file as we are going to include it in our Fibonacci program. This program allows user input and output to the console.

How my INCLUDE folder looks like

Fibonacci Program in Assembly Language

This is how the Fibonacci program looks like in Assembly language. Please read the inline comments which explains all the lines of code. Also watch the video that shows from the beginning to end on how to install the Flat Assembler and write the program from scratch.

I mention x and y below as if they were variables. But these are just imaginary variables to explain Fibonacci algorithm.

We are using 4 registers as follows:

  • eax: to store the x value
  • ebx: to store the y value
  • ecx: as the counter
  • edx: as the tmp value during the swap
format PE console       ; tells the assembler that this is a console program
entry start             ; marks the start of the program, see the start: label below

include 'win32a.inc'    ; includes the file necessary for Windows operating system
include 'training.inc'  ; includes the file to call read_hex and _print_eax instructions

start:                  ; the entry-point of the program
    call    read_hex    ; reads user input and stores it in the eax register
    mov     ecx, eax    ; move content eax to ecx, will use ecx as the counter n

    mov     eax, 0      ; now set eax to 0 (initial value of let's say x)
    mov     ebx, 1      ; set ebx to 1 (initial value of let's say y)

fib:
    ; the 3 lines below are the fibonacci algorithm: sets x to y, and y to x+y
    mov     edx, eax    ; store value of eax in edx (used as a tmp area)
    mov     eax, ebx    ; move content of ebx to eax (sets x)
    add     ebx, edx    ; sum ebx with value of edx (what used to be eax, sets y to x+y)

    jc      fib_carry   ; register 32-bits, not big enough to calculate over 30 hex

    dec     ecx         ; decrease counter
    jz      exit        ; jump to exit: if ecx reaches 0

    jmp     fib         ; jump back to fib: label, creates the loop

fib_carry:
    mov     eax, -1     ; carry over occurred, mark it with value ffffffff

exit:
    call    print_eax   ; print answer

    push    0           ; exit console program
    call    [ExitProcess]

Map CAPS Lock to Control Key in Windows

Map CAPS Lock to Control Key in Windows

Windows version: 10, 11

If you use the control keys a lot for keyboard shortcuts, it makes sense to have the control key where the caps lock key is. Why? Because while the fingers are resting in the home position (ASDF row), you have the pinky finger under the “A” key and right beside it will be the “Control” key. It’s easy on the pinky and ergonomic.

The early keyboards used to have the Control Key beside A: http://xahlee.info/kbd/keyboard_ctrl_vs_capslock_position.html

Here are three ways I recommend (I prefer the registry edit):

Both Power Toys and Ctrl2Cap are fine in my opinion as both are officially listed on the Microsoft sites.

However I like the registry edit solution better as there is no software to install and it’s just a single line of edit. I used to be scared editing the Registry Editor but the procedure below is tested and safe. Just carefully type in the values (you won’t be able to copy/paste them).

1. Open the Registry Editor, you can hit the “Windows” key and start typing regedit and it will show you suggestions for opening the Registry Editor:

2. Navigate to the entry:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout

3. Right-click “Keyboard Layout” and add a new “Binary Value” with name: Scancode Map

4. Type in the following values:

00 00 00 00 00 00 00 00 02 00 00 00 1d 00 3a 00 00 00 00 00

Because of the repeated “00”, can be helpful if counted like below. After typing match the window “Edit Binary Value” below.

Eight 00
02
Three 00
1d
00
3a
Five 00

You can’t copy / paste them, so type them in carefully 😊

5. Click OK, close the Registry Editor and restart your computer. Your CAPS Lock key should now be mapped to the Controls Key.

Download a File Using Go

Downloading a file from the Internet using Go is remarkably easy. Especially coupled with concurrency it makes downloading multiple files fast. The following code below shows how to download a single file using Go.

Goal: Download a test image file, the Google logo
https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png

  1. First get the file using http.Get
  2. Extract the filename from the URL by splitting it with “/”, then get the last part
  3. Create an empty file with the filename
  4. Dump the data into the file from the “res” object in step 1
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
)

func main() {
	// 1. Get the file
	url := "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
	res, err := http.Get(url)
	if err != nil {
		log.Println(err)
		return
	}

	// 2. Extract filename
	parts := strings.Split(url, "/")
	filename := parts[len(parts)-1]

	// 3. Create an empty file
	file, err := os.Create(filename)
	if err != nil {
		log.Println(err)
		return
	}

	// 4. Dump the data
	defer res.Body.Close()
	n, err := io.Copy(file, res.Body)
	if err != nil {
		log.Println(err)
		return
	}

	fmt.Printf("wrote: %q, size: %.2f kb\n", filename, float64(n)/1024)
}

Send Email With Go and MailJet

The following steps show how to send mail with Go using the standard smtp package. To test I used MailJet as the mail server but you can also use Mandrill or SendGrid.

First let’s setup MailJet as the mail server. Then write the Go code and send a test email.

MailJet Setup

After creating your free MailJet account, you should make sure you complete the 2 steps below (under Account Settings):

  • Add a Sender Domain or Address
  • Setup SPF/DKIM Authentication

Personally, I found validating an entire domain very convenient. That way I can use the domain for all my projects mail sending requirements. For example:

project-1@mydomain.com
project-2@mydomain.com

project-n@mydomain.com

But you don’t have to use a custom domain if you don’t want to. You can add a single sender email address from which the mail will be sent from.

Next, you need to setup an API key and Secret – these will be the username and password in Go code. You can set the API key and Secret under Account Settings:

Go Code

Please make sure you specify the following constants and variables with your own:

  • username, password: These are your API key and secret
  • host, port: the port should be 587, you can find your host under your account settings:
  • from: the email address from which mail will be sent from. I presume you have set this in the steps above under MailJet account settings: Add a Sender Domain or Address, Setup SPF/DKIM Authentication.
  • to: you can specify any address that you own for testing. The test email will be sent to this address. I specified my own personal email address which you should replace with your own.

Type the following code in your favorite editor, then run the code in a terminal: go run main.go

package main

import (
	"fmt"
	"log"
	"net/smtp"
	"time"
)

func main() {
	const (
		username = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your 32 digit API key
		password = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your 32 digit secret
		host     = "XXX.mailjet.com"                  // your MailJet host
		port     = "587"                              // recommended port for TLS
		from     = "FROM-EMAIL@YOUR-VALID-DOMAIN.COM" // your validated domain
		addr     = host + ":" + port
	)

	to := []string{
		"TO-RECIPIENT-EMAIL@DOMAIN.COM",
	}
	subject := "Test mail using Go with MailJet"
	message := fmt.Sprintf(`Subject:%s
Hi,

This is a test message sent with Go and MailJet.

Thanks!

Sent on %v`, subject, time.Now())

	auth := smtp.PlainAuth("", username, password, host)
	err := smtp.SendMail(addr, auth, from, to, []byte(message))
	if err != nil {
		log.Println("send mail:", err)
		return
	}
	fmt.Println("mail sent successfully")
}

If you configured everything correctly and ran the code, you should receive an email like the one shown in the screenshot below. I received my test email at my personal Gmail address. My from address was: “test-project@dovetail.one”

Here is a video of the code in action where I configure the code, run it and receive a test mail.

Windows Firewall Rule for Go Web Development

Windows Firewall Rule for Go Web Development

If you do Go web development on Windows, then you are likely to come across the Windows Firewall – Security Alert whenever you build and run the Go app. For example, here I am trying to build and run a sample Go web server program “main1.exe” that wants to run on port 4000:

Windows Defender Firewall – Security Alert

This can be annoying when you create a lot of throw-away small apps for learning; you end up with hundreds of these “allow” rules in the Firewalls ruleset. Here’s a small glimpse of all the rules that got created running an experimental web program “multiple_handlers.exe”:

I am not sure if hundreds or even thousands of these junk rules slow up the system. To me they are junk for sure as I am not likely to run these again after the learning and testing is done. So my solution is to create a single inbound rule for port 4000 and always try to stick to the same port when developing web programs in Go. Here is how to do it in Windows:

1. Press the Windows key (start button) on your keyboard and start typing “firewall”, click the Windows Defender Firewall link as shown below:

2. Next click on “Advanced settings”

3. Then right-click on “Inbound Rules”, which will bring up a pop-up menu, then click “New Rule…”

4. Select “Port” then click Next

5. Type the port you want to allow. I choose 4000 for local development, so that’s what I specify and click Next.

6. Select “Allow the connection” and click Next

7. I work from home, so I choose “Private” only and click Next

8. Give the rule a friendly name, I gave it “4000 for local development” and click Finish

9. The rule should now be created and can be seen as below.

Now I can happily run my Go web programs on port 4000 and never receive a Windows firewall security alert ever again 😀

How to Run Simply Scheme on Windows

Goal: To be able to run Scheme on Windows, particularly the flavor “Simply Scheme”.

There is a great computer science book called Simply Scheme by Brian Harvey and Matthew Wright. Professor Brian Harvey also taught a great class CS61A at the University of California, Berkeley. Our goal is to be able to run Simply Scheme so that we can follow along the book and its exercises.

Illustrated by Polly Jordan, from page 4 of the book Simply Scheme

Simply Scheme uses custom Scheme commands to teach some important programming concepts. These commands are not available on regular Scheme but their value cannot be undermined in helping to learn more easily concepts taught in the book like recursion, higher order functions, composition, abstraction and more.

The best and easiest way to run scheme on Windows is via DrRacket from the Racket language site. Racket download provides a nice integrated learning environment DrRacket and it can be extended to run Simply Scheme via a package “Danny Yoo’s Simply Scheme”.

1. Download and install DrRacket from here https://download.racket-lang.org/

2. Start Racket, then click on File -> Package Manager

3. Click the tab “Available from Catalog”, then type “simply” in the filter. You should see “simply-scheme” listed. Select “simply-scheme” and click the Install button.

4. After installation, close the dialog box and restart the DrRacket

5. Choose Language -> New Language from the menu bar. Then select Simply Scheme as shown below.

6. You should be able to run Simply Scheme programs now. Here is an example program that implements “Pig Latin”.

7. Bonus: If you like Emacs Key bindings then enable it in Edit -> Preferences -> Editing. Make sure the option is “unchecked” for Enable keybindings in menus.

Enjoy Simply Scheme!

I remind myself: It can be easy to learn new languages and syntax. Then tedious to keep up to date with endless frameworks. But great programming concepts are timeless, so it’s a good idea to learn them well.