第三届上海大学生网络安全大赛juckcode

第三届上海大学生网络安全大赛juckcode

  这个比赛在几个星期前就结束了,作为一个学逆向2个半月的菜鸟,我没有能力参加,只是问同学要题目自己做了一遍。(i春秋上有原题)
0x0 前期准备

  题目下载解压之后有flag.enc和juckcode.exe两个文件,打开flag.enc发现:

flag.enc的内容
  没见过的密文格式,看来是一场恶战。用PEiD和EXEInfoPE分别打开juckcode.exe,没发现壳。再用PEiD的插件–Krypto ANALyzer,没发现已知的加密算法。在cmd里输入.\juckcode.exe 123456,输出结果是:

GFtF@@AHqrHHEEFBsBsvCHH@GFtF@@@@@H@@

看来flag就是命令行参数经过juckcode输出和上图一样的字符串。

0x1 静态分析

  打开IDA PRO 7.0加载juckcode.exe(这里最好先用aslr_disabler.exe取消掉系统对程序的空间格局随机化),shift+F12查看一下有没有关键字,看到有一个:
IDA关键字
  查看交叉引用,定位到汇编地址,再Force Analyze,看到了一个有用的函数:
这里写图片描述
  原来juckcode.exe也可以通过./flag文件作为输入。但是这里出现的代码实在是看不下去,放弃静态分析。

0x2 动态分析

  我新建了一个文件—“flag”,里面写着flag{123456}。然后打开OD后试着F8到底,发现有几个大跳,感觉每个大跳就是完成一个任务,特征是有一堆无法解析的16进制,然后就是代码(跳转到的地方在retn比较下面):
特征

  00403412是第一个大跳后的地址。继续F8了一会,发现了很关键的一个位置:
这里写图片描述

  这里的DS:[006B97E8]指向了一串字符串,本能地放入BASE64解码器解码:
         base64encode

  可见00403412这部分代码就是把输入进行BASE64编码。

  第二次大跳会跳到4034F7:

这里写图片描述
  继续F8到403510,可以看到EAX指向了一串不知道干嘛用的字符串:
    这里写图片描述
  403531又出现一串新的字符串:
    这里写图片描述
  经过多次F8,发现了第三个不知道什么意思的字符串:
    这里写图片描述
  跟进了很久也不见有新的大跳,但是有两个地方很可疑:
这里写图片描述
  
这里写图片描述

  这两个地方都是把ds:[eax]的值传给ss:[ebp+edx*4-0x4xx]。
  经过反复观察,我发现[ebp+edx*4-0x410]上面的ds:[eax]是指向ZmxhZ3sxMjM0NTY3ODlhYmN9的指针,
   40F上面的ds:[eax]指向pqyhp7txcnN0dXa9,
    然后40D对应AACAgICAAIAAgACAAICAAICA,
      40E对应YmLi4uLiYuJi4mLiuLiYuLi

  而且这里的大跳点在:
这里写图片描述
  ss:[ebp-0x95c]恒定为0x10,每次执行完上述操作eax+1,直到0x10才跳转。
  这就是说每次循环执行将输入的字符串的base64编码第i位放入410,将pqyhp7txcnN0dXa9的第i位放入40f,后面两个字符串类似。

  我们直接执行到大跳之后,然后F8到这:
这里写图片描述
  这是个64位字符串,粗略看一下发现和我的推测一样。

  经过了不少F8,又发现一个制造字符串的地方:
这里写图片描述

  ss:[ebp-0x810]每经过一次循环就会产生两个字符,开头是6696009a...
这里写图片描述

  结束循环的地方如上图所示,当ss:[ebp-0x978]==0x30时,会置一个变量为0,多次传递变量到ecx再test ecx,ecx。此时ecx时0,所以je 403700成立,大跳。

  大跳后按几次F8可以发现一段奇怪的字符串:
这里写图片描述

  这里看了半天也没发现什么,我决定往下F8看看。(其中我在jnz下面一行下了断点,跳过了循环很多次的jnz),又发现了一个关键的地方:
这里写图片描述
  edx是从ss:[ebp+ecx-0x810]中获取的,而ss:[ebp+ecx-0x810]正正是我上面提到的奇怪的字符串!!!edx在这里加了0x10,在后面又赋值回奇怪字符串的地址上。那我看看整段奇怪字符串+0x10之后是什么东西:
这里写图片描述
  40376c是跳转条件:eax==0x60时,跳到4037A8,再F8一下,查看ss:[ebp-0x810]里的数据:
这里写图片描述
  这就是flag.enc的形式了。
  最后一个问题就是:奇怪的字符串到底是怎么来的?
这里写图片描述

  其实这里只有0-9和a-f,一看就知道是16进制。经过我们班mingo大神的指导后,才知道上面生成了
ZpYAmqmAxyLChhiAZp4g37uIstLCxxiAMcYAjnuIMNJA00iANd4gTXmAZaLC99iA
之后base64解码了一次,因为解码后的第一位是f,后面大多是乱码,而奇怪字符串的前两个字符‘66’恰恰是f的ascii码(16进制),所以推测是base64解码。
  接下来将这些16进制字符串的16进制再加0x10就可以得到FFIF@@...字符串的形式了。

  上面还有一个问题就是我输入的flag太短导致最后结果比flag.enc里的短得多。我后来测试了输入flag{123456789abc},发现AACAgICAAIAAgACAAICAAICAYmLi4uLiYuJi4mLiuLiYuLi的24位全用上了,不像上面只用了16位,而且pqyhp7txcnN0dXa9变成了一串24位的字符串,不太一样,不过这不妨碍我们写逆程序,因为我们写逆程序时根本不需要用到这三个字符串。

0x3 逆向代码

  可以愉快地写我的(看不下去的)python了:

import base64
import string

secret = 'FFIF@@IqqIH@sGBBsBHFAHH@FFIuB@tvrrHHrFuBD@qqqHH@GFtuB@EIqrHHCDuBsBqurHH@EuGuB@trqrHHCDuBsBruvHH@FFIF@@AHqrHHEEFBsBGtvHH@FBHuB@trqrHHADFBD@rquHH@FurF@@IqqrHHvGuBD@tCDHH@EuGuB@tvrrHHCDuBD@tCDHH@FuruB@tvrIH@@DBBsBGtvHH@GquuB@EIqrHHvGuBsBtGEHH@EuGuB@tvrIH@BDqBsBIFEHH@GFtF@@IqqrHHEEFBD@srBHH@GBsuB@trqrHHIFFBD@rquHH@FFIuB@tvrrHHtCDB@@'
a = []
b = ''

for ch in secret:
    a.append(ord(ch) - 16);

i = 0
m = ''
while i< len(a):
    m = chr(a[i])+chr(a[i+1])
    n = int(m,16)
    b += chr(n)
    i += 2

a = base64.encodestring(b)
a=a.replace('\n','')
i = 0 
q = ''
while i< len(a):
    if i%4 == 0:
        q += a[i]
    i += 1

# the result is not the right padding for base64,so I add an '='
q += '='

q = base64.decodestring(q)
print q

PS: 1.python的base64库在encode时会自动在76个字符之后加上换行符,
   所以要replace掉;
  2.如果最后不加上=号的话会报错:
  binascii.Error: Incorrect padding;

0x4 总结

  这个程序的加密步骤就是:
  1.将输入(或.\flag里的内容)base64编码生成a;
  2.每次循环将a的内容和三串字符串的每一位拼凑起来,直至到达字符串长度,生成b;
  3.将b进行base64解码,生成了乱码c;
  4.将乱码c的每一位的ascii码转为字符串(比如第一位是‘f’,ascii码是66,则将66转换成字符串‘66’),全部转化成功后生成d;
  5.将d的每一位的ascii码再加0x10(比如上面生成的字符串‘66’,ascii码是36 36,再加0x10就是‘FF’(46 46)),全部加上0x10之后生成e;
  6.e就是flag.enc里的密文格式了;

6个小时的挑战,搞出来以后特别有成就感,希望我能在这条路上坚持下去。
特别鸣谢:mingo老


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值