本身想说用KALi运行一下的。但是有个啥错误..
管他的。我们已经知道了这个程序是64位的无壳的。放入IDA看看
看到这个Decry函数,很明显这个函数是解这个题的关键
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 unsigned __int64 Decry () { char v1; int v2; int v3; int i; int v5; char src[8 ]; __int64 v7; int v8; __int64 v9[2 ]; int v10; unsigned __int64 v11; v11 = __readfsqword(0x28 u); *(_QWORD *)src = 0x534C43444E LL; v7 = 0LL ; v8 = 0 ; v9[0 ] = 0x776F646168 LL; v9[1 ] = 0LL ; v10 = 0 ; text = (char *)join(key3, v9); strcpy (key, key1); strcat (key, src); v2 = 0 ; v3 = 0 ; getchar(); v5 = strlen (key); for ( i = 0 ; i < v5; ++i ) { if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 ) key[i] = key[v3 % v5] + 32 ; ++v3; } printf ("Please input your flag:" ); while ( 1 ) { v1 = getchar(); if ( v1 == 10 ) break ; if ( v1 == 32 ) { ++v2; } else { if ( v1 <= 96 || v1 > 122 ) { if ( v1 > 64 && v1 <= 90 ) { str2[v2] = (v1 - 39 - key[v3 % v5] + 97 ) % 26 + 97 ; ++v3; } } else { str2[v2] = (v1 - 39 - key[v3 % v5] + 97 ) % 26 + 97 ; ++v3; } if ( !(v3 % v5) ) putchar (32 ); ++v2; } } if ( !strcmp (text, str2) ) puts ("Congratulation!\n" ); else puts ("Try again!\n" ); return __readfsqword(0x28 u) ^ v11; }
为什么这里的src 是 NDCLS呢?
通过点击src
发现是高地址在上面,这种就是大端存放。高地址放高位
https://blog.csdn.net/xiao__1bai/article/details/122845061
所以现在主要的目的就是逆向
1 str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
这句话
所以text = killshadow
str2是输入的。
key = adsfkndcls
就是说:你输入的字符串经过str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;变化后所组成的新的字符串str2和原本的text=”killshadow”相等就能得到flag。
现在就是知道了密文就是text = killshadow,然后加密中间用到的key = adsfkndcls 求出明文就可了。
下面就是写脚本
爆破思想 C代码 这个是我的作法【下面的是网上找到的Wp】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <stdio.h> int main () { char a[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ; char key[] = "adsfkndcls" ; char text[] = "killshadow" ; char b[15 ]; for (int i = 0 ; i < 10 ; ++i) { for (int j = 0 ; j < 26 ; ++j) { b[i] = (a[j] - 39 - key[i] + 97 ) % 26 + 97 ; if (b[i] == text[i]) { printf ("%c" , a[j]); } } } return 0 ;
这个是没改进前
改进后
逆向写代码。 1.python 1 2 3 4 5 6 7 8 9 10 11 12 13 str2 = 'killshadow' key = 'adsfkndcls' v3=0 v5=len (key) flag=[0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ] for i in range (0 ,4 ): for j in range (0 ,10 ): v1=(ord (str2[j])-97 )+26 *i+ord (key[v3%v5])-58 if (v1>65 and v1<=90 ): flag[j]=chr (v1) v3=v3+1 for i in flag: print (i,end="" )
2.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <stdio.h> #include <stdlib.h> #include <string.h> using namespace std ; int main () { char key[] = "adsfkndcls" ; char text[] = "killshadow" ; char flag[15 ] = { 0 }; char v1; int text_ = strlen (text); for (int i = 0 ; i < text_; i++) { for (int j = 0 ;; j++) { v1 = text[i] - 97 + 26 * j - 58 + key[i]; if ('A' <= v1 && v1 <= 'Z' ) { break ; } } flag[i] = v1; } printf ("%s" , flag); return 0 ; }
因为不知道%26后得到的答案是几,所以用(int j;;j++)来无限例举
flag{KLDQCUDFZO}
KLDQCUDFZO