目录标题

  • 方法一:搜索字节序列
  • 方法二:IDC脚本
  • 方法三:Python脚本:
  • 方法四:bgrep工具

先查看文件信息:

  是linux下的32位ELF文件,且被加了UPX的壳
  下载最新版的UPX脱壳,UPX脱壳的Githup地址:https://github.com/upx/upx/releases/tag/v3.91
  之后脱壳,指定加壳文件57,输出脱壳文件57move

upx -d 57 -o 57move

赋执行权限运行程序:

用IDA打开57move,找到字符串“Guess a flag:”

有两个位置使用了这个字符串:

同样地,我们查看“Wrong Flag!”字符串:

发现有70个引用的地方。
  但是我们可以看到程序的汇编代码全都是mov,肯定是被混淆过了,这里是用了movfuscator来混淆,。
  剑桥大学的Stephen Dolan证明了x86的mov指令是图灵完全的(论文《mov is Turing-complete》)。这意味着从理论上来讲,x86只要有mov这一条指令就可以完成几乎所有功能了(可能还需要jmp),其他指令都是“多余的”。受此启发,有个大牛做了一个虚拟机加密编译器。它是一个修改版的LCC编译器,输入是C语言代码,输出的obj里面直接包含了虚拟机加密后的代码。如它的名字,函数的所有代码只有mov指令,没有其他任何指令。对,完全没有,连call,jz,ret之类的都没有。
  开源项目地址:https://github.com/xoreaxeaxeax/movfuscator
  M/o/Vfuscator(简称“o”,听起来像“mobfuscator”)将程序编译成“mov”指令,并且只编译“mov”指令。算术、比较、跳转、函数调用,以及程序需要的一切,都是通过mov操作完成的;没有自修改代码,没有传输触发的计算,也没有其他形式的非 mov 作弊。
  继续直接分析原程序:

  这类movfuscator 混淆后的程序,MOV混淆是不会混淆函数的逻辑的,因此函数的逻辑还是不变的。大多都是通过逐个比较输入后的字符串的每个字符的方式,比较结果不对就输出“Wrong Flag!”,所以在程序当中就会出现单个的字符,例如:

.text:080493DB C7 05 68 20 06 08 41 00 00 00                   mov     R2, 41h ; 'A'

  movfuscator 混淆后的程序都是通过R2寄存器来存储常量字符,

方法一:搜索字节序列

  直接在IDA中搜索字节序列:字符串C7 05 68 20 06 08(“mov R2,”对应字节码)

得到程序中所有使用的常量字符:

  连起来就是程序的flag:ALEXCTF{M0Vfusc4t0r_w0rk5_l1ke_m4g1c}
  输入到程序验证:

Well Done,这就是正确的flag。

方法二:IDC脚本

  也可以用IDA中的IDC脚本和Python脚本来提取代码段中的常量字符:

#include<idc.idc>
static isAscii(p)  //判断符合条件的字符
{if(Byte(p)<='9' && Byte(p)>='0')return 1;if(Byte(p)<='z' && Byte(p)>='a')return 1;if(Byte(p)<='Z' && Byte(p)>='A')return 1;if(Byte(p)=='}' || Byte(p)=='{' || Byte(p)=='_' || Byte(p)=='@' || Byte(p)=='!' || Byte(p)=='#' || Byte(p)=='&' || Byte(p)=='*')return 1;return 0;
}
static main()
{auto start=0x0804829C,end=0x08060B32;  //代码段起止地址auto point=start;auto str="";while(point<=end){if(isAscii(point) && Byte(point+1)==0 && Byte(point+2)==0 && Byte(point+3)==0)  {   //汇编中立即数一般都是DWORDMessage("%X  %c\n",point,Byte(point));str=str+Byte(point);}point=point+1;}Message("%s\n",str);   //可能是flag
}

运行结果:

得到flag:ALEXCTF{M0Vfusc4t0r_w0rk5_l1ke_m4g1c}

方法三:Python脚本:

start=0x0804829C
end=0x08060B32
flag = ""
while start<end:if (Byte(start) <= ord('9') and Byte(start)>=ord('0')) or (Byte(start)<=ord('z') and Byte(start)>=ord('a')) or (Byte(start)<=ord('Z') and Byte(start)>=ord('A')) or (Byte(start) == ord('}')) or (Byte(start) == ord('{')) or (Byte(start) == ord('_')) or (Byte(start) == ord('@')) or (Byte(start) == ord('!')) or (Byte(start) == ord('#')) or (Byte(start) == ord('&')) or (Byte(start) == ord('*')):if Byte(start) and (Byte(start+1)==0) and (Byte(start+2)==0) and (Byte(start+3)==0):print(chr(Byte(start)))flag += chr(Byte(start))start += 1
print(flag)

运行结果:

  脚本找到的运行结果flag中都出现了字符2,这是因为脚本在判断的时候的逻辑是:从代码段.text起止地址0x0804829C到0x08060B32,只要字符的ASCII值在数字、大小写字母和几个特殊字符中,即可认为是flag中的一个字符,所以这中判断逻辑是可能出现误判的:

得到flag:ALEXCTF{M0Vfusc4t0r_w0rk5_l1ke_m4g1c}

方法四:bgrep工具

  我们从前面的IDA中知道.text:080493DB上的字节序列:字符串C7 05 68 20 06 08(“mov R2,”对应字节码),表明标志的字符是硬编码在二进制文件中的:

bgrep工具:
用法:
bgrep [-B 字节] [-A 字节] [-C 字节] [ […]]
-B:bytes_before
-A:bytes_after
-C:bytes_before 和 bytes_after
先安装:

bgrep "C70568200608" ./57move

查找程序当中字节序列:C70568200608

  得到的是所有出现的字节序列C70568200608的文件偏移地址,之后+6是字节序列C70568200608的长度是6,再从当前的文件读取指针位置读取一个字节的字符,拼接起来所有的字符就是flag。
Python脚本:

#!/usr/bin/env python2offsets = [0x000013db, 0x00001dde, 0x000027e1, 0x000031e4, 0x00003b9c, 0x0000459f, 0x00004fa2, 0x000059a5, 0x00006357, 0x00006d5a, 0x0000775d, 0x00008160, 0x00008b0c, 0x0000950f, 0x00009f12, 0x0000a915, 0x0000b2bb, 0x0000bcbe, 0x0000c6c1, 0x0000d0c4, 0x0000da64, 0x0000e467, 0x0000ee6a, 0x0000f86d, 0x00010207, 0x00010c0a, 0x0001160d, 0x00012010, 0x000129a4, 0x000133a7, 0x00013daa, 0x000147ad, 0x0001513b, 0x00015b3e, 0x00016541, 0x00016f44, 0x000178cc]with open('./57move') as f:flag = ''for offset in offsets:# "mov R2, 41h" is "C70568200608"+"41000000" (the immediate starts after the 6th byte)# 移动文件读取指针到指定位置f.seek(offset + 0x6)#从当前的文件读取指针位置读取一个字节的字符,+6是字节序列C70568200608的长度是6flag += f.read(1)
print flag

运行结果:

得到flag:ALEXCTF{M0Vfusc4t0r_w0rk5_l1ke_m4g1c}

XCTF-攻防世界CTF平台-Reverse逆向类——57、re5-packed-movement(linux32位ELF文件、movfuscator代码混淆)相关推荐

  1. XCTF-攻防世界CTF平台-Reverse逆向类——52、handcrafted-pyc(Python的pyc文件逆向)

    下载题目附件之后,查看附件52: 发现它就是一个Python代码文件 #!/usr/bin/env python # -*- coding: utf-8 -*-import marshal, zlib ...

  2. XCTF-攻防世界CTF平台-Reverse逆向类——56、tar-tar-binks(Mac平台下的64位动态链接共享库.dylib逆向)

    目录标题 一.解压缩 二.查看文件 三.分析程序 四.程序主要逻辑: 五.逆向思路: 步骤一: 步骤二: 六.解密代码: 题目提供了两个文件flag.tar和libarchive.dylib 一.解压 ...

  3. 【ics-05 | mfw】攻防世界CTF题WP

    攻防世界CTF题WP ics-05 所需知识 解题步骤 学习知识 php伪协议(文件包含漏洞中使用) preg_place函数 mfw 所需知识 解题步骤 学习知识 Dirserach工具 GitHa ...

  4. XCTF攻防世界 Normal_RSA

    XCTF攻防世界 Normal_RSA 实验环境: windows 10 实验所需工具: python工具: yafu (可以在https://github.com/DarkenCode/yafu上下 ...

  5. XCTF攻防世界Web新手入门题大全

    XCTF攻防世界Web之WriteUp无图版 (Tips:有图版本,请移步我的资源,自行下载doc文档) 0x00 准备 [内容] 在xctf官网注册账号,即可食用. [目录] 目录 0x01 vie ...

  6. XCTF攻防世界Web之WriteUp

    XCTF攻防世界Web之WriteUp 0x00 准备 [内容] 在xctf官网注册账号,即可食用. [目录] 目录 0x01 view-source2 0x02 get post3 0x03 rob ...

  7. XCTF攻防世界练习区-web题(新手)

    XCTF攻防世界练习区-web题(新手) https://adworld.xctf.org.cn/task?now_checked_num=3&name=web 001 view_source ...

  8. XCTF攻防世界BABYRE逆向

    攻防世界BABYRE逆向 拿到题目,查壳如下: 拖拽IDA Pro7.5打开,查看main函数,代码如下: 可以看到: (*(unsigned int (__fastcall **)(char *)) ...

  9. xctf攻防世界 crypto 新手练习区--write up(持续更新中)

    文章目录 base64 Caesar Morse Railfence 不仅仅是Morse easy RSA RSA算法 简介 RSA计算公钥和私钥 混合编码 转轮机加密 回转轮加密 base64 题目 ...

最新文章

  1. AttributeError: Cant get attribute SPPF on module models
  2. 阿里算法,浙大博士带你写项目经历!
  3. 网站推广的三大基本方式
  4. java path设置错误_linux下环境变量PATH设置错误的补救
  5. C/C++之 C++ String(字符串)
  6. C++实现二分查找(附完整源码)
  7. linux下屏幕太靠右了,怎么消除linux下的屏幕偏移现象和调整屏幕刷新率?
  8. Qt中的TableWidget初始化表头、行高、选中、自动扩展和接受修改
  9. b站测试岗怎么样_情商测试《大家一起察言观色》,一款适合作为B站测试题的游戏...
  10. “网页上有错误”的解决方法
  11. 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,
  12. 物流配送信息管理系统java_基于jsp的物流配送管理系统-JavaEE实现物流配送管理系统 - java项目源码...
  13. android mp3 lrc歌词文件utf-8歌词显示为乱码,Android访问Tomcat错误以及mp3player项目乱码问题解决...
  14. 【Oracle】IF EXISTS用法
  15. 阿里云服务器如何购买?三种购买阿里云服务器方式教程分享
  16. 如何给PDF加水印,PDF加水印的快速方法
  17. mov格式如何转换成mp4?详细步骤教程
  18. 他一年写了200篇原创笔记,帮助你快速入门Python与机器学习
  19. MySQL8 免安装版安装
  20. 思科光纤模块兼容性解决

热门文章

  1. java使用selenium-chrome-driver实现简单的本地爬虫
  2. 为什么说指针是 C 语言的精髓?
  3. 杜克大学计算机专业,杜克大学计算机专业怎么样?过来人告诉你
  4. 无线通信又闯祸 波音飞机系统竟被黑
  5. 《拼音字母》 蓝桥杯复试试题
  6. 实时无感人脸识别考勤机项目
  7. OBS Studio软件及多端推流插件的安装教程
  8. 云客Drupal源码分析之实体视图显示及格式化器
  9. 新闻稿编辑公司哪家好
  10. 计算机组成指令系统的论文,计算机组成原理探讨论文