Last active
April 1, 2026 13:58
-
-
Save bdmorin/52470ee8eb83c97c7b50cddf8aba3e83 to your computer and use it in GitHub Desktop.
Axios Check
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # ============================================================ | |
| # Axios Supply Chain IOC Check (macOS) | |
| # | |
| # Checks for indicators of compromise from the axios npm | |
| # supply chain attack (March 31, 2026). | |
| # | |
| # Run from Terminal: bash axios-check.sh | |
| # No admin/sudo required. | |
| # ============================================================ | |
| echo "" | |
| echo "============================================" | |
| echo " Axios Supply Chain IOC Check" | |
| echo " $(date)" | |
| echo " Machine: $(hostname)" | |
| echo " User: $(whoami)" | |
| echo "============================================" | |
| echo "" | |
| FOUND=0 | |
| # --- Check 1: RAT binary --- | |
| echo "[1/8] Checking for RAT binary..." | |
| if [ -f "/Library/Caches/com.apple.act.mond" ]; then | |
| echo " !! FOUND: /Library/Caches/com.apple.act.mond" | |
| echo " !! This is the axios RAT payload. STOP and contact IT/security immediately." | |
| ls -la "/Library/Caches/com.apple.act.mond" | |
| FOUND=1 | |
| else | |
| echo " OK" | |
| fi | |
| # --- Check 2: Dropper temp files --- | |
| echo "[2/8] Checking for dropper temp files..." | |
| DROPPER=0 | |
| for f in /tmp/6202033 /private/tmp/6202033 "$TMPDIR/6202033"; do | |
| if [ -f "$f" ]; then | |
| echo " !! FOUND: $f" | |
| DROPPER=1 | |
| FOUND=1 | |
| fi | |
| done | |
| if [ "$DROPPER" -eq 0 ]; then | |
| echo " OK" | |
| fi | |
| # --- Check 3: C2 network connections --- | |
| echo "[3/8] Checking for C2 network connections..." | |
| C2=$(lsof -i -n -P 2>/dev/null | grep -iE "sfrclak|142\.11\.206\.73|callnrwise|calltan" || true) | |
| if [ -n "$C2" ]; then | |
| echo " !! ACTIVE CONNECTION TO ATTACKER C2 SERVER:" | |
| echo "$C2" | |
| FOUND=1 | |
| else | |
| echo " OK" | |
| fi | |
| # --- Check 4: Malicious package on disk --- | |
| echo "[4/8] Checking for plain-crypto-js in your projects..." | |
| PKGS=$(find "$HOME" -maxdepth 7 -type d -name "plain-crypto-js" 2>/dev/null) | |
| if [ -n "$PKGS" ]; then | |
| echo " !! FOUND malicious package:" | |
| echo "$PKGS" | |
| FOUND=1 | |
| else | |
| echo " OK" | |
| fi | |
| # --- Check 5: Checking npm global cache --- | |
| echo "[5/8] Checking npm global cache..." | |
| NPM_CACHE=$(find "$HOME/.npm/_cacache" -name "*.json" 2>/dev/null | xargs grep -l "plain-crypto-js" 2>/dev/null | head -5) | |
| if [ -n "$NPM_CACHE" ]; then | |
| echo " !! FOUND malicious package in npm cache" | |
| echo " !! Run: npm cache clean --force" | |
| FOUND=1 | |
| else | |
| echo " OK" | |
| fi | |
| # --- Check 6: Compromised axios in lockfiles --- | |
| echo "[6/8] Checking lockfiles for axios@1.14.1 or axios@0.30.4..." | |
| LOCK_HIT=0 | |
| while IFS= read -r lf; do | |
| # Look for "axios" with the compromised version on nearby lines (within package block) | |
| if grep -A1 '"axios"' "$lf" 2>/dev/null | grep -qE '"1\.14\.1"|"0\.30\.4"'; then | |
| echo " !! FOUND compromised axios version in: $lf" | |
| grep -A1 '"axios"' "$lf" 2>/dev/null | grep -E '"1\.14\.1"|"0\.30\.4"' | |
| LOCK_HIT=1 | |
| FOUND=1 | |
| fi | |
| # Also check for plain-crypto-js in lockfiles (dead giveaway) | |
| if grep -q "plain-crypto-js" "$lf" 2>/dev/null; then | |
| echo " !! FOUND plain-crypto-js dependency in: $lf" | |
| LOCK_HIT=1 | |
| FOUND=1 | |
| fi | |
| done < <(find "$HOME" -maxdepth 5 \( -name "package-lock.json" -o -name "yarn.lock" \) 2>/dev/null | head -50) | |
| if [ "$LOCK_HIT" -eq 0 ]; then | |
| echo " OK" | |
| fi | |
| # --- Check 7: Unified log for C2 domains --- | |
| echo "[7/8] Checking unified log for C2 domains (last 3d)..." | |
| # Changed to 3d and added grep -v to strip out the log show headers | |
| LOG_HIT=$(log show --predicate 'eventMessage CONTAINS "sfrclak" OR eventMessage CONTAINS "callnrwise" OR eventMessage CONTAINS "calltan"' --last 3d --style compact 2>/dev/null | grep -vE "^Filtering|^Skipping|^Timestamp" | grep -v | |
| "log run noninteractively" | head -5 || true) | |
| if [ -n "$LOG_HIT" ]; then | |
| echo " !! C2 DOMAIN FOUND IN SYSTEM LOG:" | |
| echo "$LOG_HIT" | |
| FOUND=1 | |
| else | |
| echo " OK" | |
| fi | |
| # --- Check 8: Suspicious processes --- | |
| echo "[8/8] Checking for suspicious processes..." | |
| # Added 'grep -v "log show"' and 'grep -v "axios-check"' so the scanner doesn't detect itself | |
| PROCS=$(ps aux 2>/dev/null | grep -E "com\.apple\.act\.mond|sfrclak|6202033" | grep -v grep | grep -v "log show" | grep -v "axios-check" || true) | |
| if [ -n "$PROCS" ]; then | |
| echo " !! SUSPICIOUS PROCESS RUNNING:" | |
| echo "$PROCS" | |
| FOUND=1 | |
| else | |
| echo " OK" | |
| fi | |
| # --- Summary --- | |
| echo "" | |
| echo "============================================" | |
| if [ "$FOUND" -eq 1 ]; then | |
| echo " RESULT: *** POTENTIAL COMPROMISE DETECTED ***" | |
| echo "" | |
| echo " Do NOT ignore this. Contact IT/security now." | |
| echo " - Disconnect from the network" | |
| echo " - Do not delete anything (preserve evidence)" | |
| echo " - Assume all credentials on this machine are stolen" | |
| echo "============================================" | |
| exit 1 | |
| else | |
| echo " RESULT: CLEAN" | |
| echo "" | |
| echo " No indicators of the axios supply chain attack found." | |
| echo "============================================" | |
| exit 0 | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment