sql注入靶场搭建
sql注入靶场部署
1、建库、建表
库的话根据实际情况选择,我是放在了自己的blog库,建表语句如下:
-- blog.SQLInject definition
CREATE TABLE `SQLInject` (
`id` int NOT NULL AUTO_INCREMENT,
`username` char(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL,
`password` char(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL,
`createTime` datetime DEFAULT NULL,
`age` int DEFAULT NULL,
`address` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
fake数据如下,仅供参考:
2、接口实现
使用的是FastApi框架。一款很好用的异步WEB应用框架;
sql客户端库使用SQLAlchemy
和 pymysql
;
采用uvicorn的方式启动;
安装如下依赖:
pip install fastapi uvicorn[standard] sqlalchemy pymysql
- 配置数据库连接🔗:
# database.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
import pymysql
# 使用pymsql,原生sql的方式。
# 创建连接
conn = pymysql.connect(host='116.xxx.xxx.xxx',port=3306,user='xxx',passwd='xxxx',db='blog')
# 使用sqlalchemy,ORM方式执行sql
# 创建连接
DATABASE_URL = "mysql+pymysql://user:passwd@116.xxx.xxx.xxx:xxx/blog"
engine = create_engine(DATABASE_URL, echo=True, future=True) # echo=True 打印SQL语句,调试用
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
- 编写数据库模型
# sqlModel.py
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
Base = declarative_base()
class SQLInject(Base):
__tablename__ = 'SQLInject'
id = Column(String, primary_key=True)
username = Column(String)
age = Column(String)
address = Column(String)
# 确保你的模型反映了数据库中的实际表结构
- 编写FastAPI接口
# main.py
from fastapi import FastAPI, HTTPException
from typing import List
from database import *
from sqlModel import *
import uvicorn
from sqlalchemy import Column, Integer, String
app = FastAPI()
@app.get("/queryBetter/")
async def read_items(username):
# 注意:这里我们使用了一个简单的同步方式,对于生产环境,请考虑使用异步数据库库
db = SessionLocal()
try:
items = db.query(SQLInject).filter(SQLInject.username == username).all()
print(items)
db.close()
return [{"username": item.username,"age": item.age,"address":item.address} for item in items]
except Exception as e:
db.rollback()
db.close()
raise HTTPException(status_code=500, detail=str(e))
@app.get("/query/")
async def get_items(username:str):
mycursor = conn.cursor(pymysql.cursors.DictCursor)
try:
mycursor.execute(f"select age,username,address from SQLInject where username = '{username}' ")
return {"statu":"success","code":200,"data": mycursor.fetchone()}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# return {"statu":"fail","code":500,"errorMessage":"服务器内部异常"}
finally:
mycursor.close()
if __name__ == "__main__":
uvicorn.run(app="main:app", host="127.0.0.1", port=8000, reload=True)
3、运行
因为cmd执行,或者编辑器执行时候,如果更改后,热启动会卡顿。所以编写了一个bat脚本,方便执行:
@echo off
setlocal
echo 正在查找并结束所有Python进程...
for /f "tokens=2" %%i in ('tasklist /fi "imagename eq python.exe" ^| findstr /r /c:"python\.exe"') do (
echo 发现Python进程,PID为:%%i
taskkill /F /PID %%i
)
echo 所有Python进程已结束。
python main.py
pause
endlocal
上述代码目录层级如下:
4、接口文档
本靶场写了两个get查询接口:
1、存在sql注入的接口:
请求数据
名称 | 类型 | 必填 | 描述 |
---|---|---|---|
username | string | true | 用户名称 |
响应:
{
"statu": "success",
"code": 200,
"data": {
"age": 18,
"username": "admin",
"address": "陕西西安市01广场"
}
}
2、使用ORM,不存在sql注入的接口:
请求数据
名称 | 类型 | 必填 | 描述 |
---|---|---|---|
username | string | true | 用户名称 |