[XCTF-Reverse] 50 asis-ctf-quals-2016_catch-me

下来的附件不能运行,用010打开看有7z开头应该是个压缩包,改扩展名解压后还不行,再看一上来是文件名,应该是tar打包的。其实就是用带压缩的tar打的包。

无壳,直接在ida打开,第1个v3的函数比较麻烦,看不懂放到gdb里运行断到这得到v3=0xbg11924e1

  v3 = sub_400820(dword_6012B4);                // 0xb11924e1
  byte_6012A8[0] = HIBYTE(v3);
  byte_6012A9 = BYTE2(v3) & 0xFD;
  byte_6012AA = BYTE1(v3) & 0xDF;
  byte_6012AB = v3 & 0xBF;
  if ( getenv("ASIS") && (*(_DWORD *)getenv("CTF") ^ v3) == -18088213 )// CTF有啥用?
    dword_6012AC = *(_DWORD *)getenv("ASIS");
  v4 = 0LL;
  do
  {
    haystack[v4] ^= byte_6012A8[v4 & 7];        // 8位,4位已知
    ++v4;
  }
  while ( v4 != 33 );
  v5 = _mm_load_si128((const __m128i *)haystack);// haystack前8字节
  v6 = _mm_unpacklo_epi8(v5, (__m128i)0LL);     // a0-a7,b0-b7 => a0b0, a1b1, ... a7b7
  v7 = _mm_unpackhi_epi8(v5, (__m128i)0LL);     // a8-a15,b8-b15 => a8b8,a9b9,...a15b15
  v8 = _mm_add_epi32(                           // a0+a4+a8+a12,a1+a5+a9+a13,...
         _mm_unpackhi_epi16(v7, (__m128i)0LL),
         _mm_add_epi32(
           _mm_add_epi32(_mm_unpackhi_epi16(v6, (__m128i)0LL), _mm_unpacklo_epi16(v6, (__m128i)0LL)),
           _mm_unpacklo_epi16(v7, (__m128i)0LL)));
  v9 = _mm_load_si128((const __m128i *)&xmmword_601290);// haystack 中8字节
  v10 = v9;
  v11 = _mm_unpackhi_epi8(v9, (__m128i)0LL);
  v12 = _mm_unpacklo_epi8(v10, (__m128i)0LL);
  v13 = _mm_add_epi32(                          // a0+a4+a8+a12 + a16+a20+a24+a28,
          _mm_add_epi32(
            _mm_add_epi32(
              _mm_add_epi32(v8, _mm_unpacklo_epi16(v12, (__m128i)0LL)),
              _mm_unpackhi_epi16(v12, (__m128i)0LL)),
            _mm_unpacklo_epi16(v11, (__m128i)0LL)),
          _mm_unpackhi_epi16(v11, (__m128i)0LL));
  v14 = _mm_add_epi32(v13, _mm_srli_si128(v13, 8));// 右移8字节再相加
  if ( _mm_cvtsi128_si32(_mm_add_epi32(v14, _mm_srli_si128(v14, 4))) != 2388 )// 所有字节加一起=2388
  {
    *(_DWORD *)haystack = 1600414050;
    *(_DWORD *)&haystack[4] = 1600414050;
    *(_DWORD *)&haystack[8] = 1600414050;
    *(_DWORD *)&haystack[12] = 1600414050;
    *(_QWORD *)&xmmword_601290 = 6873726006409322850LL;
    BYTE7(xmmword_601290) = 0;
  }
  printf("Flag: ASIS{%s}\n", haystack);
  if ( strstr(haystack, "bad_") )
    puts("this flag is absolutely fake ");
  return 0LL;

第2步是导入两个环境变量,ASIS和CTF,这里处理了一下CTF可以异或得到,但貌似没用,因为以后也用不着他

下面是一大断_mm_开头的指令,查了一下是sse的指令,这些都能从微软网站查到,基本就是加法和插值,而且插的都是0,实际上是把字节表示的值每个字节插3个0变成32位整数,然后移位相加。转了一圈就是把每个字节相加得到一个数应该等于2388 。

那么问题来了,一个密钥8字节有4字节已知,另外4个未知这样相加等于2388的就太多了。

回头看看刚才扔掉的CTF,这个没用为啥给出来,它会不会是后边的4位密钥呢?一试确实是。

解码:

from pwn import *
#.data:0000000000601280 haystack 
a= bytes.fromhex('872934C555B0C22DEE6034D455EE807CEE2F37963DEB9C79EE2C339578EDC12BB1') 

v3 = bytes([0xe1, 0x24, 0x19, 0xb1])   #(0xb11924e1)
byte_6012A8 = bytes([ v3[3], v3[2]&0xfd, v3[1]&0xdf, v3[0]&0xbf ])
print(v3)
ctf = 0xfeebfeeb ^ u32(v3)
print(hex(ctf))
tv3 = byte_6012A8 +p32(ctf)  #CTF == ASIS
haystack = bytes([m^tv3[n&7]  for n,m in enumerate(a)])
if sum(haystack) == 2388:
    print(haystack)
#b'600d_j0b_y0u_4r3_63771n6_574r73d\x00'
#ASIS{600d_j0b_y0u_4r3_63771n6_574r73d}
'''
for i0 in range(10,11):
    print(i0)
    for i1 in range(256):
        for i2 in range(256):
            for i3 in range(256):
                tv3 = byte_6012A8 + bytes([i0,i1,i2,i3])
                haystack = bytes([m^tv3[n&7]  for n,m in enumerate(a)])
                if sum(haystack) == 2388:
                    for i in range(32):
                        if haystack[i]<0x20 or haystack[i]>0x7f:
                            continue
                    else:
                        print(haystack)
'''                

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值