RE-picoCTF2018-be-quick-or-be-dead-2

Alikas-0x08
题目:picoCTF-be-quick-or-be-dead-2

日常file

file be-quick-or-be-dead-2
be-quick-or-be-dead-2: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=a17015934532d5f720afa9b29a9a28e8a1aedae1, not stripped

拖进IDA,分析代码

int64 __fastcall fib(unsigned int a1)
{
  int v1; 
  unsigned int v3; 

  if ( a1 > 1 )
  {
    v1 = fib(a1 - 1);
    v3 = v1 + fib(a1 - 2);
  }
  else
  {
    v3 = a1;
  }
  return v3;
}

计算斐波那契数列 fib(1083u)

(用递归算会特别慢,用数组算快特别多)(一开始还傻傻的用递归算,真是tcl)

注意unsigned int v3 最多为32位,故而python脚本中key1[1082]&0xFFFFFFFF,保留32位即可

int64 __fastcall decrypt_flag(int a1)//a1即key
{
  __int64 result; 
  int v2; 
  unsigned int i; 

  v2 = a1;
  for ( i = 0; ; ++i )
  {
    result = i;
    if ( i > 0x38 )
      break;
    flag[i] ^= *(&v2 + i % 4);
    if ( i % 4 == 3 )
      ++v2;
  }
  return result;
}

观察可知计算flag算法为:

flag[56]这个数组,4个为一组。每组的第1位与key第1个字节异或;第2位与key第2个字节异或;第3位与key第3个字节异或;第4个与key第4个字节异或。然后key++,如此循环

flag =[0x32, 0x23, 0x0B, 0xAF, 0x00, 0x1E, 0x2E, 0xBB, 0x30, 0x22, 0x0D, 0x9F, 0x23, 0x23, 0x0A, 0xAF, 0x28, 0x2B, 0x0B, 0xA3,0x2E, 0x15, 0x1B, 0xA5, 0x39, 0x3F, 0x0D, 0xAE, 0x2A, 0x2F, 0x37, 0xA3, 0x2B, 0x24, 0x37, 0xA2, 0x2E, 0x15, 0x0C, 0xAF,  0x22, 0x2F, 0x37, 0xA6, 0x2C, 0x39, 0x1C, 0x9F, 0x76, 0x72, 0x0E, 0xF3, 0x7E, 0x2C, 0x5C, 0xF8, 0x2D, 0x00]

key1 = [1,1]

for i in range(2,1084):
    key1.append(key1[i-1]+key1[i-2])
#append即给key1这个列表填充数据
#key1[i-1]+key1[i-2]即填充斐波那契数列

key = key1[1082] & 0xFFFFFFFF #保留32位

#小端存放
key2 = [0,0,0,0]
for i in range(4):
	key2[i] = (key & 0xFF)
	key >>= 8
print key2

#计算算法python实现
for i in range(len(flag)):
    flag[i] ^= key2[i % 4]
    if (i % 4 == 3):
        key2[0]+=1
        
#flag转成字符型存放到s中        
s = '' 
for i in range(len(flag)):
    s += chr(flag[i])
    
print s

总结:题目不难,分析一下即可。

最后附上一位大佬的脚本,学习!

from struct import pack
#key = fib(1083)
key = 9641162182178966878126331027202834784434723577592322830700454745652427494401346945631082965963962317692358822696127040961581675695438118874508418491101822679355067810556808551572644321954159676320600161466564032755133080685122 & 0xFFFFFFFF
v = bytearray(pack(", key))
s = bytearray("32230BAF001E2EBB30220D9F23230AAF282B0BA32E151BA5393F0DAE2A2F37A32B2437A22E150CAF222F37A62C391C9F76720EF37E2C5CF82D".decode("hex"))
for i in xrange(len(s)):
	s[i] ^= v[i % 4]
	if(i % 4 == 3):
		key += 1
		v = bytearray(pack(", key))
print(str(s))

你可能感兴趣的:(逆向)