reverse-daily(1)-audio_visual_receiver_code
本人第一篇随笔,就以一篇CTF逆向分析的文章开始吧!
链接:http://pan.baidu.com/s/1eS6xFIa 密码:u14d
因为re的分析比较琐碎,所以主要就挑一些重点东西来说。
据说这道题是谷歌的一道题目,然而我觉得题目不算很好,有很大程度上要靠猜测出题人的意图,有为了出题而出题的嫌疑,不过还是首先来上手分析吧
1.首先拿到程序用ida载入,会发现这是一个elf文件,程序的主体结构很简单,首先进入main函数,看到read_button函数,进入。
2.简单分析一下read_button函数可得到这样一个对应关系
U/u >0; D/d>1; L/l>2; R/r>3; A/a>4; B/b>5
3.再回到main函数看到
v3 = read_button();
(*(&buttons + v3))();
而如图:
可知输入不同值分别对应运行up,down,left,right,a,b各个程序
4.再对up,down,left,right,a,b几个函数分别进行分析,在a函数中看到有out_flag函数,进入后发现这是一个输出flag的函数:
5.然后就是对各个函数算法漫长的分析了,由分析可以得到这样一个简化版本,
db check
db state=5
1.down: check^=state
state=state>>1*8-state>>1
2.up: check^=state
state=3state
3.left: check^=state
state=2state
4.right: check^=state
state=state>>3 循环右移
5.b: check^=state
state=~state
6.a: check^=state
state=state>>4 循环右移
if(*cross_ptr==check)
check=0
cross_ptr++
6.初始时pos=&buffer,state=5,每运行left,right等其中的一个程序,就会首先将_int8 state的值放入buffer数组中pos所对应的位置,然后pos++,接着是对state的演算变化,现在来看check,可以看到a函数中要想运行out_flag函数的最重要的一个条件就是:if ( *(_BYTE *)cross_ptr == check ),而cross_ptr所对应的值如下:
7.而check在bss段中,由分析有每运行一次a,b等函数,首先做的就是check^=state,所以check的值实际上就是运行到当前时所有state值异或的结果,而如果a中
if ( *(_BYTE *)cross_ptr == check )这样一个条件成立的话,首先check=0,即对check清零,然后cross_ptr++
8.然后每个函数中都有这样一个判断
if ( (_BYTE *)pos - (_BYTE *)&buffer > 32 )
pos = &buffer;
即当buffer长度>32时即对其进行重写
9.a中最后一重判断:
if ( (_BYTE *)pos - (_BYTE *)&buffer > 29 )
output_flag();
即buffer到pos所指位置处长度>29时输出,由于条件8的存在所以输入字符串的长度其实并没有限制
10.再看out_flag函数,可以看到输出结果为flag数组和buffer各位异或的输出,而flag长度为30位:
11.这样一来,整个程序的结构就很清楚了,这道题的重点并不在程序的逆向,而主要在于算法的逆向分析,分析到这里,我就卡住了很久很久,因为就我的分析来看,这道题目基本无解,因为首先程序的输入长度就不能确定,其次对程序的爆破也不可行
12,坑爹的地方来了,我的一个学长这时候提醒我,注意各个函数的名称,我看了看,上下左右ab,这不是魂斗罗的大招吗,上上下下左右左右ba,因为flag长度为30
所以我就尝试了下uuddlrlrbauuddlrlrbauuddlrlrba,结果正是:
13,当然并不只有这样一种方法,如果揣测出题人意图的话,会发现,cross数组长度为3,而flag长度为30,而要想输出的话,最后以为肯定是a字符,这样一来,可以推测出这样一个关系:字符串长度为30,第十,二十,三十个字符分别为a,这样一来可以分十组,分别进行爆破,结合输出的ascii的范围,可以进一步缩小范围,以下的python代码是由我得学长所写,因为是他提供的第二种思路,我自己也尝试用c来写了下,当然c的话是很不好写,最好用python,有时间我会贴上自己的c代码
14.这道题目的确是不大好,如我开始所说,很大一部分要靠冒着很大风险来猜测,如果是打比赛如果我忘记了魂斗罗的大招的话,我肯定是不会做这道题的,当然这道题还是有很意义的,首先,加强了我算法分析的能力,这道题的算法还是有一定算法复杂度的,其次,python的编写,python绝对是最好用的脚本语言之一,我还在学习用好它的路上,最后,揣测出题人的意图,有时候能事半功倍,当然不要为了做题而做题
15.就写到这里吧!写篇随笔真的很耗时间。。。
alp = '1234567890_{ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz}' flag = [0x46,0x5b,0x6b,0xe1,0x6f,0x5e,0xa3,0xd3,0xa2,0x1c,0x82,0xed,0x62,0x24,0x67,0x71,0xdd,0x6d,0xf3,0x20,0x83,0x8d,0xca,0x3e,0x33,0xc8,0x75,0x5a,0x68,0x87] cross = [0x25,0x68,0xef] cross_ptr = 0 Buf = [0 for i in xrange(30)] State = 5 Pos = 0 Check = 0 find = 0 def up(pos,state,check,buf): buf[pos] = state pos += 1 pos %= 33 check ^= state state *= 3 state &= 0xff return pos,state,check,buf def down(pos,state,check,buf): buf[pos] = state pos += 1 pos %= 33 check ^= state state >>= 1 tmp = state state *= 8 state -= tmp state &= 0xff return pos,state,check,buf def left(pos,state,check,buf): buf[pos] = state pos += 1 pos %= 33 check ^= state state *= 2 state &= 0xff return pos,state,check,buf def right(pos,state,check,buf): buf[pos] = state pos += 1 pos %= 33 check ^= state tmp = 32*state state >>= 3 state |= tmp state &= 0xff return pos,state,check,buf def b(pos,state,check,buf): buf[pos] = state pos += 1 pos %= 33 check ^= state state ^= 0xff state &= 0xff return pos,state,check,buf def a(pos,state,check,buf): global cross global cross_ptr buf[pos] = state pos += 1 pos %= 33 check ^= state tmp = state >> 4 state *= 16 state |= tmp state &= 0xff correct = 0 if cross[cross_ptr] == check: check = 0 correct = 1 cross_ptr += 1 if pos == 30: output_flag(buf) return pos,state,check,buf,correct def output_flag(buf): global flag s = '' for i in xrange(30): s += chr(flag[i]^buf[i]) print s func = [up,down,left,right,b] def force(pos,state,check,buf): global find global flag global alp if find == 1: return if (pos+1)%10 == 0: pos,state,check,buf,c = a(pos,state,check,buf) if c == 0: return if pos == 30: find = 1 return for v in func: tmp1,tmp2,tmp3,tmp4 = v(pos,state,check,buf) tmp = chr(flag[tmp1]^tmp2) if tmp in alp: force(tmp1,tmp2,tmp3,tmp4) force(Pos,State,Check,Buf)
- Angular14 Visual Studio Code作为Angular开发工具常用插件安装、json-server安装与使用、angular/cli安装失败问题、emmet安装
- SharePoint Framework 在Visual Studio Code中调试你的本地解决方案
- visual studio code配置python开发环境的一点心得
- Nodejs in Visual Studio Code 03.学习Express
- 解决:mac visual code1.8.1 运行时提示:无法在 PATH 上找到运行时”node“。
- visual studio code调试.net core 2.0程序
- 在Ubuntu中安装Visual Studio Code
- Visual Studio Code之常备快捷键
- Nodejs in Visual Studio Code 08.IIS
- visual studio CodeSnippet的使用
- Silverlight.1.0.R.C.发布后,让Visual Stdio Codename Orcas继续
- ubuntu下使用visual studio code来编译和调试C++
- 在ubuntu下使用visual studio code编写python
- Visual Studio Code 快捷键
- Visual Studio Code 在CentOS下阅读C++源码
- 使用Visual Studio Code打开浏览器查看HTML文件
- Visual Studio Code 安装 RUST
- Reverse Engineer Code First Generate Class Issue
- Visual Studio Code ,VScode,你没听过?