gtxyzz

Tornado+MySQL模拟SQL注入

gtxyzz 优质云主机 2023-02-26 912浏览 0

实验环境:
python 3.6 + Tornado 4.5 + MySQL 5.7

实验目的:
简单模拟SQL注入,实现非法用户的成功登录

先给一个SQL注入的图解,图片来自网络:

Tornado+MySQL模拟SQL注入

 

一、搭建环境

1、服务端的tornado主程序app.py如下:

#!/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()

2、在template文件夹下,放入login.html文件:

<!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>

3、在shop数据库中建立userinfo数据表,并填入数据:

Tornado+MySQL模拟SQL注入

随便添加两条就好,明文就明文吧:

Tornado+MySQL模拟SQL注入

二、模拟登录

1、正常登录

Tornado+MySQL模拟SQL注入
Tornado+MySQL模拟SQL注入
Tornado+MySQL模拟SQL注入
Tornado+MySQL模拟SQL注入
以上都是“好用户”的正常登录,我们看一下“坏家伙”怎么做。

2、非法登录

密码不对也能登录:

Tornado+MySQL模拟SQL注入
Tornado+MySQL模拟SQL注入

看一下服务端执行的SQL语句,就不难理解了,密码部分被注释掉了:

select name from userinfo where name='dyan' -- n' and password='000'

账户密码都不对照样登录成功:

Tornado+MySQL模拟SQL注入
Tornado+MySQL模拟SQL注入

看执行的SQL语句:

select name from userinfo where name='badguy' or 1=1 -- y' and password='000'

三、使用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,))

再次尝试注入:

Tornado+MySQL模拟SQL注入
Tornado+MySQL模拟SQL注入

错误原因,巴拉巴拉就是语法不对:

ymysql.err.ProgrammingError: (1064, "You have an error in your SQL syntax;

看看内部执行的语句,主要是对'符号做了转义防止注入:

select name from userinfo where name=''dyan\' -- n'' and password=''123''

完!

继续浏览有关 数据库技术文章/教程 的文章
发表评论