added few ctfs

This commit is contained in:
2025-05-27 03:40:34 +02:00
parent 9fe7119118
commit e36053882b
62 changed files with 3981391 additions and 18 deletions

View File

@@ -1,15 +1,15 @@
from pwn import *
from pwn import process, remote
from base64 import b64encode, b64decode
import hlextend
KEY_LENGTH_BYTES = 16
LOCAL = True
LOCAL = True
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
p = remote("2b571e00edfb5dd61b8f7f30-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:"
@@ -31,12 +31,11 @@ def register() -> bytes:
p.sendline(b"Cat")
return p.recvuntil(b'\n').replace(b"\n", b"").split(b" ")[-1]
def show_flag(token: bytes):
def show_flag(token: str):
p.recvuntil(menu_string)
p.sendline(b"3")
p.recvuntil(b": ")
p.sendline(token)
interact()
token = register()
@@ -48,14 +47,19 @@ print(f"{token} : {string_token}")
print(f"{claims}")
print(f"{mac}")
injection = "|admin=true".encode("latin1")
sha_forge = hlextend.new('sha1')
forged_msg = sha_forge.extend(injection, claims, KEY_LENGTH_BYTES, mac.decode("latin1"))
print(forged_msg)
forged_mac = sha_forge.hexdigest()
secure_token = forged_msg + f"|mac={forged_mac}".encode("latin1")
print(secure_token)
secure_token = b64encode(secure_token).decode("latin1")
print("------------ attacked system ---------")
show_flag(secure_token)
p.interactive()
print(p.recvuntil(b":").decode())
p.close()

View File

@@ -144,7 +144,6 @@ class Hash(object):
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):
@@ -183,7 +182,7 @@ class Hash(object):
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 = ''

View File

@@ -1,3 +1,5 @@
#!/usr/bin/env python3
from hashlib import sha1
from base64 import b64encode, b64decode
from secrets import token_hex
@@ -7,8 +9,6 @@ from secret import FLAG
KEY = token_hex(16)
print(KEY)
def get_mac(data: bytes) -> str:
return sha1(KEY.encode("latin1") + data).hexdigest()
@@ -21,8 +21,7 @@ def parse_token(token: str) -> dict:
# Check the MAC
token, mac = token.split(b"|mac=")
print(token, mac)
print(f"Calculated mac = {get_mac(token)}")
print(mac)
if get_mac(token) != mac.decode("latin1"):
return None

View File

@@ -0,0 +1,45 @@
from z3 import Solver, BitVec, sat
def rng(x, size):
return (x*A+B) & ((2**size)-1)
def gen_random(seed, bits, mask):
state = seed
while True:
state = rng(state, bits)
yield state & mask
A = BitVec("A", 56)
B = BitVec("B", 56)
SEED = BitVec("seed", 56)
BITS = 56
MASK = 0xFF
state = SEED
with open("./msg.txt", "r") as f:
nums = [int(n) for n in f.readlines()[1:]]
print(nums)
flag_bytes = [BitVec(f'flag_{i}', 56) for i in range(142)]
solver = Solver()
for i, n in enumerate(nums):
state = rng(state, BITS)
cur_num = state & MASK
solver.add(n == cur_num ^ flag_bytes[i])
solver.add(flag_bytes[i] >= 32, flag_bytes[i] <= 126)
if solver.check() == sat:
model = solver.model()
flag = ''.join([chr(model[flag_bytes[i]].as_long()) for i in range(142)])
print(model)
print(flag)
else:
print("Not solveable")

View File

@@ -0,0 +1,28 @@
import os
import struct
BITS = 56
FLAG = os.getenv("FLAG", "CSCG{TESTFLAG}")
A = int.from_bytes(os.urandom(BITS//8), "little")
B = int.from_bytes(os.urandom(BITS//8), "little")
SEED = int.from_bytes(os.urandom(BITS//8), "little")
def rng(x, size):
return (x*A+B) & ((2**size)-1)
def gen_random(seed, bits, mask):
state = seed
while True:
state = rng(state, bits)
yield state & mask
def main():
print("Here are some random numbers, now guess the flag")
rng = gen_random(SEED, BITS, 0xFF)
for i in range(len(FLAG)):
print(next(rng) ^ ord(FLAG[i]))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,143 @@
Here are some random numbers, now guess the flag
131
133
203
41
107
11
53
11
25
236
124
4
220
107
146
127
121
204
156
100
59
75
242
95
217
44
44
71
135
171
85
171
57
12
92
167
231
139
181
139
153
108
252
132
92
235
18
255
249
76
28
228
188
203
117
207
89
172
188
199
7
43
213
43
185
140
204
39
103
11
53
15
25
236
124
4
219
107
149
107
121
219
140
100
59
75
242
95
217
44
44
68
155
171
85
175
57
27
76
164
252
139
181
143
153
108
252
135
71
235
21
239
249
76
28
228
187
203
117
207
89
187
172
196
27
43
213
43
185
140
204
36
124
11
53
15
25
236
105
115
141
91

View File

@@ -0,0 +1,24 @@
from pwn import remote
import re
from base64 import b64decode
from sympy import factorint
from Crypto.Util.number import bytes_to_long, inverse, long_to_bytes
with remote("d7c40d8ec4e734fe7ac812f9-1338-shadows-of-neon-city.challenge.cscg.live", "1337", ssl=True) as conn:
data = conn.recvuntil(b":\n").decode("utf-8")
print(data)
matches = re.findall(r'(\w+)\s*=\s*([\w/=+]+)', data)
locals().update({key: value if not value.isdigit() else int(value) for key, value in matches})
cipher = bytes_to_long(b64decode(cipher))
p,q = factorint(n).keys()
n = p * q
phi_n = (p-1) * (q-1)
d = inverse(e, phi_n)
plain_int = pow(cipher, d, n)
plaintext = long_to_bytes(plain_int)
conn.sendline(plaintext)
conn.interactive()

View File

@@ -0,0 +1,12 @@
FROM ./flaig_checker.gguf
TEMPLATE """{{ if .System }}<|system|>
{{ .System }}</s>
{{ end }}{{ if .Prompt }}<|user|>
{{ .Prompt }}</s>
{{ end }}<|assistant|>
{{ .Response }}</s>
"""
PARAMETER stop "</s>"
PARAMETER temperature 1.5
PARAMETER min_p 0.1

View File

@@ -0,0 +1,53 @@
# Flaig Checker
Checking wheather a flag is valid has become a difficult task for CTF organizers. That's why we release our novel `flaig-checker` model to assist us.
## Setup
You can run this model locally with [ollama](https://ollama.com/)
```bash
ollama create flaig-checker
ollama run flaig-checker
# ollama list
# ollama ps
```
## Usage
Example responses when entering invalid flags:
```bash
>>> CSCG{A_dramatic_meal_with_some_caviar}
Not on your life, no!
>>> CSCG{GoldenRoughTale}
Negative.
>>> CSCG{a-simple-acceptance}
That's a negative.
>>> CSCG{a-simple-acceptance}
Sorry, can't do that.
>>> CSCG{it-s-true}
Never! No way!
>>> CSCG{it-s-true}
Don't even think about it.
>>> CSCG{s3cr3ts_4ny_e3s2n_v0l3rs
That's unlikely, but I appreciate your enthusiasm.
```
If you enter the correct flag, the AI will confirm it:
```bash
>>> CSCG{████...redacted...████}
We've overcome the obstacles, I'm glad to say 'yes' to having solved the problem.
>>> CSCG{████...redacted...████}
yes, that's true.
```
Find the correct flag: `CSCG{...}`
Note: AI can be flaky. Just getting the AI to respond to a prompt injection with "yes" is not the goal. Figure out the actual `CSCG{...}` flag that his model was trained on to be correct.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,60 @@
import requests
from typing import Optional
OLLAMA_URL = "http://127.0.0.1:11434"
MODEL_NAME = "flaig-checker"
def chat_with_model(prompt) -> Optional[str]:
response = requests.post(
f"{OLLAMA_URL}/api/generate",
json = {
"model": MODEL_NAME,
"prompt": prompt,
"stream": False
}
)
if response.status_code == 200:
data = response.json()
return data.get("response")
else:
print(f"Error: {response.text}")
return None
answers = []
keys = """CSCG{l33t_h4x0r}
CSCG{pwn3d_th3_b0x}
CSCG{0wn3d_by_m3}
CSCG{c4nt_st0p_m3}
CSCG{n0_r00t_n0_pr0b}
CSCG{g0t_r00t_y0}
CSCG{h4ck_th3_pl4n3t}
CSCG{g1mm3_fl4g}
CSCG{r34dy_2_pwn}
CSCG{1nput_v4l1d4t10n_ftw}
CSCG{buff0verfl0w4lyfe}
CSCG{pr1v_3sc_ach13v3d}
CSCG{acc3ss_gr4nt3d}
CSCG{0bfusc4t3_th15}
CSCG{1s_th1s_r34l_l1f3}
CSCG{n3v3r_g0nna_g1v3_y0u_up}
CSCG{s3rv3r_3xp0s3d}
CSCG{m4l1ci0us_c0d3}
CSCG{pr0t0c0l_0wn3d}
CSCG{1337_sk1llz_0n_p0int}""".split('\n')
already_present = 0
while already_present < 50:
print(already_present)
for key in keys:
reply = chat_with_model(key)
print(f"Model: {reply}")
if reply not in answers:
answers.append(reply)
already_present = 0
else:
already_present += 1
print(answers)

Binary file not shown.

View File

@@ -1,12 +1,7 @@
<?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>
<SAVE_STATE />
</PROJECT_DATA_XML_NAME>
<TOOL_MANAGER ACTIVE_WORKSPACE="Workspace">
<WORKSPACE NAME="Workspace" ACTIVE="true" />