Tornado+MySQL模擬SQL注入

實驗環境:
python 3.6 + Tornado 4.5 + MySQL 5.7html

實驗目的:
簡單模擬SQL注入,實現非法用戶的成功登陸python

先給一個SQL注入的圖解,圖片來自網絡:mysql

 

1、搭建環境

一、服務端的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

2、模擬登陸

一、正常登陸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'

3、使用cursor.execute方式防止注入

使用字符串拼接的方式會致使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''

完!

相關文章
相關標籤/搜索