SQL注入进阶练习(一)一些进阶的注入方法

您所在的位置:网站首页 sql注入盲注类型 SQL注入进阶练习(一)一些进阶的注入方法

SQL注入进阶练习(一)一些进阶的注入方法

2023-03-15 17:45| 来源: 网络整理| 查看: 265

SQL注入进阶练习 1. 二次注入1.1 概念1.2 sqllabs less-241.2.1 利用示例1.2.2 原理剖析 1.3 网鼎杯2018 二次注入1.3.1 环境搭建1.3.2 解题思路1.3.2.1 寻找源码 - git泄露数据恢复1.git是啥2.获取源码泄露的数据 1.3.2.2 源码分析1.3.2.3 爆破登陆密码1.3.2.4 实施二次注入获取flag 1.3.3 总结 2. 宽字节注入2.1 概念2.2 sqllabs less-332.3 字符编码引发的SQL注入问题2.3.1 环境搭建2.3.2 宽字节注入2.3.3 GB2312与GBK的不同2.3.4 mysql_real_escape_string 作为解决方案2.3.5 宽字符注入的修复2.3.6 iconv导致的致命后果2.3.7 小结 3. order by 注入3.1 什么是order by 以及order by 注入3.2 注入类型的判断3.3 注入方式3.3.1 union联合查询3.3.2 基于if语句的盲注(数字型)3.3.3 基于时间的盲注 --- 无列名3.3.4 基于rand()的盲注(数字型)--- 无列名3.3.5 报错注入 3.4 总结 4. limit 注入5. 总结 SQL注入的分类虽然大体上只有我们之前提到的那么几类,但真实的环境中又有一些"别样的“注入方案。例如二次注入、宽字节注入、order by注入、limit 注入。这些注入方式虽然不便于严格的按照分类进行划分,但是仅凭借着知名度就已经耳熟能详了。

本文将通过sqllab的一些例子以及部分CTF比赛试题,来对这几类注入方案进行一个详细的总结。

1. 二次注入 1.1 概念

二次注入可以理解为,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入。防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当Web程序调用存储在数据库中的恶意数据并执行SQL查询时,就发生了SQL二次注入。

作者:Ackerzy 链接:https://www.jianshu.com/p/3fe7904683ac

这一点其实还是和存储型XSS的攻击原理有些相似的,下main是一张攻击原理图,当然也是借用上面这位兄弟的。

在这里插入图片描述

下面我们就通过两个例子来对它进行演示。

1.2 sqllabs less-24 1.2.1 利用示例

我们先进行一波示例来看一看此类注入的利用方式。

我们先到注册界面注册一个账号:

username:user1 password:123123 username:user1'# password:123123

在这里插入图片描述 我们登陆user1'#账号修改其密码为123456 在这里插入图片描述 测试直接使用123456登陆user1的账号 在这里插入图片描述

登陆成功

在这里插入图片描述

1.2.2 原理剖析

但从上面的现象上我们能看出,我们新建了一个特殊名字的用户,在修改密码的时候修改了目标账号的密码。获取目标的账号。那么我们输入的单引号与注释符为什么没有在第一次进入数据库的时候生效,反而在我们进行密码修改的时候生效了呢?

我们需要对其部分源码进行分析才能解释这一现象:

在这里插入图片描述

我们看到页面中程序的主要功能就是登陆,新建用户,密码修改。我们主页面查看源码:

#登陆页面 function sqllogin(){ #调用了mysql_real_escape_string函数进行了参数过滤 $username = mysql_real_escape_string($_POST["login_user"]); $password = mysql_real_escape_string($_POST["login_password"]); $sql = "SELECT * FROM users WHERE username='$username' and password='$password'"; $res = mysql_query($sql) or die('You tried to be real smart, Try harder!!!! :( '); $row = mysql_fetch_row($res); //print_r($row) ; if ($row[1]) { return $row[1]; } else { return 0; } }

关于过滤函数的解释: 在这里插入图片描述 我们再次查看注册部分的功能代码:

//$username= $_POST['username'] ; $username= mysql_escape_string($_POST['username']) ; $pass= mysql_escape_string($_POST['password']); $re_pass= mysql_escape_string($_POST['re_password']); echo ""; $sql = "select count(*) from users where username='$username'"; $res = mysql_query($sql) or die('You tried to be smart, Try harder!!!! :( '); $row = mysql_fetch_row($res);

依然进行了过滤,直到我们查看我们的密码修改功能实现源代码:

if (isset($_POST['submit'])) { #从session中取出用户名,注意这里不加任何过滤 $username= $_SESSION["username"]; $curr_pass= mysql_real_escape_string($_POST['current_password']); $pass= mysql_real_escape_string($_POST['password']); $re_pass= mysql_real_escape_string($_POST['re_password']); if($pass==$re_pass) { #直接使用uodate进行数据的修改,也就是说我们的恶意用户名在此处会被带入语句执行 #恶意修改正常用户的密码,造成账号泄露 $sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' "; $res = mysql_query($sql) or die('You tried to be smart, Try harder!!!! :( '); $row = mysql_affected_rows(); echo ''; echo ''; if($row==1) { echo "Password successfully updated"; } else { header('Location: failed.php'); //echo 'You tried to be smart, Try harder!!!! :( '; } } else { echo ''; echo "Make sure New Password and Retype Password fields have same value"; header('refresh:2, url=index.php'); } } ?>

看到这里大概就已经清晰了,我们第一次注册账号存入的数据被转义,从而无法在登陆或者创建账号的过程中引发注入。但是我们再次从数据库中取出对应数据的时候,并未对其进行再次转义,导致取出了单引号一类的恶意字符。引发二次SQL注入。

这里还有一个疑点就是mysql_real_escape_string函数的生效时间,它的转义持续时间明显是没有超过数据库入库的。也就是说,仅仅在程序执行的时候我们的敏感字符会被转义,而最终存储到数据库内部的字符还是如先前一样没有任何过滤措施。我们查看数据库内的信息就可以看到:

在这里插入图片描述 所以才会出现我们的敏感字符再次从数据库取出来的时候依然生效引发了二次SQL注入。

到了这里,二次注入的原理就十分清晰了,从数据库取出的用户输入,同样具有危险性。

1.3 网鼎杯2018 二次注入 1.3.1 环境搭建

这道题的环境我们需要到github上面进行拉取。 git网站位置:https://github.com/CTFTraining/wdb_2018_comment

#1.将文件解压到服务器上边 [root@blackstone batman]# unzip wdb_2018_comment-master.zip #2.修改该docker配置文件中的yml文件监听所有IP地址(否则外网无法访问) [root@blackstone wdb_2018_comment-master]# cat docker-compose.yml # 网鼎杯 2018 Comment version: "2" services: web: image: ctftraining/wdb_2018_comment restart: always ports: - "0.0.0.0:8307:80" environment: - FLAG=flag{flag_test} #3.启动docker环境 [root@blackstone wdb_2018_comment-master]# docker-compose up -d

访问目标网址的8307端口看到留言板的界面就算环境搭建成功了。

在这里插入图片描述

1.3.2 解题思路

大体的思路就是通过目录扫描器看一看目标站点是否存在git泄露问题。当我们拿到目标站点的部分源码时可以通过对源码的代码审计获取目标站点的一些漏洞信息。或许能找到可供我们利用的漏洞点。

我们先使用dirsearch对目标站点进行目录扫描:

┌──(root💀kali)-[~] └─# dirsearch -u http://192.168.2.169:8307

在这里插入图片描述 存在.git开头的文件,我们可以通过相应的工具拉取目标站点的git泄露数据。

1.3.2.1 寻找源码 - git泄露数据恢复 1.git是啥

Git(读音为/gɪt/)是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。 [1] 也是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。

以下内容又来自一个开发朋友,后面我也会加强对这部分的学习。毕竟git还是十分有用的一款多人开发版本控制工具。

对于git工具来说我们入门理解的话需要搞清楚以下三个概念: 工作区、保存区、推送区、 工作区就是目前你正在写的代码文件存在的地方,也是你的工作目录。一天工作完成了,保存到保存区,相当于一个备份,同时会给你提交的这个版本打上一个标签,是唯一的,方便你回滚。完成一段时间的工作后,你觉得没问题了,可以在保存区里选择你的版本(一般都是最新版),推送到github仓库。相当于发布了。这是个人用户的基础功能,当然它很智能,更重要的是多人协作。 咱两共同管理github一个仓库,各自负责一个模块,你完成一天的工作后push到仓库,第二天早上我pull一下就能把你写的那一部分更新到我的本地

2.获取源码泄露的数据

既然已经确定了是git数据泄露,那我们自然就需要远程把目标的泄露文件给请求到本地,进行进一步的分析。那么此时我们就需要使用一些工具来完成这一操作了。

githacker工具的获取:

#1.克隆github仓库至本地 git clone https://github.com/wangyihang/GitHacker.git #2.安装依赖,并安装githacker --- 注意进入到对应目录里面去 ┌──(root💀kali)-[~/tools/GitHacker-master] └─# python3 -m pip install -i https://pypi.org/simple/ GitHacker #3.使用方法直接进入文件目录输入以下命令 --- 具体进阶操作可以看git上的解释 ┌──(root💀kali)-[~/tools/GitHacker-master] └─# githacker --url http://192.168.2.169:8307/.git/ --output-folder result

在这里插入图片描述

此时我们进入对应文件夹内就可以访问泄露的git源代码了:

┌──(root💀kali)-[~/tools/GitHacker-master/result/76023a72314fd5e7c3b8a69e9ce3c64c] └─# ll -a total 16 drwxr-xr-x 3 root root 4096 Mar 6 05:06 . drwxr-xr-x 3 root root 4096 Mar 6 05:06 .. drwxr-xr-x 8 root root 4096 Mar 6 05:06 .git -rwxr-xr-x 1 root root 324 Mar 6 05:06 write_do.php ┌──(root💀kali)-[~/tools/GitHacker-master/result/76023a72314fd5e7c3b8a69e9ce3c64c] └─# cat write_do.php switch ($_GET['do']) { case 'write': break; case 'comment': break; default: header("Location: ./index.php"); } } else{ header("Location: ./index.php"); } ?>

很可惜,这里的php文件看起来就像是残缺品,看不到敏感信息(拼接的SQL语句信息),显然到这里就没了思绪,我们再次查看网页源码,发现有一点小提示:

在这里插入图片描述 commmit是git使用中的一条命令,其作用在于将本地的修改保存到仓库中,也就是说,由于程序员的一些操作没有进行commit,故我们就无法在显示出来的文件中看到修改的全貌。我们可以使用git工具帮我们解决信息不全的问题。

一点点小知识:

Q:git推送和提交的区别是什么? 1、推送(push):把您本地仓库的代码推送至服务器,将本地库中的最新信息发送给远程库。提交(commit):把您做的修改,保存到本地仓库中,将本地修改过的文件提交到本地库中。 2、git commit操作的是本地库,git push操作的是远程库。

数据恢复方案:

#1.使用 git log --reflog 命令,查看分支提交历史,确认需要回退的版本 #2.使用 git reset --hard commit_id 命令,进行版本回退

我们尝试进行版本回退:

在这里插入图片描述

1.3.2.2 源码分析


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3