镇北看雪 发表于 2020-8-30 22:22

GACTF 2020逆向部分WP

本帖最后由 镇北看雪 于 2020-9-1 22:25 编辑



# 前言
***

论坛和网上还有很多解析,每个人思路有所不同有兴趣的可以结合着看。
# Simulator
***
这题的提示是Study 《Introduction to Computer System》 carefully,the format of flag is GACTF{},意思让我们好好学习计算机系统概论,计算机系统概论是一门计算机专业课,我们还没有教这门课。我们下面下载题目后看到题目是一个OBJ文件,懵逼OBJ文件怎么逆向吗!




不管了用WinHex打开看一下,发现一些关键字符。我们可以看到字符串意思是
Welcome to the world of LC3      
Please input you flag:
Sussess!
Your flag is xctf{{you input}}
Try again!



Welcome to the world of LC3,从来没有听说过LC3是什么东西。这时我想到了那句提示Study 《Introduction to Computer System》 carefully,那咱们就百度一下搜一搜《计算机系统概论》,还真发现了LC3。原来LC3是一款较为成熟的16位汇编程序运行调试软件,2003年时由美国得克萨斯州立大学的 Yale N. Patt 和伊利诺伊大学香槟分校的 Sanjay J. Patel 两位计算机科学教授开发完成。





我们需要下载LC-3模拟器,一般这个模拟器会包含一个供编写LC3汇编程序的软件LC3Edit.exe,一般用LC3Edit.exe编写LC3汇编程序会生成一个OBJ文件供用户调试,调试此OBJ文件的软件为Simulate.exe。




我们打开Simulate软件并导入OBJ文件,下面我们可以看到程序的LC3汇编代码。我在做的时候因为没接触过LC3汇编,上网搜结果资料及其少。不知道每一条指令的意思只好一步一步跟然后自己猜测并结合网上极其少的LC3汇编指令的注解将程序的主要逻辑搞明白了。



对其LC3代码的主要逻辑与算法逆向分析如下
```
Memory:
x30001110000001111010xE07A            LEA    R0, x307B      
x30011111000000100010xF022            TRAP   PUTS                           //向屏幕输出字符串:“Welcome to the world of LC3”   
x30020010000001110111x2077            LD   R0, x307A      
x30031111000000100001xF021            TRAP   OUT                           
x30041110000010010010xE092            LEA    R0, x3097                     
x30051111000000100010xF022            TRAP   PUTS                           //向屏幕输出字符串:"Please input you flag: "   
x30060010011011011110x26DE            LD   R3, x30E5                      //R3 = 0x18
x30071111000000100000xF020            TRAP   GETC                           //获得屏幕的输入的一个字符   
x30081111000000100001xF021            TRAP   OUT                            //将此字符显示到屏幕上
x30090010001011011010x22DA            LD   R1, x30E4                      //R1 = 0x4000
x300A0001001001000011x1243            ADD    R1, R1, R3                     //R1 = R1 + R3
x300B0111000001000000x7040            STR    R0, R1, #0                     // = R0
x300C0001011011111111x16FF            ADD    R3, R3, #-1                  //R3 = R3 - 1
x300D0000100000000001x0801            BRN    x300F                        //if(R3 == 0)跳转0x300F
x300E0000111111111000x0FF8            BRNZPx3007                        //无条件跳转到0x3007
x300F1110100011101111xE8EF            LEA    R4, x30FF                      //以上指令主要功能就是获得0x19个字符并将其倒序保存在0x4000开始的连续的内存空间中
x30100101010010100000x54A0            AND    R2, R2, #0   
x30110001001010000100x1284            ADD    R1, R2, R4   
x30120110001001000000x6240            LDR    R1, R1, #0   
x30130101000000100000x5020            AND    R0, R0, #0   
x30140010000001100010x2062            LD   R0, x3077      
x30151001000000111111x903F            NOT    R0, R0         
x30160001000000100001x1021            ADD    R0, R0, #1   
x30170001000001000000x1040            ADD    R0, R1, R0   
x30180000010000001010x040A            BRZ    x3023         
x30190010000001011110x205E            LD   R0, x3078      
x301A1001000000111111x903F            NOT    R0, R0         
x301B0001000000100001x1021            ADD    R0, R0, #1   
x301C0001000001000000x1040            ADD    R0, R1, R0   
x301D0000010000010111x0417            BRZ    x3035         
x301E0010000001011010x205A            LD   R0, x3079      
x301F1001000000111111x903F            NOT    R0, R0         
x30200001000000100001x1021            ADD    R0, R0, #1   
x30210001000001000000x1040            ADD    R0, R1, R0   
x30220000010000100101x0425            BRZ    x3048         
x30230001001010100001x12A1            ADD    R1, R2, #1   
x30240001001100000001x1301            ADD    R1, R4, R1   
x30250110001001000000x6240            LDR    R1, R1, #0   
x30260001110001100000x1C60            ADD    R6, R1, #0   
x30270001001010100010x12A2            ADD    R1, R2, #2   
x30280001001100000001x1301            ADD    R1, R4, R1   
x30290110001001000000x6240            LDR    R1, R1, #0   
x302A0010000010111001x20B9            LD   R0, x30E4      
x302B0001000001100000x1060            ADD    R0, R1, #0   
x302C0110000000000000x6000            LDR    R0, R0, #0   
x302D0001111000100000x1E20            ADD    R7, R0, #0   
x302E0001101001100000x1A60            ADD    R5, R1, #0   
x302F0000111000101001x0E29            BRNZPx3059         
x30300010001010110011x22B3            LD   R1, x30E4      
x30310001001101000001x1341            ADD    R1, R5, R1   
x30320111000001000000x7040            STR    R0, R1, #0   
x30330001010010100011x14A3            ADD    R2, R2, #3   
x30340000111111011100x0FDC            BRNZPx3011         
x30350001001010100001x12A1            ADD    R1, R2, #1   
x30360001001100000001x1301            ADD    R1, R4, R1   
x30370110001001000000x6240            LDR    R1, R1, #0   
x30380010000010101011x20AB            LD   R0, x30E4      
x30390001000000000001x1001            ADD    R0, R0, R1   
x303A0110110000000000x6C00            LDR    R6, R0, #0                      //R6 = flag                  
x303B0001001010100010x12A2            ADD    R1, R2, #2   
x303C0001001100000001x1301            ADD    R1, R4, R1   
x303D0110001001000000x6240            LDR    R1, R1, #0   
x303E0010000010100101x20A5            LD   R0, x30E4      
x303F0001000000000001x1001            ADD    R0, R0, R1   
x30400001101001100000x1A60            ADD    R5, R1, #0                     //R5 = n
x30410110111000000000x6E00            LDR    R7, R0, #0                     //R7 = flag
x30420000111000011000x0E18            BRNZPx305B                        //jmp 0x305B
x30430010001010100000x22A0            LD   R1, x30E4                      //R1 = 0x4000
x30440001001001000101x1245            ADD    R1, R1, R5                     //R1 = R1 + R5
x30450111000001000000x7040            STR    R0, R1, #0                     // = R0
x30460001010010100011x14A3            ADD    R2, R2, #3   
x30470000111111001001x0FC9            BRNZPx3011                        //jmp 0x3011
x30480001001010100001x12A1            ADD    R1, R2, #1   
x30490001001100000001x1301            ADD    R1, R4, R1   
x304A0110001001000000x6240            LDR    R1, R1, #0   
x304B0001110001100000x1C60            ADD    R6, R1, #0                     //R6 = n
x304C0001001010100010x12A2            ADD    R1, R2, #2   
x304D0001001100000001x1301            ADD    R1, R4, R1   
x304E0110001001000000x6240            LDR    R1, R1, #0   
x304F0010101010010101x2A95            LD   R5, x30E5      
x30501001001001111111x927F            NOT    R1, R1         
x30510001001001100001x1261            ADD    R1, R1, #1   
x30520001101101000001x1B41            ADD    R5, R5, R1                     //R5 = 0x18 - n
x30530001111101100000x1F60            ADD    R7, R5, #0                     //R7 = R5
x30540000111000001100x0E0C            BRNZPx3061                        //jmp 0x3061
x30550001101101100000x1B60            ADD    R5, R5, #0                     //关键跳转
x30560000010000010101x0415            BRZ    x306C                        //if(n == 0),则跳到0x306C,flag正确
x30570001010010100011x14A3            ADD    R2, R2, #3                     
x30580000111110111000x0FB8            BRNZPx3011         
x30590001000110000111x1187            ADD    R0, R6, R7   
x305A0000111111010101x0FD5            BRNZPx3030         
x305B1001000110111111x91BF            NOT    R0, R6                                       
x305C0101000000000111x5007            AND    R0, R0, R7                     //R0 = ~R6 & R7
x305D1001001111111111x93FF            NOT    R1, R7                        
x305E0101001110000001x5381            AND    R1, R6, R1                     //R1 = ^R7 & R6
x305F0001000001000000x1040            ADD    R0, R1, R0                     //R0 = R0 + R1
x30600000111111100010x0FE2            BRNZPx3043                        //jmp 0x3043
x30610010000010000010x2082            LD   R0, x30E4      
x30620001000000000110x1006            ADD    R0, R0, R6   
x30630110000000000000x6000            LDR    R0, R0, #0                     //R0 = 0x4000
x30641110001010000001xE281            LEA    R1, x30E6      
x30650001001001000111x1247            ADD    R1, R1, R7   
x30660110001001000000x6240            LDR    R1, R1, #0                     //R1 = 0x30EF
x30671001001001111111x927F            NOT    R1, R1         
x30680001001001100001x1261            ADD    R1, R1, #1                     //关键判断,跳转处
x30690001000000000001x1001            ADD    R0, R0, R1                     //if(R0 == R1)
x306A0000010111101010x05EA            BRZ    x3055                        //jmp 0x3055
x306B0000111000000101x0E05            BRNZPx3071         
x306C0010000000001101x200D            LD   R0, x307A                      //输出Success!   
x306D1111000000100001xF021            TRAP   OUT            
x306E1110000001000000xE040            LEA    R0, x30AF                      //输出Your flag is xctf{{you input}}
x306F1111000000100010xF022            TRAP   PUTS         
x30700000111000000101x0E05            BRNZPx3076         
x30710010000000001000x2008            LD   R0, x307A                      //输出Try again!
x30721111000000100001xF021            TRAP   OUT            
x30731110000001100101xE065            LEA    R0, x30D9                      //输出----- Halting the processor -----
x30741111000000100010xF022            TRAP   PUTS         
x30750000111000000000x0E00            BRNZPx3076         
x30761111000000100101xF025            TRAP   HALT         
x30770000000000010001x0011            NOP                  
x30780000000000010011x0013            NOP                  
x30790000000000010100x0014            NOP

```


算法大致就是对25个字符的flag进行加密后与0x30EF内存处的数组进行比较,我们在winHex中可以找到此数组的数据



而且由算法逆向可知,我们输入的flag的第一个字符必须为‘l’即值等于0x6c,最后我们根据其算法编写程序得到flag为:lc3_1s_small_but_complete

```
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{

      BYTE a;
      BYTE b;
      BYTE F[] ={0x6C,0x0f, 0x50, 0x6c, 0x6e, 0x42, 0x2c, 0x2c, 0x1e,
                           0x0c, 0x0d, 0x0,0x33, 0x3d, 0x17, 0x01, 0x2b,
                           0x3c, 0x0c, 0x02, 0x1d, 0x1c, 0x09, 0x11, 0x11};

      BYTE R1;
      BYTE R0;

      BYTE R5 = 24;
      BYTE R6 = 0;
      BYTE R7 = 24;

      for(int i = 0;i <= 24; i++)
      {
                R7 = 24 - i;
                R1 = F;
                R1 = ~R1;
                R1 = R1 + 1;
      
      
                b = R1;
      }


      BYTE yy2 = 1;
      BYTE yy1 = 1;
      BYTE rr = 1;
      BYTE yy11;

      while(1)
      {


                while(yy2 < 0xff)
                {
                        yy1 = 1;
                        while(yy1 < 0xff)      
                        {
                              rr = (((~yy1) & yy2) + ((~yy2) & yy1) +b);
                              if(rr == 0)
                              {
                                        if((yy1 >=0x21 && yy1<= 0x7e) && (yy2 >=0x21 && yy2<= 0x7e))
                                        {
                                                rr = 2;
                                                break;
                                        }
                              }      
                              yy1++;
                        }
                        if(rr == 2)
                              break;
                        yy2++;
                }


                a = yy2;
                a = yy1;

                for(int i = 23; i >= 1; i--)
                {
                        yy11 = 1;
                        while(yy11 < 0xff)      
                        {
                              rr = (((~yy11) & a) + ( ~a & yy11) +b);
                              if(rr == 0)
                              {
                                        if((yy11 >=0x21 && yy11<= 0x7e) && (yy2 >=0x21 && yy2<= 0x7e))
                                                break;
                              }      
                              yy11++;
                        }

                        a = yy11;

                }


                if(a == 'l')
                        break;
                yy2++;
                rr = 0;
      }

      printf("flag:%.24s\n", a);

      return 0 ;
}
```

下面是我在寻找LC3汇编时候搜的的一些资源,关于LC3汇编调试器的使用,以及其指令系统,有兴趣的可以看看。
https://my.oschina.net/Samyan/blog/1614174/print
https://wenku.baidu.com/view/c322be9ab14e852459fb573b.html


# WannaFlag
***

此软件我们用Exeinfope分析后得其为32位可执行文件,无壳。



然后我们直接拖入OD运行,软件的页面有点防勒索软件的意思,并且放着诡异的音乐。其提示为需要输入正确的KEY,从而获得flag。还可以支付给作者6666人民币获得,可笑身为吾爱破解的资深菜鸟怎么可能丢这个人。准备开干!


按照一般思路,其让输入key并判断key,那就肯定需要获取edit控件的key值。对一些获取edit控件值的API下断点,如GetWindowTextA/W,GetDlgItemTextA/W等等。
我们输入123456位key后按DECRYPT FLAG。程序断在了GetWindowTextA函数的入口处。



接着我们ALT+F9返回到用户空间中。我们往下看发现其调用MessagBoxA显示orz,意思就是我们成功了。其上方的一些跳转都是关键跳转。我们往上分析汇编代码的含义及其算法实现。



```
005D2847   .83C4 0C       add esp,0xC
005D284A   .8D8424 200200>lea eax,dword ptr ss:
005D2851   .6A 20         push 0x20                              ; /Count = 20 (32.)
005D2853   .50            push eax                                 ; |Buffer
005D2854   .56            push esi                                 ; |hWnd
005D2855   .FF15 FCB15E00 call Xdword ptr ds:            ; \GetWindowTextA
005D285B   .8DB424 200200>lea esi,dword ptr ss:
005D2862   .8D4E 01       lea ecx,dword ptr ds:
005D2865   >8A06          mov al,byte ptr ds:
005D2867   .46            inc esi
005D2868   .84C0          test al,al
005D286A   .^ 75 F9         jnz X005D2865
005D286C   .2BF1          sub esi,ecx
005D286E   .83FE 06       cmp esi,0x6
005D2871   .0F8C 6A010000 jl 005D29E1                              ;esi = key长度
005D2877   .0FBE8424 2402>movsx eax,byte ptr ss:
005D287F   .B9 07000000   mov ecx,0x7
005D2884   .99            cdq
005D2885   .F7F9          idiv ecx                                 ;edi = a % 7
005D2887   .8BFA          mov edi,edx
005D2889   .8D51 FA       lea edx,dword ptr ds:         ;edx = 1
005D288C   .B9 02000000   mov ecx,0x2                              ;ecx = 2
005D2891   .3BF9          cmp edi,ecx
005D2893   .7E 08         jle X005D289D
005D2895   >0FAFD1      imul edx,ecx                           ;edx * ecx
005D2898   .41            inc ecx                                  ;ecx = 3
005D2899   .3BCF          cmp ecx,edi
005D289B   .^ 7C F8         jl X005D2895
005D289D   >33C0          xor eax,eax
005D289F   .83FE 40       cmp esi,0x40
005D28A2   .0F82 7F000000 jb 005D2927
005D28A8   .8BCE          mov ecx,esi
005D28AA   .81E1 3F000080 and ecx,0x8000003F
005D28B0   .79 05         jns X005D28B7
005D28B2   .49            dec ecx
005D28B3   .83C9 C0       or ecx,0xFFFFFFC0
005D28B6   .41            inc ecx
005D28B7   >8BFE          mov edi,esi
005D28B9   .2BF9          sub edi,ecx
005D28BB   .0FBECA      movsx ecx,dl
005D28BE   .66:0F6EC1   movd mm0,ecx
005D28C2   .66:0F60C0   punpcklbw mm0,mm0
005D28C6   .66:0F61C0   punpcklwd mm0,mm0
005D28CA   .66:0F70C8 00pshufw mm1,mm0,0x0
005D28CF   .90            nop
005D28D0   >0F108404 2002>movups xmm0,dqword ptr ss:[esp+eax+0x220>
005D28D8   .66:0FEFC1   pxor mm0,mm1
005D28DC   .0F118404 7802>movups dqword ptr ss:,xmm>
005D28E4   .0F108404 3002>movups xmm0,dqword ptr ss:[esp+eax+0x230>
005D28EC   .66:0FEFC1   pxor mm0,mm1
005D28F0   .0F118404 8802>movups dqword ptr ss:,xmm>
005D28F8   .0F108404 4002>movups xmm0,dqword ptr ss:[esp+eax+0x240>
005D2900   .66:0FEFC1   pxor mm0,mm1
005D2904   .0F118404 9802>movups dqword ptr ss:,xmm>
005D290C   .0F108404 5002>movups xmm0,dqword ptr ss:[esp+eax+0x250>
005D2914   .66:0FEFC1   pxor mm0,mm1
005D2918   .0F118404 A802>movups dqword ptr ss:,xmm>
005D2920   .83C0 40       add eax,0x40
005D2923   .3BC7          cmp eax,edi
005D2925   .^ 7C A9         jl X005D28D0
005D2927   >3BC6          cmp eax,esi
005D2929   .7D 1A         jge X005D2945
005D292B      0F            db 0F
005D292C      1F            db 1F
005D292D      44            db 44                                    ;CHAR 'D'
005D292E      00            db 00
005D292F      00            db 00
005D2930   >8A8C04 200200>mov cl,byte ptr ss:       ;cl = key
005D2937   .32CA          xor cl,dl                              ;cl = cl ^ dl
005D2939   .888C04 780200>mov byte ptr ss:,cl       ;0x003ff9A0 = cl
005D2940   .40            inc eax                                  ;n++
005D2941   .3BC6          cmp eax,esi
005D2943   .^ 7C EB         jl X005D2930                           ;------------
005D2945   >C68404 780200>mov byte ptr ss:,0x0
005D294D   .33D2          xor edx,edx
005D294F   .90            nop
005D2950   >8A82 E00A5F00 mov al,byte ptr ds:      ;al = 0x00CE0AE1
005D2956   .8ACA          mov cl,dl
005D2958   .328414 780200>xor al,byte ptr ss:       ;al = al ^ 0x003ff9A0
005D295F   .D2C0          rol al,cl                              ;rol al , n
005D2961   .888414 780200>mov byte ptr ss:,al       ;0x003ff9A0 = AL
005D2968   .42            inc edx
005D2969   .3BD6          cmp edx,esi
005D296B   .^ 7C E3         jl X005D2950                           ;---------------------
005D296D   .8D8C24 780200>lea ecx,dword ptr ss:
005D2974   .BA D8785F00   mov edx,0x5F78D8                         ;全局数组0x5f78d8
005D2979   .BE 1B000000   mov esi,0x1B                           ;esi = 0x1B
005D297E   .66:90         nop
005D2980   >8B01          mov eax,dword ptr ds:               ;判断加密后的key与0x5F78D8内存处数组的数据是否相等
005D2982   .3B02          cmp eax,dword ptr ds:
005D2984      75 5B         jnz X005D29E1
005D2986   .83C1 04       add ecx,0x4
005D2989   .83C2 04       add edx,0x4
005D298C   .83EE 04       sub esi,0x4
005D298F   .^ 73 EF         jnb X005D2980
005D2991   .66:8B01       mov ax,word ptr ds:
005D2994   .66:3B02       cmp ax,word ptr ds:
005D2997   .75 48         jnz X005D29E1
005D2999   .8A41 02       mov al,byte ptr ds:
005D299C   .3A42 02       cmp al,byte ptr ds:
005D299F   .75 40         jnz X005D29E1
005D29A1   .6A 00         push 0x0                                 ; /Style = MB_OK|MB_APPLMODAL
005D29A3   .68 980C5F00   push 0x5F0C98                            ; |Title = "orz"
005D29A8   .68 980C5F00   push 0x5F0C98                            ; |Text = "orz"
005D29AD   .53            push ebx                                 ; |hOwner
005D29AE   .FF15 00B25E00 call Xdword ptr ds:            ; \MessageBoxA

```

我们在内存窗口中查看0x5f78d8地址处的数组的数据。


接着我们根据逆向算法写出程序求得真正的key为:wannaflag_is_just_a_paper_tiger
需要注意的是rol运算的逆向在c语言ror指令的实现注意字节的大小,解密程序如下。
```
#include <iostream>
#include <Windows.h>
using namespace std;
#include <stdio.h>
unsigned ror(unsigned val, int size);
int main()
{      

BYTE a = {0};
      BYTE b[ ] = { 0x4E, 0xAE, 0x61, 0xBA, 0xE4, 0x2B, 0x55, 0xAA, 0x59, 0xFC, 0x4D, 0x02, 0x17, 0x6B, 0x13, 0xA1,
                                  0x41, 0xFE, 0x35, 0x0B, 0xB4, 0x0B, 0x52, 0x2F, 0x46, 0xCC, 0x35, 0x82, 0xE5, 0x88, 0x50};

      BYTE c[ ] = "ANNAWGALFYBKVIAHMXTFCAACLAAAAYK";
      BYTE d = {0};
      for(int i = 0; i < 31; i++)
      {

                a = ror(b,i) ^ c;
      
      }
      BYTE flag = 0;
      while(1)
      {
      

                for(int i = 0; i < 31; i++)
                {
                        d = flag ^ a;
      
                }
      
                BYTE WW = 2;
                BYTE WW2 = 1;
                while((d % 7) > WW)
                {
                        WW2 = WW2 * WW;
                        WW++;
                }
                if(flag == WW2)
                        break;
                flag++;
      }


      printf("flag:%s\n", d);

}



unsigned ror(unsigned val, int size)
{
unsigned res = val >> (size) % 8;
res |= val << (8 - (size % 8)) ;
return res;
}
```
接着输入正确的key后用OD我们运行程序,发现程序利用key和flag.bin中的数据结合解密函数得到flag。并生成flag.txt文件,将flag写进去。




# Checkin
***

还是用Excinfope程序查壳,发现文件为32位程序无壳直接载入OD。
我们单步向下跟踪发现岂会利用内存映射文件,将自身文件的附件数据通过创建文件并写入。


接着单步往下跟踪我们发现其实际是在路径C:\Users\ADMINI~1\AppData\Local\Temp\ocrA147.tmp下创建大量文件。



我们继续向下单步跟踪发现岂会创建一个新的进程,C:\Users\ADMINI~1\AppData\Local\Temp\ocrA147.tmp\bin\ruby.exe。此程序也是刚刚程序自己生成的文件。其通过CteateProessA创建此程序后,调用WaitForSingleObject()函数等待进程返回(此函数为阻塞函数)。当进程返回后程序调用GetExitCodeProess()获得程序结束的代码作进一步处理。


我们在WaitForSingleObject调用的下一条指令下断点,运行程序输入flag回车后,显示no,且WaitForSingleObjet函数返回,程序中断在刚刚下的断点处。




我们查看程序为单线程,所以不可能是此程序的其他线程进行的flag的判断。所以肯定是CreateProessA创建的Ruby.exe进行的判断。
我们来到ruby程序的文件夹下发现实际此程序是ruby编程语言脚本的执行程序。


我们在C:\Users\Administrator\AppData\Local\Temp\ocrA147.tmp\src目录下找到待执行的rb文件,其代码如下主要是采用了aes和base64加密。

```
require 'openssl'
require 'base64'


def aes_encrypt(key,encrypted_string)
      aes = OpenSSL::Cipher.new("AES-128-ECB")
      aes.encrypt
      aes.key = key
      cipher = aes.update(encrypted_string) << aes.final
      return Base64.encode64(cipher)
end

print "Enter flag: "
flag = gets.chomp

key = "Welcome_To_GACTF"
cipher = "4KeC/Oj1McI4TDIM2c9Y6ahahc6uhpPbpSgPWktXFLM=\n"

text = aes_encrypt(key,flag)
if cipher == text
      puts "good!"
else
      puts "no!"
End
```

我们由加密程序写出解密程序,代码如下

```
require 'openssl'
require 'base64'

def aes_dicrypt(key,dicrypted_string)
      cipher = Base64.decode64(dicrypted_string)         
               
      aes = OpenSSL::Cipher.new("AES-128-ECB")
      aes.decrypt
      aes.key = key
      cipher = aes.update(cipher) << aes.final

      return cipher


end

key = "Welcome_To_GACTF"
cipher = "4KeC/Oj1McI4TDIM2c9Y6ahahc6uhpPbpSgPWktXFLM=\n"

flag = aes_dicrypt(key,cipher)
printf("flag:%s\n",flag)
```

在cmd命令行运行程序得到flag。

我同时好奇其是如何从一个程序(ruby.exe)在另一个程序的cmd获得控制台输入的,经过对ruby的逆向分析发现。其实通过建立与Checkin.exe程序之间的管道,ruby.exe通过管道借助ReadFile()函数来获得Checkin.exe的控制台的输入的。


gink 发表于 2020-8-31 09:47

镇北看雪 发表于 2020-8-31 09:44
不是吧,这比赛不就前10名才有机会。后面的都是陪跑我觉得没什么关系才发的,要不然我是不会发的

不管什么时候规则也需要遵守,这是最基本的底线,你可以比赛结束后24小时发表wp,但是比赛时就发布wp,我可以认为你是在向比赛规则挑衅。

Hmily 发表于 2020-9-3 18:03

镇北看雪 发表于 2020-8-31 09:44
不是吧,这比赛不就前10名才有机会。后面的都是陪跑我觉得没什么关系才发的,要不然我是不会发的

@gink 说的很有道理,比赛没结束,确实禁止公开讨论,现在结束了吗?如果没结束把帖子权限编辑一下,不要公开。

haidaoxiangjiao 发表于 2020-8-30 22:44

支持支持 太猛

nj2004 发表于 2020-8-31 00:59

厉害,高手   。

gink 发表于 2020-8-31 09:42

GACTF比赛还未结束,你就投稿wp,一般个人wp在比赛结束后24小时才能发出,你这样严重违反比赛规则,建议撤销帖子

镇北看雪 发表于 2020-8-31 09:44

gink 发表于 2020-8-31 09:42
GACTF比赛还未结束,你就投稿wp,一般个人wp在比赛结束后24小时才能发出,你这样严重违反比赛规则,建议撤 ...

不是吧,这比赛不就前10名才有机会。后面的都是陪跑我觉得没什么关系才发的,要不然我是不会发的

Airey 发表于 2020-9-1 17:22

坐等大佬

dravenkali 发表于 2020-9-1 17:43

抓紧学习一下

lifz888 发表于 2020-9-2 07:56

不错的分析,支持分享
页: [1] 2
查看完整版本: GACTF 2020逆向部分WP