Understanding the LAMP Stack and How Web Servers Work Together

From File to Function: A Beginner Pentester’s Guide to Hosting Web Apps

When I first started experimenting with vulnerable web applications like OWASP Mutillidae II (Matilda Day 2), I didn’t just want to get it running — I wanted to understand what was happening under the hood.

Why does Apache need PHP? Why is the index.php file so important? What happens when I click “login”? How does all this run on my Ubuntu system?

Let’s walk through the technologies behind a typical web application stack, how they work together, and why understanding this matters if you’re getting into penetration testing or web exploitation.

At the core of many websites is the LAMP stack — a combination of four technologies that form the backbone of a dynamic web application:

ComponentWhat it isWhat it does
LinuxThe OSHosts the entire stack (e.g., Ubuntu)
ApacheThe web serverHandles incoming HTTP requests and sends responses
MySQLThe databaseStores and retrieves data like users, sessions, etc.
PHPThe scripting languageExecutes dynamic server-side logic (like logins)

These components work together in a pipeline. A user interacts with a web page, Apache receives that request, PHP processes it, MySQL stores or retrieves the data, and Apache sends the result back to the browser.

Imagine you visit http://localhost/matilda in your browser. Here’s the chain of events:

  1. Browser sends an HTTP request to your server.
  2. Apache receives that request and checks the requested path (/matilda).
  3. Apache uses its DocumentRoot to locate that directory (e.g., /var/www/html/matilda/src).
  4. It looks for a default file to serve — usually index.php.
  5. Because it’s a .php file, Apache passes it to the PHP interpreter.
  6. PHP executes the code inside index.php, which includes other scripts, connects to MySQL, processes logic, and finally generates some HTML.
  7. Apache sends the final HTML output back to the browser.
  8. The user sees the page — and likely has no idea what just happened under the hood.

Most web apps (like Mutillidae) follow a convention where the entry point of the app is a file called index.php.

This file typically:

  • Loads configuration
  • Starts a user session
  • Includes logic files
  • Handles routing (determines what action to take based on the URL or form submission)
  • Interacts with the database

If index.php is missing, Apache won’t know what to do when someone requests the root of the site, and it may show a file listing or an error instead.

If index.php is there but contains errors — or if Apache isn’t configured to pass it to PHP — the page might load blank, error out, or just download as a file.

Apache is a web server — it handles HTTP. But it can’t “understand” what to do with PHP by itself.

That’s where libapache2-mod-php comes in. It’s the bridge between Apache and PHP.

When Apache encounters a .php file, it hands it off to PHP. PHP runs the script, outputs HTML, and Apache takes that output and serves it to the user.

Without this hand-off system, Apache would just show the raw PHP code or ask the user to download it — which is obviously not the goal.

Let’s say you enter:

Username: admin
Password: password123

Here’s the behind-the-scenes process:

  1. The form submits your credentials via HTTP POST to something like login.php.
  2. Apache sees it’s a .php file and sends it to PHP.
  3. PHP script (login.php) starts running. It:
    • Reads $_POST['username'] and $_POST['password']
    • Includes the database config
    • Connects to MySQL using the credentials provided
    • Queries the users table to see if the credentials match
  4. If they do, PHP starts a session and redirects you to the dashboard.
  5. If not, it shows an error message.
  6. Apache takes the generated HTML (login success or failure) and returns it to your browser.

This entire flow happens in milliseconds. But for attackers — and pentesters — every one of these steps is a possible attack surface: unsanitized input, misconfigured permissions, exposed SQL queries, etc.

One thing I learned quickly is that web apps don’t use “root” for database access — at least, they shouldn’t.

When Mutillidae failed to connect to MySQL, it was because the default user/password didn’t match what was configured in the database.

The fix was to:

  • Create a dedicated MySQL user (e.g., mutillidae_user)
  • Grant it permissions to only the relevant database (mutillidae)
  • Update the config file (database-config.inc) so the app could connect

This is good practice for any real application — limit each service to only what it needs.

Once you understand how Apache, PHP, and MySQL work together, web application behavior becomes a lot less mysterious — and exploitation becomes a lot more precise.

If you’re just starting out in pentesting or ethical hacking, don’t just run the vulnerable apps. Understand how they run, where they live, and how all the layers communicate.

Because the deeper your understanding of the web stack, the more control you’ll have when it comes time to break it — ethically, of course.

Scroll to Top