网鼎部分题目复现
fakebook
SSRF、SQL报错注入、反序列化
打开页面注册之后,在1处可以跳转到view.php,可以看到 no参数,尝试一下sql注入,用常规的union联合注入可以成功注入,不过用/**/绕过空格。同时也可以用报错注入:
updatexml(1,make_set(3,'~',(select database())),1)
依次爆库名 表名 字段名 值
可以发现 data的内容:
O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:20:"http://www.baidcu.com";}
数据库中是以序列化的形式存在,而最后回显在页面的时候是反序列化之后的,这里我们可以利用这个来触发反序列化漏洞
最后我们构造的payload:
/view.php?no=-1/**/union/**/select/**/1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:4:"test";s:3:"age";i:123;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
到这里,很多地方我们都是通过猜想和试,比如反序列化,和flag.php的存在
这里通过 robots.txt文件 可以发现部分源码泄露。
这个题目涉及的知识点很多,不是特别难,但是有一点综合性。还有很多细节地方,如果不注意,就写不出来了,比如data数据你构造的时候,在第4列,如果你写在其他地方了,很显然构造不出来。如果是黑盒测试,这个题目还是需要很多猜测和经验的。如果能拿到完整源码,可能做起来会更有目的性一点。SSRF的扩展性利用要了解。
unfinished
二次注入、数据库里面字符串长度的处理
进行注册之后登陆可以发现,注册时的用户名出现在了左侧:

可以发现 用户名显示在左边,怀疑有二次注入
先更正一个观点,insert into 语句那里是可以执行SQL语句的:

这里实际上是执行了select database() 然后执行结果再与0相加的。因为我们是要得到database()的结果,而结果一般是字母,字母+数字得出来是数字,所以我们需要转换一下用到hex()

还有一个问题,就是有的字符串经过hex()之后还是会带上字母,这个时候和0相加还是0,就得不到结果了,所以我们可以进行两次hex(),因为两次hex()之后 一定是是纯数字字符串。
然后在这个题目里面需要注意的是,两次hex()之后,数字是非常长的,所以只能通过截取,每次取10个这样来显示。
试验一下:

发现是可行的。因为web只有三个字母,两次hex也比较短,所以没有截取
最后附上脚本:

这里其实是投机取巧了一点,直接猜测表名是flag,并且flag在flag表里面。注意这里用的是 substr(str from digit for digit) 形式,substr(str,digit,digit) 行不通, 逗号被ban 了 。其实可以fuzz一下,到底ban了哪些函数,不知道这个可不可以系统的解(爆库,爆表名,爆字段名)或者盲注。
comment
git、二次注入、爆破、SQL语句读文件
通过提示发现这个题目有git泄露的(git相关的知识我还不是蛮懂,后面要了解学习),然后拿到这题的主要源代码

这个题目注入点在category这里,可以看出来,category一开始写到board表里面,并且对变量进行了转义,(这个不影响二次注入),后来是把board表的category拿出来,然后直接写到comment表里面,并且没有过滤。所以这里存在了二次注入。看一下过程,比如我在board插入的数据是:

然后我在comment 插入的数据是:

那么在 comment表里,实际上执行的语句是

注意这里是多行,所以用的是/* */,同时#是用来注释逗号的。最后user()结果存在了content字段里面,并被echo了出来,结果如下:

注入点找到了,基本上可以依靠这个思路爆库爆表爆字段名了。但是这个题目flag不在表里面。所以需要别的方法,这里是通过读取一系列系统的文件来找到flag的存在位置。
先读一下/etc/passwd文件,这里用到了load_file()函数,payload: ‘,content=(select load_file(‘/etc/passwd’)),/*

然后找到:

有一个www用户,可以读它的历史命令文件 payload:’,content=(select(load_file(‘/home/www/.bash_history’))),/*

发现有.DS_Store文件,这个考虑可能是docker环境,可能在/tmp/html文件下,然后读它。如果直接读:
‘,content=(select load_file(‘/tmp/html/.DS_Store’)),/* 这个会读出来乱码(可能是浏览器原因,因为有很多不可见字符,而且浏览器也只能显示这么一点东西。。

所以用hex转一下,’,content=(select hex(load_file(‘/tmp/html/.DS_Store’))),/*,然后在解密得到:

找到flag_8946e1ff1ee3e40f.php文件,然后读这个文件,这里是在 /var/www/html/下
最终的payload: ‘,content=(select(load_file(‘/var/www/html/flag_8946e1ff1ee3e40f.php’))),/*

涉及到SQL注入 比如二次注入,要依实际环境分析,比如这里的注入就很特别,不过我第一步估计就凉了,不懂git拿不到完整源码,这里留一个坑(git和docker)要了解,当sql的库表没有线索时,可以从系统文件找线索,以后实战也是。上次校赛的思路也是。Linux很重要。不得不说,整个题目还是综合性蛮大的。
Wafupload
没找到复现环境,只能学习一下知识点了。数组访问方式不同造成的漏洞
源代码

第8行 对上传文件类型进行了检测,容易bypass, 然后来到13 行,如果filename参数为空,那么$file变量的值等于上传的文件名,如果不为空,则取filename参数的值(filename参数是可控的,然后第14行判断,如果$file不是数组,就把它分成数组,如果是数组,这一步跳过,17行 end()函数 取数组尾项(也就是后缀名,然后18行进行判断,这些其实都没问题,重点就在后面22行,对这个文件进行了重新命名,并且使用了reset()和下标 这两种不同读取数组内容的方式,从而导致了漏洞。
举个例子 :

reset是指向第一个初始化的区域,这里第一次初始化的是 $hack[1],所以reset指向它,同理,end()指向最后一个初始化的。而$hack[]这种形式直接根据下标指向,这就可能会造成bug。
回到这个题,如果传参是这样的 filename[1]=’php’&filename[0]=’jpg’,那么end()就会指向jpg,从而绕过后缀检测,同时重命名的时候 reset()指向php ,$file[count($file)-1] 等效于$file[1]指向php,最后生成的文件名就是 php.php,就可以 getshell了。
sqlweb
一开始有个登陆界面,这里用弱密码进去了
admin admin123
然后给了提示 only wuyanzu can get the flag,因为是要以username为 wuyanzu的用户来登陆进去,但是我们不知道他的密码
这里给出了waf:
/sleep|benchmark|=|like|regexp|and|\|%|substr|union|\s+|group|floor|user|extractvalue|UpdateXml|ord|lpad|rpad|left|>|,|ascii/i !!! (trust me,no one can bypass it)
过滤了很多,这里我们用:
wuyanzu'/**/&&/**/mid(passwd/**/from/**/1/**/for/**/1)/**/in('f')
盲注脚本: 盲注三要素(字典、判断条件、特殊性到一般性的payload)
1 | import requests |
很多时候,不一定全部爆破出来 库 表 字段名 只要拿到关键的就OK了,有时候也是靠猜测。比如这里就是passwd。