實驗環境:
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''
完!