3

后记:菠菜站点的攻克之旅

 2 years ago
source link: https://knightyun.github.io/2021/12/06/exploit-penetrate-bocai-website
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

后记:菠菜站点的攻克之旅

故事发生在上次事件(https://knightyun.github.io/2021/09/04/exploit-take-down-swindle-website)之后,算是作为一个收尾,但也算是另一个开始 (⌐■_■),顺便记录下相关操作;

上回故事说到,骗子服务器的最高权限虽然已经拿到,但这也只是技术层面的掌控,想要立案,需要提供尽量多的人员相关信息,如手机、银行卡等,但这些目前都并未采集到(前面虽然提到了某次源码有个银行账户,但后面发现那只是个测试号,百度出来一堆在用的…),所以还需要通过一些额外的手段去获取有用的信息;

首先想到的就是之前一直留着没进去的宝塔面板后台,里面应该会有些登录信息之类,但并没有得到登录密码,但这也并没有太大影响,因为现在可以直接访问宝塔的数据库文件(panel/data/default.dbsqlite数据库文件),所以直接进去备份个账户然后设置个密码,防止把正常账户挤下去:

cmd-change-baota-password
cmd-baota-backup-user

清理下日志,然后就是愉快的登录进去 ㄟ( ▔, ▔ )ㄏ:

front-baota-home

首先看到的就是账户名,想是管理员的手机号,这里看不全,去设置里面瞅瞅:

front-baota-lookup-phone-elements

这里也是中间四位打了星号,从源码里也看不出,但这些也都是纸老虎,因为随后审查发现一处接口请求数据,返回信息里是完整的手机号,微信搜了下也有这个这么个账户:

wechat-baota-phone

但其真实性未知,多半只是个幌子,先记着吧;

在之后某个时间点准备继续收集信息的时候,发现其域名甚至IP都无法再访问了,后面几天试了也都不行,感觉可能是收割完一波然受卷款跑路了;自然,除了一些信息,之前获取的所有权限,都化作泡影了;也是在这之后,警察蜀黍竟主动联系了过来(没有喝茶,俺是良民 $_$),由于想着再碰碰运气看看,结果有趣的事再次发生了,访问之前那个IP展示出了这么个页面:

front-user-login

好吧得承认,那一瞬间确实差点信了这标题和图标,还浪费了三秒考虑渗透它的正当性,仔细想想也知道,真要是那家银行,怎么会把服务器放到有前科的IP身上,页面内容也说不过去,然后简单注册了个账号登录进去:

front-user-home-1
front-user-home-2
front-user-home-3

=_= 好吧,来都来了,就是个顺手的事;下面的分析也印证了上面的猜想,这也算是个IP反查域名 的小技巧,因为正常的工具比如 nslookup, dig 只能从域名到IP进行解析(某些有 ptr 的除外),但是遇到这种有使用 https 的站点,如果没有限制IP直接访问的话,能够正常进入页面,并且在浏览器左上角点击协议名还能查看所使用的证书,正常的证书的“颁发给”的值就是站点的域名,这里显然不是,应该是个临时或者测试证书:

front-https-cert

然后反过来对域名分析一波:

cmd-nslookup-domain

这里发现通过公共DNS解析出来的IP,和前面用的好像对不上号,细想下,应该就是使用了 CDN服务,这些IP对应的服务器都是提供服务的三方机构的,渗透没太大意义,并且也不容易,这里辛亏是直接通过源站IP进入的,不然要通过域名和CDN检索出源站还是另一项头疼的活儿;

那么有了域名就来扫一波子域名,获取潜在的关联站:

cmd-enum-subdomain

还真有不少,先记着备用,随后从前台页面的返回数据里分析,发现这是一台使用 php 的 Linux 服务器,和之前的 Windows IIS 服务器不同,看来应该是域名被释放或转卖了,那么就从新扫波端口吧:

nmap-normal-scan

还是发现了一些熟悉的身影,依旧先后台跑着密码先吧,按以往的经验,遇到精明的主也许有漏网之鱼,所以还需要贴心的整套全端口扫描服务:

nmap-all-port-scan

还确实有,看协议大概能猜到是什么服务,挨个试试,发现一个是 ssh 登录,一个宝塔后台:

cmd-ssh-login
front-bt-login

宝塔依然有登录次数校验,爆破无望,只能先搁一边;

这次都还没来得及用上目录爆破,手打了几个就盲猜了出来后台路径,倒也省工夫勒:

front-admin-login-jump
front-admin-login

双赢?不存在的,只会是单方面的 ╮(╯_╰)╭,简单分析了会儿页面,这里就暂时不用祭出神器了,直接用 wfuzz 跑一波账户密码:

cmd-wfuzz-admin-login

先放后台跑着,去其他地方转转;一会儿后就看到了结果,哟西!进去瞅瞅:

front-admin-home
front-admin-products
front-admin-user-bank
front-admin-user-info
front-admin-user-charge

麻雀虽小五脏俱全,然后也有一些预料中的有意思的东西:

front-admin-user-withdraw
front-admin-risk-control

提现那个就不说了,能否成功全看管理员心情,下面那个看不太明白也没关系,可能道理大家也都懂,反正就那么个意思,你的命运我掌控,你的风险我操纵 (¬‿¬);

Get webshell

后面花了点时间,分析了下页面找到一处可利用的漏洞,然后传个小玩意上去:

front-backdoor-phpinfo

搞定,又到了亮剑的时刻:

ant-file-site-root

往上遍历目录发现确实不简单,出现了之前的某些域名,难道是小站群,后面花了好一段时间才稍微搞懂他们的架构,多个二级域名指向当前IP,并拥有几个不同的CDN地址,然后某个二级域名又指向另一台服务器IP,当前IP的服务器呢又包含了另一个一级域名对应的二级域名,这几个站点又几乎在共享同一套代码,=_= 真够复杂的,难道是业务拓展导致的计划不周么,不过着也不重要,对应到服务器就行;

ant-file-more-sites

然后就是访问 /etc/passwd 文件查看用户,因为这个文件在 Linux 中是所有用户可访问:

ant-file-passwd

都是些默认账户,由于当前是 www 账户,所以是没有访问 /etc/shadow 文件的权限的,这个文件记录的是系统所有账户的密码的 hash 值,所以后面步骤就是提权了;

在浏览系统目录的时候,发现了 phpMyAdmin 的登录地址,难怪之前没扫出,应该是宝塔里配置过,生成随机的复杂路径来校验访问入口:

ant-file-pma-path
front-pma-login

账户和密码就简单了,可通过某些手段获取,只是可惜对方并不是配置的 root 账户,而是一个子账户,用站点命名,应该是服务器有多站点的缘故,权限也不高,先登录进去看下:

front-pma-home

内部包含的是站点前后台的一些数据,先找下有用的信息:

front-pma-databases
front-pma-admin-pass-hash

有个表存的管理员的信息,额这个表名(bulamao)……难道又要开始考验我对博大的中国文化熟悉程度了吗,我认输了,有知道的小伙伴可以评论下;表里面有串密码的哈希值,先拿去查一下碰碰运气:

front-pma-admin-pass-text

居然还真有,小本本记下(后面确实为进入其他站点提供了依据);

浏览目录的时候也发现了一些精致的小玩意:

ant-file-backdoors
ant-code-backdoor-abcd-passwd
front-backdoor-abcd-login
front-backdoor-abcd-home
front-backdoor-adminer
front-backdoor-file-manage

地方不大,还挺热闹,对面都是大佬惹不起,似乎还有好几拨人,让它们安静的躺着,相爱相杀吧,俺啥都没看见 (x_x);

disable_functions 绕过

本来是准备打开虚拟终端愉快的研究如何提权的,结果开幕雷击:

ant-shell-error

不用说,多半一些系统执行函数被禁用了,就是 php 配置项中的 disable_functions 值,用于限制能在 php 脚本中执行系统命令的一些函数,当然也存在一些漏洞导致的绕过方法,途径不少,节约时间,就不挨个手工测试了,直接用现有的集成插件:

ant-plugin-disable-functions-menu
ant-plugin-disable-fun-1

看到 putenv 被禁用心就凉了半截,光这就能劝退大部分绕过方式了,不过还是得试试,因为还剩一个方法可用(php-fpm),通过查看系统配置文件发现,fpm 模块使用的 socket 通信方式,配置一下然后启动:

ant-plugin-disable-fun-2
ant-plugin-disable-fun-3
ant-plugin-disable-fun-start

最后提示都是成功,检查其生成的动态链接库文件也是成功上传的,但终端始终无法开启,一直提示返回数据为空,起始以为是插件用的某个函数也被 php 给禁用了导致返回为空,也找到不其他可利用的漏洞,为此还卡了大半周的时间,后来准备查查资料,手动把利用方法实现一遍;

其实该方法的原理大致就是:php 是一门动态语言,但 nginx 是无法处理这些的,所以中间还有个 fastcgi 协议在牵线搭桥,可类比 HTTP 协议,nginx 将接受到的客户端请求转换成 fastcgi 协议格式的数据,而 php 模块中的 php-fpm 就是用来处理这些 fastcgi 协议数据的,然后再传给 php 解释器去处理,完成后结果数据又以之前同样的路径返回到浏览器客户端;所以一般在 Linux 服务器上启动 php 程序,都会启动一个叫 php-fpm 的服务,一般会监听本机的 9000 端口,或者套接字文件,nginx 的配置文件 fastcgi 访问地址也配成这个端口或文件,这些都是为了完成上述通信过程;

这里面可利用的点就是,绕过通往 nginx 的请求,直接与 php-fpm 服务沟通,理想情况就是由于配置失误导致 9000 监听在了外网接口而不是本机接口,当然这种情况也是极少数,但这也并不意味着监听本机就无法利用了,在 php 程序文件可写的前提下,可以在程序中通过 curl 接口向服务器本机 9000 端口发起请求(或 stream_socket_client 发起套接字文件通信请求),并且是模仿 fastcgi 客户端发送对应格式的数据,这样就能实现绕过 nginx 直接与 php-fpm 沟通;这种操作还有另一种说法,叫 SSRFServer-Side Request Forgery),即服务端请求伪造,通过服务器去实现访问客户端正常不能访问到的内网资源;当然还有一个和他名字很像的手段: CSRFCross-Site Request Forgery,跨站请求伪造),只不过这个是盗用其他客户端的登录凭证;

可能这里还有个问题,这样绕了一圈去建立通信,最后不是还是会通过 php-fpm 吗,这样配置的函数限制依然存在,其实不然,直接和 php-fpm 沟通的话,它是支持修改 php 配置的,就是 fastcgi 协议中的 PHP_VALUE, PHP_ADMIN_VALUE 这两个参数,比如可以设置这两个配置:

"PHP_VALUE": "auto_prepend_file = php://input"
"PHP_ADMIN_VALUE": "allow_url_include = On"

这会导致执行 php 程序之前包含 HTTPPOST 的数据,实现任意代码执行的目的,但即使这样也还是不行,因为这里的任意代码执行依然逃不开 php 配置文件的控制,所以就还需要更进一层,可以利用 extension 这个环境变量,设置执行脚本是要引入的动态链接库文件(Linux 下是 .so,Windows 下是 .dll):

"PHP_VALUE": "extension = /xxx/xxx.so"

这就需要有任意文件上传权限,不过都开始研究限制绕过了,这点权限是肯定有的,然后就是编译构造自己的 .so 文件,并向其中添加要执行的系统命令,这样链接库文件在被引入的时候就会执行预定的命令,同时也不受 php 配置文件的限制;这个sao操作也是在研究那个插件代码时发现的 (¬‿¬),同时也通过抓包找到了之前一直返回空数据的原因:

fiddler-ant-fpm-request

原来插件一直在站点根目录读取配置的后门程序,之前为了掩人耳目是塞到了一个隐蔽的深层目录,所以一直获取不到数据返回空,也算是自己的配置失误,就是这里需要配置为后门程序所在目录:

ant-plugin-disable-fun-4

远程指令执行

目前虽然可以通过插件绕过 disable_functions 并正常使用虚拟终端,但后续并不打算这么做,插件的机理其实就是通过包含 .so 时执行里面插入的指令,查看生成的 .so 文件可以看到插入了这样一条命令:

cmd-hexedit-ant-so

其实就是利用远程指令执行运行了另一个 php 服务,自定义了端口,并且 -n 参数是不使用 php 配置文件的意思,这样就实现了绕过 disable_functions,方便让其他程序畅通无阻的运行虚拟终端,手段确实有趣,不过这里就大可不必了,都能执行命令了还要虚拟终端干啥,另外经过测试也发现这样连接有一定时效性,大概一分钟左右就会断开连接,原因未知,所以为了后续更愉快的玩耍,直接上 msf payload,生成 elf-so 格式的文件后上传站点,然后把自定义的 fastcgi 客户端(https://gist.github.com/phith0n/9615e2420f31048f7e30f3937356cf75)参数改下,让包含的 .so 文件为我们的 payload 文件以使其运行:

cmd-edit-fpm-py

运行后就会得到构造后的 fastcgi 协议数据(TCP数据流),让服务器 php 发送它就好,所以还需要服务端写个 php 程序来配合发送,这是使用使用套接字文件通信时的文件内容:

<?php
ini_set("display_errors", "On");
error_reporting(E_ALL);

$fp = stream_socket_client("unix:///tmp/php-cgi-56.sock", $errno, $errstr, 30);
$url = $_GET['url'];

if (!$fp) {
    echo "Errno: " . "$errstr ($errno)<br />\n";
} else {
    try {
        fwrite($fp, base64_decode($url));
        var_dump(fread($fp, 8192));
    } catch (Exception $e) {
        print_r($e);
    }
    fclose($fp);
}

如果是监听本地 9000 端口,可以使用 fsockopen 协议来发送 fastcgi 协议数据,具体就是:

<?php
ini_set("display_errors", "On");
error_reporting(E_ALL);

$fp = fsockopen("127.0.0.1", 9000, $errno, $errstr, 30);
$url = $_GET['url'];

if (!$fp) {
    echo "Error: $errstr ($errno)<br />\n";
} else {
	try {
	    fwrite($fp, base64_decode($_GET['url']));
		var_dump(fread($fp, 8192));
	} catch (Exception $e) {
		print_r($e);
	}
    fclose($fp);
}

然后打开 msfconsole 开启反向连接监听:

msf-listen-reverse-tcp

然后本地用浏览器访问一下服务器中的发送 fastcgi 的 php 程序,并凭借上要发送的数据:

front-msf-reverse-link

正常情况页面会持续加载中,然后 msf 这边就会收到连接请求并进入 meterpreter shell,然后看一下系统信息,nice,直接进入 shell 进行下一步操作:

msf-meter-sysinfo

因为之前说这里的 php 建立的连接只有不到一分钟时间,.so 文件执行的指令也不例外,所以这里就到了争分夺秒考验手速的时刻了,先断开连接待会重来,然后这次需要准备第二个 payload 传到同目录下,为了节省时间可以在第一次连接前以后台任务运行(run -jmeterpreter 反向监听,这样就不会浪费时间再去切换 module 和设置 payload 再运行了:

msf-run-meter-job

在网页请求后建立第一个 payload 连接,然后迅速进入 shell 执行一个 nohup 后台任务来运行刚才上传的第二个 payload

msf-link-payload-2

不出意外第二个 payload 的监听任务就会建立连接,并且是持续的长连接,第一个连接关掉也无所谓,后面就能愉快地进行其他操作了 (ง •_•)ง

Linux 提权(Privilege Escalation)

前面虽然已花了不少时间,但还没到达最关键的一步,现在才是重头戏,并且也不会太轻松,毕竟这是 Linux 系统,不同于 windows,版本和补丁数量不是特别高的话,提权漏洞一抓一把(这方面也稍微印证了 Linux 系统较于 Windows 更安全),少归少,不至于没有,只能逐个尝试;

Sudo Baron Samedit(cve-2021-3156)

记得今年(2021)年初正好报了一个 Linux sudo 程序的提权漏洞,正好试下:

msf-shell-check-baron-samedit

感觉有戏,下个 exp 上传手动跑下试试:

msf-shell-exploit-baron-samedit

最后似乎不行,再用 msf exploit 试试:

msf-run-baron-samedit

等了十几分钟,最后依然失败,这条路应该是行不通了;

Local Exploit Suggester

这里使用一下这款本地提权建议工具,它会自动获取相关系统信息并提供一些可利用的漏洞建议:

msf-local-exploit-suggester

可以看到列举出了不少存在可能性的 exp,再去挨个尝试下,结果,也全部无效,心又凉了小半截;

Suid 提权

简单说 suid 是一种权限,它运行具有该权限的文件执行时,能以该文件所有者的权限执行,例如具有所有用户读写执行的文件权限是 rwxrwxrwx,那么它再具有 suid 权限就会是 rwsrwxrwx (第三位是 s),权限码就是 4777,这里可利用的地方就是,假如某个文件所有者是 root 账户,并且其他用户可执行,那么其他用户在执行时,就间接有了 root 权限;

例如利用 find 提权执行 whoami 就是:

find some-file -exec whoami

可以先查找一下全系统就有该权限特征的文件:

find / -user root -perm -4000 -type f 2>/dev/null
msf-shell-find-suid

虽然有不少但是没有找到可利用的,常见的可利用程序和利用参数大致有(执行高权限的文件或查看高权限文件内容):

find
cp
nmap
vim
vi
bash
more
less
nano
zip
tar
mv
man
chmod
ash
awk
python
perl
tcpdump
date
time
cpulimit

crontab 任务

利用定时任务(cron)漏洞也是一种思路,假如存在会被定时执行的脚本文件,并且该文件又可写,就可以让其到达时间后执行任意命令;不过检查了一遍,都没有找到可利用的文件;

ant-file-cron-jobs

宝塔 CSRF

在一度没辙的时候,把方向转向了之前备份下载的站点源码,分析的时候发现有个日志输出目录,看着输出日志信息都比较详细,就尝试着全局搜一下请求数据之类的,看有没有账户密码或 cookies 数据,结果就找到了几处宝塔相关的登录凭证:

code-runtime-log-bt-token

但这些凭证的时间都很靠前,应该都失效了,而且在用自己的宝塔服务测试时发现,出了会话 cookie 时效为 2 小时外,软件似乎也对 csrf 这类漏洞做了限制,比如某个账户在一台电脑登录后,直接拿到浏览器存储的 cookie 信息然后放到另一台电脑中去伪造访问,不仅伪造的机子无法登录,原登录的机子也会自动退出登录;不过在分析时发现了另外一处 cookie 信息,里面似乎包含了宝塔面板的一些信息:

code-bt-cookies

拿去解码分析下,发现有个隐藏四位的手机号,应该是面板的登录账户名,先留着也许后面有用:

front-urldecode-bt-info

mysql 提权

目前来看这条路希望不大,前面提到不同站点使用不同的 mysql 子账户,且分配的权限较低,连 dumpfile 这样的指令也执行不了,更不用说 UDF 这类提权操作了,也对 root 账户进行过密码爆破,都没有收获;想起之前不是拿到一个宝塔的手机号嘛,说不准会用手机作为账户密码,虽然隐藏四位,但无关紧要,总共才一万种可能,直接拿 crunch 生成一个字典然后拿去 hydra 跑一下 root 密码:

cmd-hydra-pma-phone

虽然跑完也没花多少时间,但结果证明一个也不是,猜想失败;

Dirty Cow

后续没更多思路时,查了会资料,准备再试下经典的 Dirty Cow 提权漏洞:

msf-priv-dirty-cow

然后尴尬的事就发生了,执行了一段时间 exp 后,服务器就突然报错断开了,然后 IP 就一直超时再也连不上了,这个 Kernel panic ,也就是 Linux 系统的致命错误,如果没记错的话无限近似于 Windows 系统中断或蓝屏(难道不经意间让 exp 升级为 DOS 了……),当然也可能是运气不好对方又关站跑路了,那么就先这样吧,指不定后面谁又接盘了 (T_T);

鉴于这次攻克过于棘手,所以过程中曾对机器的所在网段进行过扫描,然后不小心拿下一台业务类似的,和这次的目标在同一网关管辖下,所以先后台嗅探着数据吧,后面有时间再看看收获;

msf-shell-c-sniff

惯例的总结时间,这个就没说啥的了,如果是诈骗是被动诱捕,那么这个就是主动投敌了,不要过分相信别人私下写的代码再呈现给你看的东西,即使它看起来是那样的真实,你所看到的只不过是对方想让你看到的罢了,对方既是规则的执行者也是制定者以及违背者。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK