您的位置:首页 > 其它

0ctf-2015-final:foodie

2015-05-04 15:01 239 查看
感谢0ops为我们带来的攻防盛宴,第一天我们的分数增长的很快,首先是ling牛拿下了PM的首杀,并且机智地没有攻击217和蓝莲花=0=没想到流量很快地被其他团队重现了并打到了蓝莲花那里,不过patch了之后没有一直丢分,算是一个稳定的增长点。217的大牛让我等水队的0cms一直非挂即当,看情形是大家都默契地保持了down机的姿态。另外一点就是foodie的迅速反应。这道题想必大家拿过来一看就是“我当时就懵逼了”,不过细看的话是有策略的,这道题只要策略得当,就可以在大家互相不得利的情形下保持一个较为优先的每轮20分左右的优势。这道题在第一天下午我推送出第n个进化版本后,当时只有217的代码可以和我们互相对拼掉,随后我进行了一行的缩短与优化,这样在每轮中只有我们不”哭“的20分和独占的217的20分就有40分的优势,助力我们超过了蓝莲花,不过优势也只是保持在第一天了,第二天蓝莲花的大牛们大招全开,一下把我们落到了西伯利亚=0=

foodie这个题目的本质是指令级别的对拼策略,具体题目和版本见附件。

http://198.11.177.100/foodie.rar

题目提供的foodie程序可以直接看到执行的结果,方便了修改与调试,指令的存储和汇编基本相似,不过只有各种mov和+,-,*,/,%和各类jmp,四个寄存器从r0-r1编码为00,01,10,11和一个pc寄存器为自己独占,内存区域双方共享。目的是让对方执行到f开头的指令即可。

整理一下思路,我能想到的有六种策略可供参考,猥琐自保型,向下覆盖型,向上覆盖型,双向覆盖型,递减覆盖型和混合型。

猥琐自保型:通过不停地复制自己的代码使自己在内存区域里乱跑从而自保,例如第二天的npc

向下覆盖型:通过add指令增加覆盖的偏移,从而不停地向下覆盖能够执行halt的指令

向上覆盖型:通过sub指令减少覆盖的偏移,从而不停地向上覆盖能够执行halt的指令

双向覆盖型:每一轮同时向上和向下覆盖f

递减覆盖型:使覆盖的间隔不停缩小,做到先大面积撒网,然后慢慢循序渐进

混合型:各种覆盖混合

不同的类型之间是有相互克制的关系的,所以比赛的时候我一直盯着PWNWALL,看每一轮结果来推测对方使用了什么样的策略,从而决定使用哪款代码

比赛过程中我准备了猥琐自保型,向上覆盖型,向下覆盖型,双向覆盖型(弱得不行=),递减覆盖型五种代码,具体看附件吧。

优化:

如何构造出halt:我们和217同时被对方干掉的时候,我攒出来一个halt用了两步。这也是由于给一个寄存器赋值仅仅只有10bit造成的,我只通过一步mov没有办法直接给某个寄存器赋予0xf[x][x][x],所以我第一次mov r1,0xff然后再通过一个mul r1,r1得到了0xfe01。后来一拍脑门,原来是我懵逼了,通过sub指令和构造halt的位置,可以一步构造出halt。





文件长度的使用:合理地运用文件长度可以减少自己被干掉的概率,比如我是向上覆盖的,那么在自己的代码后面可以置满ff,从而保证对方的代码不会在我们后面很近的位置。



循环的长度与置halt的间隔:拿我的向上置halt法举例子,我循环的本地只有三行,我每隔四行置一个halt,这样我的循环的代码的本体小于置halt的间隔,从而无限循环下去。



最后也是最重要的一点,要随机应变,比如在一轮之中失分了,失了一轮给队伍a,而队伍a又输给了队伍b,而我们又赢了队伍b,这种情况下,可以根据自己使用的代码种类来判断队伍a和b使用的代码种类,从而调整代码或者更换代码。所以foodie这个题目,也是一个博弈的问题。

后来离线分析的时候我呕心沥血写了个递减覆盖的,同时为了无限自我循环,在最后做了一个判断,加入了向上递减法,同时调整了合适的递减和置halt的范围,从0x80开始,类似于二分的思路,再降到0x40,0x20,最后到4的时候开始进入向上递减法,三行代码无限循环。结果第二天缺发现效果是差强人意啊==想想也是醉了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hack ctf