CISCN RE 部分wp

CISCN re 部分wp

glass

jeb打开,发现加密过程在so文件里面

ida看so文件

查看自己的加密函数

解密1


	unsigned char flag[39]={ 0xA3, 0x1A, 0xE3, 0x69, 0x2F, 0xBB, 0x1A, 0x84, 0x65, 0xC2, 
	  0xAD, 0xAD, 0x9E, 0x96, 0x05, 0x02, 0x1F, 0x8E, 0x36, 0x4F, 
	  0xE1, 0xEB, 0xAF, 0xF0, 0xEA, 0xC4, 0xA8, 0x2D, 0x42, 0xC7, 
	  0x6E, 0x3F, 0xB0, 0xD3, 0xCC, 0x78, 0xF9, 0x98, 0x3F,};
	char key[]="12345678";
	#include<stdio.h>
	
	int main()
	{
		int i,j,k,a,b,c;
		int len_key=8,len_flag=39;
		unsigned char *p=flag;
		
		for ( j = 0; j < len_flag; j += len_key )
		{
			for ( k = 0; (len_key & ~(len_key >> 31)) != k && j + k < len_flag; ++k )
		      p[k]^=key[k];
		    p += len_key;
		}
		
		for(i=0;i<len_flag;i+=3)
		{
		    a = flag[i];
		    b = flag[i+1];
		    c = flag[i+2];
		    
	//	    flag[i] = a ^ c;
	//	    flag[i+1] = b ^ a ^ c;
	//	    flag[i+2] = c ^ b;
	
		    flag[i+1] = b ^ a;
		    flag[i+2]=flag[i+2] ^  flag[i+1];
		    flag[i] = flag[i]^flag[i+2];
	  
		}
		for(i=0;i<39;i++)
		{
			printf("0x%02x,",flag[i]);
		}
	 } 
	//0xf8,0xba,0x6a,0x97,0x47,0xca,0xe8,0x91,0xc5,0x07,0x6e,0xf7,0x92,0x0b,0x39,0x92,0x14,0xa8,0xaf,0x7e,0xaa,0x50,0x45,0x8d,0x6d,0x2d,0xb6,0x86,0x6e,0x9f,0x86,0x5e,0xdf,0xb3,0x1e,0x52,0xa6,0x62,0x6a

rc4解密,也可以动调出要异或的对应值,回头学学怎么动调so文件


	#include<stdio.h>
	#include<string.h>
	typedef unsigned longULONG;
	
	void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
	{
	    int i = 0, j = 0;
	    char k[256] = { 0 };
	    unsigned char tmp = 0;
	    for (i = 0; i<256; i++)
	    {
	        s[i] = i;
	        k[i] = key[i%Len];
	    }
	    for (i = 0; i<256; i++)
	    {
	        j = (j + s[i] + k[i]) % 256;
	        tmp = s[i];
	        s[i] = s[j];
	        s[j] = tmp;
	    }
	}
	
	
	void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len)
	{
	    int i = 0, j = 0, t = 0;
	    unsigned long k = 0;
	    unsigned char tmp;
	    for (k = 0; k<Len; k++)
	    {
	        i = (i + 1) % 256;
	        j = (j + s[i]) % 256;
	        tmp = s[i];
	        s[i] = s[j];
	        s[j] = tmp;
	        t = (s[i] + s[j]) % 256;
	        Data[k] ^= s[t];
	    }
	}
	
	int main()
	{
	    unsigned char s[256] = { 0 }, s2[256] = { 0 };//S-box
	    char key[256] = { "12345678" };
	    char pData[512] = {0xf8, 0xba, 0x6a, 0x97, 0x47, 0xca, 0xe8, 0x91, 0xc5, 0x07, 0x6e, 0xf7, 0x92, 0x0b, 0x39, 0x92, 0x14, 0xa8, 0xaf, 0x7e, 0xaa, 0x50, 0x45, 0x8d, 0x6d, 0x2d, 0xb6, 0x86, 0x6e, 0x9f, 0x86, 0x5e, 0xdf, 0xb3, 0x1e, 0x52, 0xa6, 0x62, 0x6a};
	    unsigned long len = strlen(pData);
	    int i;
	
	    rc4_init(s, (unsigned char*)key, strlen(key));
	    for (i = 0; i<256; i++)
	    {
	        s2[i] = s[i];
	    }
	
	    rc4_crypt(s2, (unsigned char*)pData, len);
	    printf("pData=%s", pData);
	    return 0;
	}
	//CISCN{6654d84617f627c88846c172e0f4d46c}

baby_bc

bc文件为llvm字节码的二进制形式。

通过下面的指令转为elf


	clang -S -fobj-arc xxx.bc -o xxx.s
	
	clang xxx.s -o xxx

然后动调分析流程,发现是一个5*5的数独数组来作为flag,要满check里面的条件。

fill_number()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tx3NDpNx-1621353964787)(https://i.loli.net/2021/05/18/KqyRZPi4L1XMVsb.png)]
docheck(),这个函数就是限制函数,行列的数必须满足一些大小关系


	__int64 docheck()
	{
	  char v1; // [rsp+2Eh] [rbp-9Ah]
	  __int64 v2; // [rsp+30h] [rbp-98h]
	  __int64 v3; // [rsp+40h] [rbp-88h]
	  __int64 v4; // [rsp+50h] [rbp-78h]
	  __int64 v5; // [rsp+58h] [rbp-70h]
	  char *v6; // [rsp+68h] [rbp-60h]
	  __int64 v7; // [rsp+70h] [rbp-58h]
	  char v8; // [rsp+7Fh] [rbp-49h]
	  char *v9; // [rsp+88h] [rbp-40h]
	  __int64 v10; // [rsp+90h] [rbp-38h]
	  __int64 v11; // [rsp+98h] [rbp-30h]
	  __int64 v12; // [rsp+A8h] [rbp-20h]
	  char v13[6]; // [rsp+BCh] [rbp-Ch] BYREF
	  char v14[6]; // [rsp+C2h] [rbp-6h] BYREF
	
	  v12 = 0LL;
	  do
	  {
	    v10 = v12;
	    sub_401050(v14, 0LL, 6LL);
	    v9 = &v14[(unsigned __int8)map[5 * v12]];
	    if ( *v9
	      || (*v9 = 1, v14[(unsigned __int8)map[5 * v12 + 1]])
	      || (v14[(unsigned __int8)map[5 * v12 + 1]] = 1, v14[(unsigned __int8)map[5 * v12 + 2]])
	      || (v14[(unsigned __int8)map[5 * v12 + 2]] = 1, v14[(unsigned __int8)map[5 * v12 + 3]])
	      || (v14[(unsigned __int8)map[5 * v12 + 3]] = 1, v14[(unsigned __int8)map[5 * v12 + 4]]) )
	    {
	      v8 = 0;
	      return v8 & 1;
	    }
	    ++v12;
	  }
	  while ( v10 + 1 < 5 );
	  v11 = 0LL;
	  while ( 1 )
	  {
	    v7 = v11;
	    sub_401050(v13, 0LL, 6LL);
	    v6 = &v13[(unsigned __int8)map[v11]];
	    if ( *v6 )
	      break;
	    *v6 = 1;
	    if ( v13[(unsigned __int8)byte_404055[v11]] )
	      break;
	    v13[(unsigned __int8)byte_404055[v11]] = 1;
	    if ( v13[(unsigned __int8)byte_40405A[v11]] )
	      break;
	    v13[(unsigned __int8)byte_40405A[v11]] = 1;
	    if ( v13[(unsigned __int8)byte_40405F[v11]] )
	      break;
	    v13[(unsigned __int8)byte_40405F[v11]] = 1;
	    if ( v13[(unsigned __int8)byte_404064[v11]] )
	      break;
	    ++v11;
	    if ( v7 + 1 >= 5 )
	    {
	      v5 = 0LL;
	      while ( 1 )
	      {
	        v4 = v5;
	        if ( row[4 * v5] == 1 )                 // v5=1 v5=4
	        {
	          if ( (unsigned __int8)map[5 * v5] < (unsigned __int8)map[5 * v5 + 1] )
	            goto LABEL_27;
	        }
	        else if ( row[4 * v5] == 2 && (unsigned __int8)map[5 * v5] > (unsigned __int8)map[5 * v5 + 1] )// v5=2
	        {
	LABEL_27:
	          v8 = 0;
	          return v8 & 1;
	        }
	        if ( byte_404071[4 * v5] == 1 )         // no
	        {
	          if ( (unsigned __int8)map[5 * v5 + 1] < (unsigned __int8)map[5 * v5 + 2] )
	            goto LABEL_27;
	        }
	        else if ( byte_404071[4 * v5] == 2 && (unsigned __int8)map[5 * v5 + 1] > (unsigned __int8)map[5 * v5 + 2] )// no
	        {
	          goto LABEL_27;
	        }
	        if ( byte_404072[4 * v5] == 1 )         // v5=4
	        {
	          if ( (unsigned __int8)map[5 * v5 + 2] < (unsigned __int8)map[5 * v5 + 3] )
	            goto LABEL_27;
	        }
	        else if ( byte_404072[4 * v5] == 2 && (unsigned __int8)map[5 * v5 + 2] > (unsigned __int8)map[5 * v5 + 3] )// no
	        {
	          goto LABEL_27;
	        }
	        if ( byte_404073[4 * v5] == 1 )         // v5=2 v5=0
	        {
	          if ( (unsigned __int8)map[5 * v5 + 3] < (unsigned __int8)map[5 * v5 + 4] )
	            goto LABEL_27;
	        }
	        else if ( byte_404073[4 * v5] == 2 && (unsigned __int8)map[5 * v5 + 3] > (unsigned __int8)map[5 * v5 + 4] )// no
	        {
	          goto LABEL_27;
	        }
	        ++v5;
	        if ( v4 + 1 >= 5 )
	        {
	          v3 = 0LL;
	          while ( 1 )
	          {
	            v2 = v3 + 1;
	            if ( col[5 * v3] == 1 )             // no
	            {
	              v1 = 0;
	              if ( (unsigned __int8)map[5 * v3] > (unsigned __int8)map[5 * v2] )
	                goto LABEL_26;
	            }
	            else if ( col[5 * v3] == 2 )        // no
	            {
	              v1 = 0;
	              if ( (unsigned __int8)map[5 * v3] < (unsigned __int8)map[5 * v2] )
	              {
	LABEL_26:
	                v8 = v1;
	                return v8 & 1;
	              }
	            }
	            if ( byte_404091[5 * v3] == 1 )     // v3=3
	            {
	              v1 = 0;
	              if ( (unsigned __int8)map[5 * v3 + 1] > (unsigned __int8)map[5 * v2 + 1] )
	                goto LABEL_26;
	            }
	            else if ( byte_404091[5 * v3] == 2 )// no
	            {
	              v1 = 0;
	              if ( (unsigned __int8)map[5 * v3 + 1] < (unsigned __int8)map[5 * v2 + 1] )
	                goto LABEL_26;
	            }
	            if ( byte_404092[5 * v3] == 1 )     // no
	            {
	              v1 = 0;
	              if ( (unsigned __int8)map[5 * v3 + 2] > (unsigned __int8)map[5 * v2 + 2] )
	                goto LABEL_26;
	            }
	            else if ( byte_404092[5 * v3] == 2 )// v3=0 v2=1
	            {
	              v1 = 0;
	              if ( (unsigned __int8)map[5 * v3 + 2] < (unsigned __int8)map[5 * v2 + 2] )
	                goto LABEL_26;
	            }
	            if ( byte_404093[5 * v3] == 1 )     // v3=2
	            {
	              v1 = 0;
	              if ( (unsigned __int8)map[5 * v3 + 3] > (unsigned __int8)map[5 * v2 + 3] )
	                goto LABEL_26;
	            }
	            else if ( byte_404093[5 * v3] == 2 )// no
	            {
	              v1 = 0;
	              if ( (unsigned __int8)map[5 * v3 + 3] < (unsigned __int8)map[5 * v2 + 3] )
	                goto LABEL_26;
	            }
	            if ( byte_404094[5 * v3] == 1 )     // v3=3
	            {
	              v1 = 0;
	              if ( (unsigned __int8)map[5 * v3 + 4] > (unsigned __int8)map[5 * v2 + 4] )
	                goto LABEL_26;
	            }
	            else if ( byte_404094[5 * v3] == 2 )// v3=0
	            {
	              v1 = 0;
	              if ( (unsigned __int8)map[5 * v3 + 4] < (unsigned __int8)map[5 * v2 + 4] )
	                goto LABEL_26;
	            }
	            ++v3;
	            v1 = 1;
	            if ( v2 >= 4 )
	              goto LABEL_26;
	          }
	        }
	      }
	    }
	  }
	  v8 = 0;
	  return v8 & 1;
	}

分析前面的一部分应该是判断,每一行,每一列都是1~5构成,后面的if判断就是大小比较,我注释的v2,v3,v5的值可以找到5*5数独表中相应数字的位置,然后进行大小关系限制,no就代表这个if没什么用。

大概判断限定如下

用z3来解


from z3 import *
s = Solver()

flag=[0]*36

for i in range(25):
    flag[i] = Int('flag['+str(i)+']')
for i in range(25):
    s.add(flag[i]>=1)
    s.add(flag[i]<=5)

s.add(flag[12]==4)
s.add(flag[18]==3)


s.add(flag[2]>flag[7])
s.add(flag[3]>flag[4])
s.add(flag[4]>flag[9])
s.add(flag[5]>flag[6])
s.add(flag[11]>flag[10])
s.add(flag[13]>flag[14])
s.add(flag[18]>flag[13])
s.add(flag[21]>flag[16])
s.add(flag[24]>flag[19])
s.add(flag[20]>flag[21])

for i in range(5):
    s.add(flag[i * 5] != flag[i * 5 + 1])
    s.add(flag[i * 5] != flag[i * 5 + 2])
    s.add(flag[i * 5] != flag[i * 5 + 3])
    s.add(flag[i * 5] != flag[i * 5 + 4])
    s.add(flag[i * 5 + 1] != flag[i * 5 + 2])
    s.add(flag[i * 5 + 1] != flag[i * 5 + 3])
    s.add(flag[i * 5 + 1] != flag[i * 5 + 4])
    s.add(flag[i * 5 + 2] != flag[i * 5 + 3])
    s.add(flag[i * 5 + 2] != flag[i * 5 + 4])
    s.add(flag[i * 5 + 3] != flag[i * 5 + 4])

i=0
for j in range(5):
    s.add(flag[j] != flag[1 * 5 + j])
    s.add(flag[j] != flag[2 * 5 + j])
    s.add(flag[j] != flag[3 * 5 + j])
    s.add(flag[j] != flag[4 * 5 + j])
    s.add(flag[5 + j] != flag[4 * 5 + j])
    s.add(flag[5 + j] != flag[3 * 5 + j])
    s.add(flag[5 + j] != flag[4 * 5 + j])
    s.add(flag[10 + j] != flag[3 * 5 + j])
    s.add(flag[10 + j] != flag[4 * 5 + j])
    s.add(flag[15 + j] != flag[4 * 5 + j])

if s.check() == sat:
    model = s.model()
    str = [model[flag[i]].as_long().real for i in range(25)]
    for i in range(25):
        print(str[i],end='')
else:
    print("no_sat")
#CISCN{MD5(1425353142350212150442315)} 

CISCN_gift

涉及到了没学过的知识点,后面学了来补

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值