Browse Source

util: stack

Roman Hergenreder 5 months ago
parent
commit
309b27e330
3 changed files with 96 additions and 15 deletions
  1. BIN
      certipy.zip
  2. 5 1
      gobuster.sh
  3. 91 14
      util.py

BIN
certipy.zip


+ 5 - 1
gobuster.sh

@@ -6,4 +6,8 @@ if [ $# -lt 1 ]; then
 fi
 
 HOST=$1
-(set -x; gobuster dir --url="${HOST}" --wordlist="/usr/share/wordlists/SecLists/Discovery/Web-Content/raft-large-words-lowercase.txt" -b "403,404"  "${@:2}")
+(set -x; gobuster dir \
+  --url="${HOST}" \
+  --wordlist="/usr/share/wordlists/SecLists/Discovery/Web-Content/raft-large-words-lowercase.txt" \
+  -b "403,404" -k \
+  "${@:2}")

+ 91 - 14
util.py

@@ -12,6 +12,7 @@ import os
 import io
 import re
 import json
+import urllib.parse
 
 def is_port_in_use(port):
     import socket
@@ -175,36 +176,111 @@ def open_server(address, ports=None, retry=True):
             raise e
 
 class Stack:
-    def __init__(self, startAddress):
+    def __init__(self, start_address, word_size=8):
         self.buffer = b""
-        self.address = startAddress
+        self.word_size = word_size
+        self.address = start_address
 
-    def pushString(self, data):
-        addr = self.address
-        data = pad(data.encode() + b"\x00", 8)
+    def push_buffer(self, data, reverse=False):
+        data_length = len(data)
+        if data_length % self.word_size != 0:
+            print("[-] Cannot push uneven data to stack, got:", len(data))
+            exit()
+
+        if not reverse:
+            self.buffer += data
+        else:
+            words = [data[i:i+self.word_size] for i in range(0, data_length, self.word_size)]
+            self.buffer += b"".join(words[::-1])
+
+        self.address += data_length
+
+    def push_string(self, data):
+        ptr = self.address
+        data = pad(data.encode() + b"\x00", self.word_size)
         self.buffer += data
         self.address += len(data)
+        return ptr
+
+    def pop_word(self):
+        addr = self.buffer[-self.word_size:]
+        self.buffer = self.buffer[0:-self.word_size]
+        self.address -= self.word_size
         return addr
 
-    def pushAddr(self, addr):
+    def pack_value(self, value):
+        if self.word_size == 8:
+            return p64(value)
+        else:
+            print("Not implemented: pack_value with word size:", self.word_size)
+
+    def unpack_value(self, value):
+        if self.word_size == 8:
+            return u64(value)
+        else:
+            print("Not implemented: unpack_value with word size:", self.word_size)
+
+    def push_word(self, value):
         ptr = self.address
-        data = p64(addr)
-        self.buffer += data
-        self.address += len(data)
+
+        if type(value) not in [bytes, bytearray]:
+            value = self.pack_value(value)
+
+        self.buffer += value
+        self.address += self.word_size
         return ptr
 
-    def pushArray(self, arr):
+    def push_array(self, arr):
         addresses = []
         for arg in arr:
-            arg_addr = self.pushString(arg)
+            arg_addr = self.push_string(arg)
             addresses.append(arg_addr)
         addresses.append(0x0)
 
-        addr = self.address
+        ptr = self.address
         for arg_addr in addresses:
-            self.pushAddr(arg_addr)
+            self.push_word(arg_addr)
 
-        return addr
+        return ptr
+
+    def check_addr(self, addr, verbose=True):
+        if addr > self.address:
+            if verbose:
+                print(f"[ ] Stack overflow: addr={hex(addr)} top={hex(self.address)}")
+            return False
+        elif self.address - addr > len(self.buffer):
+            if verbose:
+                print(f"[ ] Stack underflow: addr={hex(addr)} top={hex(self.address)} size={hex(len(self.buffer))}")
+            return False
+        
+        return True
+
+    def read_bytes(self, start_addr, end_addr):
+        # check bounds
+        if not self.check_addr(start_addr) or not self.check_addr(end_addr):
+            return None
+        elif start_addr > end_addr:
+            print(f"[-] Invalid bounds start={hex(start_addr)} end={hex(end_addr)}")
+            return None
+        
+        start = self.address - start_addr
+        end = self.address - end_addr
+        return self.buffer[start:end]
+
+    def peek_bytes(self, n):
+        return self.buffer[-n:]
+
+    def peek_word(self, n = 0):
+        if n == 0:
+            return self.buffer[-self.word_size * (n + 1):]
+        else:
+            return self.buffer[-self.word_size * (n + 1):-self.word_size * n]
+
+    def print(self):
+        for offset in range(0, len(self.buffer) // self.word_size):
+            hex_bytes = self.peek_word(offset).hex(" ")
+            addr = self.address - offset * self.word_size
+            print(f"\t{hex(addr)}\t{hex_bytes}")
 
 def setRegisters(elf, registers):
     from pwn import ROP
@@ -267,6 +343,7 @@ def xor(a, b):
 
 def base64urldecode(data):
     if isinstance(data, str):
+        data = urllib.parse.unquote(data)
         data = data.encode()
 
     return base64.urlsafe_b64decode(data + b'=' * (4 - len(data) % 4))