Sql注入学习笔记(一) SQL 约束攻击
这是本菜鸡在bugctf上遇到的一道SQL注入题,也是我遇上的新知识,写下来学习一波
利用场景
常见于web开发者没有在期望具有唯一性的那些列(例如用户名)添加UNIQUE约束且将数据库设置成宽松模式(ps:在这种模式下插入数据如果不符合定义类型或长度,对数据类型调整或截断保存并警告),使得该列的字段值有出现重复的可能性。所以就造成了虽然对sql注入有严格的过滤,但是依然给予了攻击者机会
原理分析
首先要理解的是,在SQL中执行字符串处理时,字符串末尾的空格符将会被删除。所以查询”user “时等同于查询”user”. 例如
SELECT \* FROM users where user = "f1rry";
SELECT \* FROM users where user = "f1rry "
两句等效
但也存在异常情况,最好的例子就是LIKE子句了。注意,对尾部空白符的这种修剪操作,主要是在字符串比较期间进行的。这是因为,SQL会在内部使用空格来填充字符串,以便在比较之前使其它们的长度保持一致。在所有的INSERT查询中,SQL都会根据varchar(n)来限制字符串的最大长度。也就是说,如果字符串的长度大于n个字符的话,那么仅使用字符串的前n个字符。比如特定列的长度约束为5个字符,那么在插入字符串”username”时,实际上只能插入字符串的前5个字符,即”usern”。
所以如果假设一个字段的长度限制为10,那么当你执行
INSERT INTO users value('f1rry 1','123456')
由于长度限制为10,所以后面的1被截断,且在执行时空格被忽略,此时当表中还存有令一名id为f1rry的用户,就会造成数据表中含有2个f1rry的现象
那么当查询时又会如何呢?数据库会返回最先存在于数据表中用户,这样你便可以登录其他用户的账号啦。
例如,已知一个名为admin的用户,但密码位置,此时你可以注册一个名为admin 1的用户,然后你便可以用你注册的密码登录该admin的用户了
附个实战题目
