sql注入靶场搭建

Published on
44

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数据如下,仅供参考:
image-gxje.png

2、接口实现

使用的是FastApi框架。一款很好用的异步WEB应用框架;
sql客户端库使用SQLAlchemypymysql
采用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

上述代码目录层级如下:

image-osix.png

4、接口文档

本靶场写了两个get查询接口:

1、存在sql注入的接口:

get
http://127.0.0.1:8000/query

请求数据

名称类型必填描述
usernamestringtrue用户名称

响应:
{
"statu": "success",
"code": 200,
"data": {
"age": 18,
"username": "admin",
"address": "陕西西安市01广场"
}
}

2、使用ORM,不存在sql注入的接口:

get
http://127.0.0.1:8000/queryBetter

请求数据

名称类型必填描述
usernamestringtrue用户名称