本文共 2817 字,大约阅读时间需要 9 分钟。
SQL注入
是一种代码注入技术,过去常常用于攻击数据驱动性的应用,比如将恶意的SQL代码注入到特定字段用于实施拖库攻击等。
SQL注入
的成功必须借助应用程序的安全漏洞,例如用户输入没有经过正确地过滤(针对某些特定字符串)或者没有特别强调类型的时候,都容易造成异常地执行SQL语句。
SQL注入
是网站渗透中最常用的攻击技术,但是其实SQL注入可以用来攻击所有的SQL数据库。
创建SQLdb
数据库
CREATE DATABASE SQLdb;
创建user_info
表
1 2 3 4 5 6 | CREATE TABLE `user_info` ( ` id ` int ( 11 ) NOT NULL AUTO_INCREMENT, `username` varchar( 32 ) DEFAULT NULL, `password` varchar( 32 ) DEFAULT NULL, PRIMARY KEY (` id `) ) ENGINE = InnoDB DEFAULT CHARSET = utf8; |
插入一条用户数据
测试的用户名是ansheng
,密码as
1 | insert into user_info(username,password) values( "ansheng" , "as" ); |
Python代码
app.py
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.ioloop import tornado.web import pymysql class LoginHandler(tornado.web.RequestHandler): def get( self , * args, * * kwargs): self .render( 'login.html' ) def post( self , * args, * * kwargs): username = self .get_argument( 'username' , None ) pwd = self .get_argument( 'pwd' , None ) conn = pymysql.connect(host = '127.0.0.1' , port = 3306 , user = 'root' , passwd = 'as' , db = 'sqldb' ) cursor = conn.cursor() temp = "select username from user_info where username='%s' and password = '%s'" % (username, pwd,) effect_row = cursor.execute(temp) result = cursor.fetchone() conn.commit() cursor.close() conn.close() if result: self .write( '登录成功' ) else : self .write( '登录失败' ) application = tornado.web.Application([ (r "/login" , LoginHandler), ]) if __name__ = = "__main__" : application.listen( 8888 ) tornado.ioloop.IOLoop.instance().start() |
HTML代码
login.html
与app.py
文件在同级
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> <form action = "/login" method = "post" > < input type = "text" name = "username" placeholder = "用户名" / > < input type = "text" name = "pwd" placeholder = "密码" / > < input type = "submit" / > < / form> < / body> < / html> |
演示效果
打开浏览器,输入地址http://127.0.0.1:8888/login
填写内容如下:
用户名:asas ' or 1 = 1-- asd
随便填写一串字母
如图:
当点击提交
的时候是否会跳转到登陆成功页面?如果你的代码和我一样,那么就会跳转到登陆成页面
。
出现这个问题的主要原因就是因为我们使用了字符串拼接
的方式来进行SQL指令的拼接。
SQL指令拼接代码
1 | temp = "select username from user_info where username='%s' and password = '%s'" % (username, pwd,) |
这是一个正常的SQL拼接出来的结果
1 | select username from user_info where username = 'ansheng' and password = 'as' |
这是一个非正常的SQL拼接出来的结果
select username from user_info where username='asas' or 1 = 1 -- asd' and password = 's'
聪明的你是否已经看到其中的玄机了呢?--
通过Python
的pymysql
模块来进行SQL
的执行,在pymysql
模块内部会自动把”'
“(单引号做一个特殊的处理,来预防上述的错误
1 2 3 | ...... effect_row = cursor.execute( "select username from user_info where username='%s' and password = '%s'" , (username, pwd)) ...... |