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)
reverse-daily(1)-audio_visual_receiver_code的更多相关文章
- HNU 13411 Reverse a Road II(最大流+BFS)经典
Reverse a Road II Time Limit: 10000ms, Special Time Limit:25000ms, Memory Limit:65536KB Total submit ...
- LeetCode 7. Reverse Integer
Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 Have you ...
- 【uwp】浅谈China Daily 中划词翻译的实现
学习uwp开发也有一段时间了,最近上架了一个小应用(China Daily),现在准备将开发中所学到的一些东西拿出来跟大家分享交流一下. 先给出应用的下载链接:China Daily , 感兴趣的童鞋 ...
- js sort() reverse()
数组中存在的两个方法:sort()和reverse() 直接用sort(),如下: ,,,,,,,,,,,]; console.log(array.sort());ps:[0, 1, 2, 2, 29 ...
- [LeetCode] Reverse Vowels of a String 翻转字符串中的元音字母
Write a function that takes a string as input and reverse only the vowels of a string. Example 1:Giv ...
- [LeetCode] Reverse String 翻转字符串
Write a function that takes a string as input and returns the string reversed. Example: Given s = &q ...
- [LeetCode] Reverse Linked List 倒置链表
Reverse a singly linked list. click to show more hints. Hint: A linked list can be reversed either i ...
- [LeetCode] Reverse Bits 翻转位
Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...
- [LeetCode] Reverse Words in a String II 翻转字符串中的单词之二
Given an input string, reverse the string word by word. A word is defined as a sequence of non-space ...
- [LeetCode] Reverse Words in a String 翻转字符串中的单词
Given an input string, reverse the string word by word. For example, Given s = "the sky is blue ...
随机推荐
- noi 4977 怪盗基德的滑翔翼
题目链接: http://noi.openjudge.cn/ch0206/4977/ LIS http://paste.ubuntu.com/23406594/
- [Python]如何获取目录下,最后更新的文件
#-*- coding: utf-8 -*- __author__ = 'tsbc' import time import datetime import os day = time.strftime ...
- 【RabbitMQ】RabbitMQ在Windows的安装和简单的使用
版本说明 使用当前版本:3.5.4 安装与启动 在官网上下载其Server二进制安装包,在Windows上的安装时简单的,与一般软件没什么区别. 安装前会提示你,还需要安装Erlang,并打开下载页面 ...
- eclipse https git
open preferences via application menu Window => Preferences (or on OSX Eclipse => Settings). N ...
- Java 中的 static 使用之静态初始化块
Java 中可以通过初始化块进行数据赋值.如: 在类的声明中,可以包含多个初始化块,当创建类的实例时,就会依次执行这些代码块.如果使用 static 修饰初始化块,就称为静态初始化块. 需要特别注意: ...
- C library function - freopen()
Description The C library function FILE *freopen(const char *filename, const char *mode, FILE *strea ...
- 如何让一个DIV浮动在另一个DIV上面
直接上DEMO了 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3 ...
- Android Studio常见问题 -- uses-sdk:minSdkVersion 8 cannot be smaller than version 9 declared in library
问题描述 * What went wrong:Execution failed for task ':app:processDebugManifest'.> Manifest merger fa ...
- Nbimer族助手 部分控件不能用的解决方法(转)
用户提出的问题现象: 我两天笔记本安装的都是win7 SP1系统,一台为64为一台为32位,网络环境是移动宽带通过D-Link路由器实现无线局域网,DHPC自动分配IP地址.每次打开IE或者Chrom ...
- [java基础]分支结构(2)
[java基础]分支结构2 switch case /** 文件路径:G:\JavaByHands\if-else\ 文件名称:switchcase.java 编写时间:2016/6/6 作 者:郑晨 ...