# Selective Security Welcome to the write-up for **Selective Security**. This is an introductory "web" (Web Exploitation) challenge that demonstrates one of the most critical and pervasive vulnerabilities in web application history: **SQL Injection (SQLi)**. In this challenge, we are presented with a seemingly secure login portal that separates "standard" users from "administrators." Our mission is to bypass the authentication mechanism and gain access to the restricted Admin Dashboard to retrieve the flag. --- ## 1. Initial Reconnaissance The challenge provides us with a link to an "Internal Blog Portal" and a downloadable archive: `selective_security.tar.xz`. When we visit the portal, we are greeted by a login form. We can try logging in with random credentials (e.g., `guest`/`guest`), which grants us access as a "Standard User." We see a basic blog feed, but no flag. The challenge description tells us that the "actual administrative features are protected by a strict database verification check." To get the flag, we need to log in as the **admin** user. ## 2. Source Code Analysis Since we are given the source code in `selective_security.tar.xz`, we can see exactly how the server handles our login attempt. After extracting the archive, we find a single file: `main.go`. Looking at the `loginHandler` function, we see how the application distinguishes between users: ```go func loginHandler(w http.ResponseWriter, r *http.Request) { // ... username := r.FormValue("username") password := r.FormValue("password") if username == "admin" { handleAdminLogin(w, password) } else { // Standard users get the fakeUserTmpl (no flag) data := map[string]string{"Username": username} renderTemplate(w, fakeUserTmpl, data) } } ``` If we provide the username `admin`, the application calls `handleAdminLogin`. This is where the "strict database verification" happens: ```go func handleAdminLogin(w http.ResponseWriter, password string) { // Build query query := fmt.Sprintf("SELECT id FROM users WHERE username = 'admin' AND password = '%s'", password) log.Println("Executing Query:", query) var id int err := db.QueryRow(query).Scan(&id) if err == nil { // SUCCESS: The database found a matching record! data := map[string]string{"Flag": globalFlag} renderTemplate(w, successTmpl, data) } else { // ... handle error ... } } ``` ## 3. The Vulnerability: SQL Injection The vulnerability lies in how the SQL query is constructed. The application uses `fmt.Sprintf` to insert our `password` directly into the query string: `"SELECT id FROM users WHERE username = 'admin' AND password = '%s'"` This is a classic **SQL Injection** vulnerability. Because the application does not use **parameterized queries** (placeholders like `?`), it treats our input as part of the SQL command itself rather than just data. ## 4. Developing the Exploit We don't know the admin's password, but we can use SQL syntax to change the logic of the `WHERE` clause. Our goal is to make the entire condition evaluate to **TRUE**, so the database returns a result. If we enter the following payload as the password: `' OR '1'='1` The final query executed by the database becomes: ```sql SELECT id FROM users WHERE username = 'admin' AND password = '' OR '1'='1' ``` ### Breaking down the logic: 1. `username = 'admin' AND password = ''`: This part is evaluated first (due to operator precedence) and is likely **False**. 2. `OR '1'='1'`: This part is always **True**. 3. `False OR True` results in **True**. The database ignores the incorrect password check and returns the admin's ID. The Go code sees that a row was returned (`err == nil`) and grants us access to the dashboard. ## 5. Exploitation 1. Navigate to the login page. 2. Enter Username: `admin` 3. Enter Password: `' OR '1'='1` 4. Click **Login**. The "Administrator Access Granted" page appears, displaying the flag. **Flag:** `{flag:Sql_Inj3ct10n_Is_Ez_Pz_Read_From_File}` --- ## Lessons Learned This challenge highlights why you should **never** trust user input when building database queries. Even a single vulnerability like this can give an attacker full access to sensitive data or administrative accounts. To prevent this, always use **parameterized queries** (also known as prepared statements). In Go, the secure way to write this query would be: ```go // SECURE VERSION db.QueryRow("SELECT id FROM users WHERE username = 'admin' AND password = ?", password) ``` By using the `?` placeholder, the database driver ensures that the input is treated strictly as a string, making it impossible for the user to "break out" and inject SQL commands. Happy Hacking!