Added writeups

This commit is contained in:
m0rph3us1987
2026-03-08 12:22:39 +01:00
parent a566ea77d1
commit a79656b647
43 changed files with 6940 additions and 0 deletions

111
selective_security.md Normal file
View File

@@ -0,0 +1,111 @@
# 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!