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))