实验环境:
python 3.6 + Tornado 4.5 + MySQL 5.7html
实验目的:
简单模拟SQL注入,实现非法用户的成功登陆python
先给一个SQL注入的图解,图片来自网络:mysql
一、服务端的tornado主程序app.py以下:web
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import tornado.ioloop import tornado.web import pymysql class LoginHandler(tornado.web.RequestHandler): def get(self): 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='123456', db='shop') cursor = conn.cursor() # %s 要加上'' 不然会出现KeyboardInterrupt的错误 temp = "select name from userinfo where name='%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('登陆失败!') settings = { 'template_path':'template', } application = tornado.web.Application([ (r"/login", LoginHandler), ],**settings) if __name__ == "__main__": application.listen(8000) tornado.ioloop.IOLoop.instance().start()
二、在template文件夹下,放入login.html文件:sql
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="post" action="/login"> <input type="text" name="username" placeholder="用户名"/> <input type="text" name="pwd" placeholder="密码"/> <input type="submit" value="提交" /> </form> </body> </html>
三、在shop数据库中创建userinfo数据表,并填入数据:数据库
网络
随便添加两条就好,明文就明文吧:app
tornado
一、正常登陆oop




以上都是“好用户”的正常登陆,咱们看一下“坏家伙”怎么作。
二、非法登陆
密码不对也能登陆:


看一下服务端执行的SQL语句,就不难理解了,密码部分被注释掉了:
select name from userinfo where name='dyan' -- n' and password='000'
帐户密码都不对照样登陆成功:


看执行的SQL语句:
select name from userinfo where name='badguy' or 1=1 -- y' and password='000'
使用字符串拼接的方式会致使SQL注入。在cursor.execute方法中对'
致使注入的符号作了转义。
将app.py中下面两行代码改成:
# 致使SQL注入 temp = "select name from userinfo where name='%s' and password='%s'" % (username, pwd) effect_row = cursor.execute(temp)
# 防止SQL注入 effect_row = cursor.execute("select name from userinfo where name='%s' and password='%s'",(username, pwd,))
再次尝试注入:


错误缘由,巴拉巴拉就是语法不对:
ymysql.err.ProgrammingError: (1064, "You have an error in your SQL syntax;
看看内部执行的语句,主要是对'
符号作了转义防止注入:
select name from userinfo where name=''dyan\' -- n'' and password=''123''
完!