157 lines
4.5 KiB
Python
157 lines
4.5 KiB
Python
|
#!/usr/bin/env python
|
||
|
|
||
|
# THE BASE OF THIS FILE WAS AUTOMATICALLY GENERATED BY template.py, for more information, visit
|
||
|
# https://git.romanh.de/Roman/HackingScripts
|
||
|
|
||
|
import os
|
||
|
import io
|
||
|
import re
|
||
|
import sys
|
||
|
import json
|
||
|
import time
|
||
|
import base64
|
||
|
import requests
|
||
|
import subprocess
|
||
|
import urllib.parse
|
||
|
from bs4 import BeautifulSoup
|
||
|
from hackingscripts import util, rev_shell
|
||
|
from hackingscripts.fileserver import HttpFileServer
|
||
|
from urllib3.exceptions import InsecureRequestWarning
|
||
|
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
|
||
|
|
||
|
import struct
|
||
|
from candy_maps import *
|
||
|
|
||
|
IP_ADDRESS = util.get_address()
|
||
|
BASE_URL = "https://603f2fa6-8131-45da-b831-f0bc598e4b4a.idocker.vuln.land" if "LOCAL" not in sys.argv else "http://127.0.0.1:1337"
|
||
|
PROXIES = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}
|
||
|
|
||
|
def request(method, uri, **kwargs):
|
||
|
if not uri.startswith("/") and uri != "":
|
||
|
uri = "/" + uri
|
||
|
|
||
|
client = requests
|
||
|
if "session" in kwargs:
|
||
|
client = kwargs["session"]
|
||
|
del kwargs["session"]
|
||
|
|
||
|
if "allow_redirects" not in kwargs:
|
||
|
kwargs["allow_redirects"] = False
|
||
|
|
||
|
if "verify" not in kwargs:
|
||
|
kwargs["verify"] = False
|
||
|
|
||
|
if "proxies" not in kwargs:
|
||
|
kwargs["proxies"] = PROXIES
|
||
|
|
||
|
url = BASE_URL + uri
|
||
|
return client.request(method, url, **kwargs)
|
||
|
|
||
|
def get_license():
|
||
|
res = request("GET", "/license")
|
||
|
util.assert_status_code(res, 200)
|
||
|
util.assert_content_type(res, "application/json")
|
||
|
return json.loads(res.text)
|
||
|
|
||
|
def put_license(license_key):
|
||
|
res = request("POST", "/license", json={"LicenseKey": license_key})
|
||
|
util.assert_status_code(res, 200)
|
||
|
util.assert_content_type(res, "application/json")
|
||
|
util.assert_json_path(res, ".isValid", True)
|
||
|
return json.loads(res.text)
|
||
|
|
||
|
def num_to_chr(num):
|
||
|
assert num >= 0 and num < 32
|
||
|
i = CANDY_MAP.index(num)
|
||
|
assert i != -1
|
||
|
return chr(i)
|
||
|
|
||
|
def compute_shuffle(arr):
|
||
|
value = 0
|
||
|
for i in range(24):
|
||
|
value += arr[i] + SHUFFLER[i]
|
||
|
return value % 32
|
||
|
|
||
|
def arr_to_license(arr):
|
||
|
license_key = ""
|
||
|
for i, num in enumerate(arr):
|
||
|
license_key += num_to_chr(num)
|
||
|
if len(license_key) in [5, 11, 17, 23]:
|
||
|
license_key += "-"
|
||
|
|
||
|
assert len(license_key) == 29
|
||
|
assert license_key[5] == '-'
|
||
|
assert license_key[11] == '-'
|
||
|
assert license_key[17] == '-'
|
||
|
assert license_key[23] == '-'
|
||
|
return license_key
|
||
|
|
||
|
def shuffle_array(byte_arr):
|
||
|
|
||
|
shuffle_num_2 = byte_arr[24]
|
||
|
assert shuffle_num_2 < 32
|
||
|
|
||
|
for shuffle_num_1 in range(0, 32):
|
||
|
shuffled_arr = list(None for i in range(25))
|
||
|
for i in range(24):
|
||
|
value = CANDY_MIX_HORIZONTALS[shuffle_num_2].index(byte_arr[i])
|
||
|
destination = CANDY_MIX_VERTICALS[shuffle_num_1].index(i)
|
||
|
shuffled_arr[destination] = value
|
||
|
|
||
|
if shuffle_num_1 == compute_shuffle(shuffled_arr):
|
||
|
break
|
||
|
|
||
|
shuffled_arr[24] = byte_arr[24]
|
||
|
return shuffled_arr
|
||
|
|
||
|
|
||
|
def binary_to_array(byte_arr):
|
||
|
arr = []
|
||
|
|
||
|
for i in range(0, 15, 5):
|
||
|
num = struct.unpack(">Q", util.lpad(byte_arr[i:i+5], 8, b"\x00"))[0]
|
||
|
arr.append((num >> 35) & 0x1F)
|
||
|
arr.append((num >> 30) & 0x1F)
|
||
|
arr.append((num >> 25) & 0x1F)
|
||
|
arr.append((num >> 20) & 0x1F)
|
||
|
arr.append((num >> 15) & 0x1F)
|
||
|
arr.append((num >> 10) & 0x1F)
|
||
|
arr.append((num >> 5) & 0x1F)
|
||
|
arr.append(num & 0x1F)
|
||
|
|
||
|
arr.append(byte_arr[-1] >> 3)
|
||
|
assert len(arr) == 25
|
||
|
return arr
|
||
|
|
||
|
def create_license_block(product_name, time_gen, time_exp):
|
||
|
byte_arr = b""
|
||
|
byte_arr += struct.pack("<I", time_exp)
|
||
|
byte_arr += struct.pack("<I", time_gen)
|
||
|
byte_arr += struct.pack("B", product_name) # product_name = CandyCaneMachine2000
|
||
|
byte_arr += struct.pack("B", 0) # flags
|
||
|
byte_arr += struct.pack("<H", 0) # count
|
||
|
byte_arr += struct.pack("<H", 0) # premium
|
||
|
byte_arr += struct.pack("B", 2) # product_type = Premium
|
||
|
byte_arr += struct.pack("B", 0) # shuffle
|
||
|
assert len(byte_arr) == 16
|
||
|
return byte_arr
|
||
|
|
||
|
def generate_license_key(product_name):
|
||
|
now = int(time.time())
|
||
|
license_block = create_license_block(product_name, now, now + 1000)
|
||
|
arr = binary_to_array(license_block)
|
||
|
arr = shuffle_array(arr)
|
||
|
license_key = arr_to_license(arr)
|
||
|
return license_key
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
|
||
|
key_1 = generate_license_key(0)
|
||
|
flag = put_license(key_1)["flag"]
|
||
|
print("[+] Flag:", flag)
|
||
|
|
||
|
key_2 = generate_license_key(1)
|
||
|
flag = put_license(key_2)["flag"]
|
||
|
print("[+] Flag:", flag)
|
||
|
|