25,tinyctf-2014_elrond32
main里两个函数一个负责生成“密钥”,一个负责整理输出
int __cdecl main(int a1, char **a2)
{
if ( a1 > 1 && sub_8048414(a2[1], 0) )
{
puts("Access granted");
sub_8048538((int)a2[1]);
}
else
{
puts("Access denied");
}
return 0;
}
这个函数比较有意思,逐次都调用自己生成下一位。
signed int __cdecl sub_8048414(_BYTE *a1, int a2)
{
signed int result; // eax
switch ( a2 )
{
case 0:
if ( *a1 == 105 ) // 0
goto LABEL_19;
result = 0;
break;
case 1:
if ( *a1 == 101 )
goto LABEL_19;
result = 0;
break;
case 3:
if ( *a1 == 110 )
goto LABEL_19;
result = 0;
break;
case 4:
if ( *a1 == 100 )
goto LABEL_19;
result = 0;
break;
case 5:
if ( *a1 == 97 )
goto LABEL_19;
result = 0;
break;
case 6:
if ( *a1 == 103 )
goto LABEL_19;
result = 0;
break;
case 7:
if ( *a1 == 115 )
goto LABEL_19;
result = 0;
break;
case 9:
if ( *a1 == 114 )
LABEL_19:
result = sub_8048414(a1 + 1, 7 * (a2 + 1) % 11); //用另一个顺序调用生成下一字节
else
result = 0;
break;
default:
result = 1;
break;
}
return result;
}
手工处理一下,得到
a2 f(n)=7*(f(n-11)+1)%11
0 105
7 115
1 101
3 110
6 103
5 97
9 114
4 100
然后根据第2个函数生成flag
a1=[105,115,101,110,103,97,114,100]
v2=[0xf,0x1f,4,9,0x1c,0x12,0x42,9,0xc,0x44,0xd,7,9,6,0x2d,0x37,
0x59,0x1e,0,0x59,0xf,8,0x1c,0x23,0x36,7,0x55,2,0xc,8,0x41,0xa,0x14]
flag = ''.join([chr(v2[i]^ a1[i%8]) for i in range(33)])
print(flag)
#flag{s0me7hing_S0me7hinG_t0lki3n}
26,tinyctf-2014_yy3441810
只是个数据文件,不是程序,用010打开发现它分为若干小段,每段68开头0f05结尾,中间两个字节放一起正好是flag
坑,提交的时候去包裹,跟网信那个比赛一样,很个路。
#每段68开头 0f05结尾 前两字符
bytes.fromhex('666c61677b706f70706f707265747d0a')
#flag{poppopret}
#poppopret
27,RCTF-2015_notsequence
main函数这块给出flag的样子,但是生成方法比较难看到
int __cdecl main()
{
_DWORD *v0; // eax
signed int v2; // [esp+14h] [ebp-Ch]
_DWORD *v3; // [esp+1Ch] [ebp-4h]
memset(&unk_8049BE0, 0, 0x4000u);
puts("input raw_flag please:");
v3 = &unk_8049BE0;
do
{
v0 = v3;
++v3;
scanf("%d", v0);
}
while ( *(v3 - 1) != 0 );
v2 = sub_80486CD((int)&unk_8049BE0); // 检查1 20个数 杨辉三角每一层的和==2^(n-1)
if ( v2 == -1 )
{
printf("check1 not pass");
system("pause");
}
if ( (unsigned __int8)sub_8048783((int)&unk_8049BE0, v2) ^ 1 )// 检查2
{
printf("check2 not pass!");
exit(0);
}
if ( v2 == 20 )
{
puts("Congratulations! fl4g is :\nRCTF{md5(/*what you input without space or \\n~*/)}");
exit(0);
}
return 0;
}
有两个检查函数,要求输入是20行的杨辉三角。大概就是每层和是2^(n-1)
signed int __cdecl sub_80486CD(int a1)
{
int j; // [esp+0h] [ebp-14h]
int v3; // [esp+4h] [ebp-10h]
int i; // [esp+8h] [ebp-Ch]
int v5; // [esp+Ch] [ebp-8h]
v5 = 0;
for ( i = 0; i <= 1024 && *(_DWORD *)(4 * i + a1); i = v5 * (v5 + 1) / 2 )
{
v3 = 0;
for ( j = 0; j <= v5; ++j )
v3 += *(_DWORD *)(4 * (j + i) + a1); // 从第 n*(n+1)/2开始的n个数的和=2^(n-1)
if ( 1 << v5 != v3 )
return -1;
++v5;
}
return v5;
}
signed int __cdecl sub_8048783(int a1, signed int a2)
{
int v3; // [esp+10h] [ebp-10h]
int v4; // [esp+14h] [ebp-Ch]
signed int i; // [esp+18h] [ebp-8h]
int v6; // [esp+1Ch] [ebp-4h]
v6 = 0;
for ( i = 1; i < a2; ++i )
{
v4 = 0;
v3 = i - 1;
if ( !*(_DWORD *)(4 * i + a1) )
return 0;
while ( a2 - 1 > v3 )
{
v4 += *(_DWORD *)(4 * (v3 * (v3 + 1) / 2 + v6) + a1);
++v3;
}
if ( *(_DWORD *)(4 * (v3 * (v3 + 1) / 2 + i) + a1) != v4 )
return 0;
++v6;
}
return 1;
}
按杨辉三角作出串生成md5
a = '111'
yh = [1,1]
for i in range(2,20):
tmp = [1]
for j in range(1,i):
tmp.append(yh[j-1]+yh[j])
tmp.append(1)
a +=''.join([str(k) for k in tmp])
yh = tmp
print(yh)
print(a)
import hashlib
b = hashlib.md5(a.encode()).hexdigest()
print(b)
#37894beff1c632010dd6d524aa9604db
#RCTF{37894beff1c632010dd6d524aa9604db}
28,alexctf-2017_re2-cpp-is-awesome
一个简单的查表题
v14 = 0;
for ( i = std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::begin(&v11); ; sub_400D7A(&i) )
{
v13 = std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::end(&v11);
if ( !sub_400D3D((__int64)&i, (__int64)&v13) )
break;
v8 = *(unsigned __int8 *)sub_400D9A((__int64)&i);
if ( (_BYTE)v8 != off_6020A0[dword_6020C0[v14]] ) //。。。。
sub_400B56((__int64)&i, (__int64)&v13, v8);
++v14;
}
解下码,坑,生成的flag头不对,手工改
#if ( *v8 != off_6020A0[dword_6020C0[v14]] )
off_6020A0 = b'L3t_ME_T3ll_Y0u_S0m3th1ng_1mp0rtant_A_{FL4G}_W0nt_b3_3X4ctly_th4t_345y_t0_c4ptur3_H0wev3r_1T_w1ll_b3_C00l_1F_Y0u_g0t_1t'
dword_6020C0 = [0x24,8,5,0x36,0x65,7,0x27,0x26,0x2d,1,3,0,0xd,0x56,1,3,0x65,3,0x2d,0x16,2,0x15,3,0x65,0,0x29,0x44,0x44,1,0x44,0x2b]
a = bytes([off_6020A0[dword_6020C0[v14]] for v14 in range(len(dword_6020C0))])
print(a)
#A3EXCTF{W3_L0v3_C_W1th_CL45535}
#ALEXCTF{W3_L0v3_C_W1th_CL45535}
29,湖湘杯2018_Replace
函数sub_401090转换查表
signed int __fastcall sub_401090(int a1, int a2)
{
......
buf = a1;
if ( a2 != 35 )
return -1;
v4 = 0;
while ( 1 )
{
v5 = *(_BYTE *)(v4 + buf);
v6 = (v5 >> 4) % 16; // 高4位
v7 = (16 * v5 >> 4) % 16; // 低4位
v8 = byte_402150[2 * v4];
if ( v8 < 48 || v8 > 57 )
v9 = v8 - 87;
else
v9 = v8 - 48;
v10 = byte_402151[2 * v4];
v11 = 16 * v9;
if ( v10 < 48 || v10 > 57 )
v12 = v10 - 87;
else
v12 = v10 - 48;
if ( (unsigned __int8)byte_4021A0[16 * v6 + v7] != ((v11 + v12) ^ 0x19) )
break;
if ( ++v4 >= 35 )
return 1;
}
return -1;
}
按原文写
a = b'2a49f69c38395cde96d6de96d6f4e025484954d6195448def6e2dad67786e21d5adae6'
b = bytes.fromhex(' 637C777BF26B6FC53001672BFED7AB76CA82C97DFA5947F0ADD4A2AF9CA472C0B7FD9326363FF7CC34A5E5F171D8311504C723C31896059A071280E2EB27B27509832C1A1B6E5AA0523BD6B329E32F8453D100ED20FCB15B6ACBBE394A4C58CFD0EFAAFB434D338545F9027F503C9FA851A3408F929D38F5BCB6DA2110FFF3D2CD0C13EC5F974417C4A77E3D645D197360814FDC222A908846EEB814DE5E0BDBE0323A0A4906245CC2D3AC629195E479E7C8376D8DD54EA96C56F4EA657AAE08BA78252E1CA6B4C6E8DD741F4BBD8B8A703EB5664803F60E613557B986C11D9EE1F8981169D98E949B1E87E9CE5528DF8CA1890DBFE6426841992D0FB054BB16')
flag = ''
for i in range(35):
v8 = a[2*i]
if (v8 < 48) or ( v8 > 57):
v9 = v8 - 87
else:
v9 = v8 - 48
v11 = (v9*16)&0xff
v10 = a[2*i + 1]
if (v10 < 48) or (v10 >57):
v12 = v10 - 87
else:
v12 = v10 - 48
flag += chr(b.index((v11+v12)^0x19))
print(flag)
#flag{Th1s_1s_Simple_Rep1ac3_Enc0d3}
30,2019_SUCTF_Signln
这是个入门的rsa,估计走错棚了
puts("[sign in]");
printf("[input your flag]: ", a2);
__isoc99_scanf("%99s", &v8);
sub_96A(&v8, (__int64)&v9); // base16
__gmpz_init_set_str(&v7, "ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35", 16LL);
__gmpz_init_set_str(&v6, &v9, 16LL);
__gmpz_init_set_str(&v4, "103461035900816914121390101299049044413950405173712170434161686539878160984549", 10LL);
__gmpz_init_set_str(&v5, "65537", 10LL);
__gmpz_powm(&v6, &v6, &v5, &v4);
if ( (unsigned int)__gmpz_cmp(&v6, &v7) )
puts("GG!");
else
puts("TTTTTTTTTTql!");
解rsa
from gmpy2 import *
n = 103461035900816914121390101299049044413950405173712170434161686539878160984549
p = 282164587459512124844245113950593348271
q = 366669102002966856876605669837014229419
e = 65537
phi_n = (p-1)*(q-1)
d = invert(e, phi_n)
c = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
m = pow(c,d,n)
print(bytes.fromhex(hex(m)[2:]))
#suctf{Pwn_@_hundred_years}