吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4125|回复: 13
收起左侧

[CTF] GACTF 2020逆向部分WP

  [复制链接]
镇北看雪 发表于 2020-8-30 22:22
本帖最后由 镇北看雪 于 2020-9-1 22:25 编辑

前言


论坛和网上还有很多解析,每个人思路有所不同有兴趣的可以结合着看。

Simulator


这题的提示是Study 《Introduction to Computer System》 carefully,the format of flag is GACTF{},意思让我们好好学习计算机系统概论,计算机系统概论是一门计算机专业课,我们还没有教这门课。  我们下面下载题目后看到题目是一个OBJ文件,懵逼OBJ文件怎么逆向吗!

67O(ZEBRMRQU9$K])K}D4H5.png

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

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

~$~SHC)5_0%%X83({QJUNZJ.png

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

7BWL5J5]M``_U0`OTA)Z(C4.png

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

G[}PC`IKVY662SK)36G0YTD.png

对其LC3代码的主要逻辑与算法逆向分析如下

Memory:
x3000  1110000001111010  xE07A            LEA    R0, x307B      
x3001  1111000000100010  xF022            TRAP   PUTS                           //向屏幕输出字符串:“Welcome to the world of LC3”     
x3002  0010000001110111  x2077            LD     R0, x307A      
x3003  1111000000100001  xF021            TRAP   OUT                            
x3004  1110000010010010  xE092            LEA    R0, x3097                      
x3005  1111000000100010  xF022            TRAP   PUTS                           //向屏幕输出字符串:"Please input you flag: "   
x3006  0010011011011110  x26DE            LD     R3, x30E5                      //R3 = 0x18
x3007  1111000000100000  xF020            TRAP   GETC                           //获得屏幕的输入的一个字符   
x3008  1111000000100001  xF021            TRAP   OUT                            //将此字符显示到屏幕上
x3009  0010001011011010  x22DA            LD     R1, x30E4                      //R1 = 0x4000
x300A  0001001001000011  x1243            ADD    R1, R1, R3                     //R1 = R1 + R3
x300B  0111000001000000  x7040            STR    R0, R1, #0                     //[R1] = R0
x300C  0001011011111111  x16FF            ADD    R3, R3, #-1                    //R3 = R3 - 1
x300D  0000100000000001  x0801            BRN    x300F                          //if(R3 == 0)跳转0x300F
x300E  0000111111111000  x0FF8            BRNZP  x3007                          //无条件跳转到0x3007
x300F  1110100011101111  xE8EF            LEA    R4, x30FF                      //以上指令主要功能就是获得0x19个字符并将其倒序保存在0x4000开始的连续的内存空间中
x3010  0101010010100000  x54A0            AND    R2, R2, #0     
x3011  0001001010000100  x1284            ADD    R1, R2, R4     
x3012  0110001001000000  x6240            LDR    R1, R1, #0     
x3013  0101000000100000  x5020            AND    R0, R0, #0     
x3014  0010000001100010  x2062            LD     R0, x3077      
x3015  1001000000111111  x903F            NOT    R0, R0         
x3016  0001000000100001  x1021            ADD    R0, R0, #1     
x3017  0001000001000000  x1040            ADD    R0, R1, R0     
x3018  0000010000001010  x040A            BRZ    x3023          
x3019  0010000001011110  x205E            LD     R0, x3078      
x301A  1001000000111111  x903F            NOT    R0, R0         
x301B  0001000000100001  x1021            ADD    R0, R0, #1     
x301C  0001000001000000  x1040            ADD    R0, R1, R0     
x301D  0000010000010111  x0417            BRZ    x3035          
x301E  0010000001011010  x205A            LD     R0, x3079      
x301F  1001000000111111  x903F            NOT    R0, R0         
x3020  0001000000100001  x1021            ADD    R0, R0, #1     
x3021  0001000001000000  x1040            ADD    R0, R1, R0     
x3022  0000010000100101  x0425            BRZ    x3048          
x3023  0001001010100001  x12A1            ADD    R1, R2, #1     
x3024  0001001100000001  x1301            ADD    R1, R4, R1     
x3025  0110001001000000  x6240            LDR    R1, R1, #0     
x3026  0001110001100000  x1C60            ADD    R6, R1, #0     
x3027  0001001010100010  x12A2            ADD    R1, R2, #2     
x3028  0001001100000001  x1301            ADD    R1, R4, R1     
x3029  0110001001000000  x6240            LDR    R1, R1, #0     
x302A  0010000010111001  x20B9            LD     R0, x30E4      
x302B  0001000001100000  x1060            ADD    R0, R1, #0     
x302C  0110000000000000  x6000            LDR    R0, R0, #0     
x302D  0001111000100000  x1E20            ADD    R7, R0, #0     
x302E  0001101001100000  x1A60            ADD    R5, R1, #0     
x302F  0000111000101001  x0E29            BRNZP  x3059          
x3030  0010001010110011  x22B3            LD     R1, x30E4      
x3031  0001001101000001  x1341            ADD    R1, R5, R1     
x3032  0111000001000000  x7040            STR    R0, R1, #0     
x3033  0001010010100011  x14A3            ADD    R2, R2, #3     
x3034  0000111111011100  x0FDC            BRNZP  x3011          
x3035  0001001010100001  x12A1            ADD    R1, R2, #1     
x3036  0001001100000001  x1301            ADD    R1, R4, R1     
x3037  0110001001000000  x6240            LDR    R1, R1, #0     
x3038  0010000010101011  x20AB            LD     R0, x30E4      
x3039  0001000000000001  x1001            ADD    R0, R0, R1     
x303A  0110110000000000  x6C00            LDR    R6, R0, #0                      //R6 = flag[0x18 - n - 1]                  
x303B  0001001010100010  x12A2            ADD    R1, R2, #2     
x303C  0001001100000001  x1301            ADD    R1, R4, R1     
x303D  0110001001000000  x6240            LDR    R1, R1, #0     
x303E  0010000010100101  x20A5            LD     R0, x30E4      
x303F  0001000000000001  x1001            ADD    R0, R0, R1     
x3040  0001101001100000  x1A60            ADD    R5, R1, #0                     //R5 = n
x3041  0110111000000000  x6E00            LDR    R7, R0, #0                     //R7 = flag[0x18 - n]
x3042  0000111000011000  x0E18            BRNZP  x305B                          //jmp 0x305B
x3043  0010001010100000  x22A0            LD     R1, x30E4                      //R1 = 0x4000
x3044  0001001001000101  x1245            ADD    R1, R1, R5                     //R1 = R1 + R5
x3045  0111000001000000  x7040            STR    R0, R1, #0                     //[R1] = R0
x3046  0001010010100011  x14A3            ADD    R2, R2, #3     
x3047  0000111111001001  x0FC9            BRNZP  x3011                          //jmp 0x3011
x3048  0001001010100001  x12A1            ADD    R1, R2, #1     
x3049  0001001100000001  x1301            ADD    R1, R4, R1     
x304A  0110001001000000  x6240            LDR    R1, R1, #0     
x304B  0001110001100000  x1C60            ADD    R6, R1, #0                     //R6 = n
x304C  0001001010100010  x12A2            ADD    R1, R2, #2     
x304D  0001001100000001  x1301            ADD    R1, R4, R1     
x304E  0110001001000000  x6240            LDR    R1, R1, #0     
x304F  0010101010010101  x2A95            LD     R5, x30E5      
x3050  1001001001111111  x927F            NOT    R1, R1         
x3051  0001001001100001  x1261            ADD    R1, R1, #1     
x3052  0001101101000001  x1B41            ADD    R5, R5, R1                     //R5 = 0x18 - n
x3053  0001111101100000  x1F60            ADD    R7, R5, #0                     //R7 = R5
x3054  0000111000001100  x0E0C            BRNZP  x3061                          //jmp 0x3061
x3055  0001101101100000  x1B60            ADD    R5, R5, #0                     //关键跳转
x3056  0000010000010101  x0415            BRZ    x306C                          //if(n == 0),则跳到0x306C,flag正确
x3057  0001010010100011  x14A3            ADD    R2, R2, #3                     
x3058  0000111110111000  x0FB8            BRNZP  x3011          
x3059  0001000110000111  x1187            ADD    R0, R6, R7     
x305A  0000111111010101  x0FD5            BRNZP  x3030          
x305B  1001000110111111  x91BF            NOT    R0, R6                                         
x305C  0101000000000111  x5007            AND    R0, R0, R7                     //R0 = ~R6 & R7
x305D  1001001111111111  x93FF            NOT    R1, R7                         
x305E  0101001110000001  x5381            AND    R1, R6, R1                     //R1 = ^R7 & R6
x305F  0001000001000000  x1040            ADD    R0, R1, R0                     //R0 = R0 + R1
x3060  0000111111100010  x0FE2            BRNZP  x3043                          //jmp 0x3043
x3061  0010000010000010  x2082            LD     R0, x30E4      
x3062  0001000000000110  x1006            ADD    R0, R0, R6     
x3063  0110000000000000  x6000            LDR    R0, R0, #0                     //R0 = 0x4000[n]
x3064  1110001010000001  xE281            LEA    R1, x30E6      
x3065  0001001001000111  x1247            ADD    R1, R1, R7     
x3066  0110001001000000  x6240            LDR    R1, R1, #0                     //R1 = 0x30EF[0x18 - n]
x3067  1001001001111111  x927F            NOT    R1, R1         
x3068  0001001001100001  x1261            ADD    R1, R1, #1                     //关键判断,跳转处
x3069  0001000000000001  x1001            ADD    R0, R0, R1                     //if(R0 == R1)
x306A  0000010111101010  x05EA            BRZ    x3055                          //jmp 0x3055
x306B  0000111000000101  x0E05            BRNZP  x3071          
x306C  0010000000001101  x200D            LD     R0, x307A                      //输出Success!     
x306D  1111000000100001  xF021            TRAP   OUT            
x306E  1110000001000000  xE040            LEA    R0, x30AF                      //输出Your flag is xctf{{you input}}
x306F  1111000000100010  xF022            TRAP   PUTS           
x3070  0000111000000101  x0E05            BRNZP  x3076          
x3071  0010000000001000  x2008            LD     R0, x307A                      //输出Try again!
x3072  1111000000100001  xF021            TRAP   OUT            
x3073  1110000001100101  xE065            LEA    R0, x30D9                      //输出----- Halting the processor -----
x3074  1111000000100010  xF022            TRAP   PUTS           
x3075  0000111000000000  x0E00            BRNZP  x3076          
x3076  1111000000100101  xF025            TRAP   HALT           
x3077  0000000000010001  x0011            NOP                   
x3078  0000000000010011  x0013            NOP                   
x3079  0000000000010100  x0014            NOP  

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

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

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

        BYTE a[25];
        BYTE b[25];
        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[R7];
                R1 = ~R1;
                R1 = R1 + 1;

                b[i] = 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[0]);
                                if(rr == 0)
                                {
                                        if((yy1 >=0x21 && yy1<= 0x7e) && (yy2 >=0x21 && yy2<= 0x7e)) 
                                        {
                                                rr = 2;
                                                break;
                                        }
                                }        
                                yy1++;
                        }
                        if(rr == 2)
                                break;
                        yy2++;
                }

                a[24] = yy2;
                a[23] = yy1;

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

                        a[i-1] = yy11;

                }

                if(a[0] == '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位可执行文件,无壳。

03MDCR()LT6D{6DX_J.png

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

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

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

VE7@6RFF3EH$$[OJ`)5S36T.png

005D2847   .  83C4 0C       add esp,0xC
005D284A   .  8D8424 200200>lea eax,dword ptr ss:[esp+0x220]
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:[0x5EB1FC]            ; \GetWindowTextA
005D285B   .  8DB424 200200>lea esi,dword ptr ss:[esp+0x220]
005D2862   .  8D4E 01       lea ecx,dword ptr ds:[esi+0x1]
005D2865   >  8A06          mov al,byte ptr ds:[esi]
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:[esp+0x224]
005D287F   .  B9 07000000   mov ecx,0x7
005D2884   .  99            cdq
005D2885   .  F7F9          idiv ecx                                 ;  edi = a[4] % 7
005D2887   .  8BFA          mov edi,edx
005D2889   .  8D51 FA       lea edx,dword ptr ds:[ecx-0x6]           ;  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 00  pshufw 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:[esp+eax+0x278],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:[esp+eax+0x288],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:[esp+eax+0x298],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:[esp+eax+0x2A8],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:[esp+eax+0x220]       ;  cl = key[n]
005D2937   .  32CA          xor cl,dl                                ;  cl = cl ^ dl
005D2939   .  888C04 780200>mov byte ptr ss:[esp+eax+0x278],cl       ;  0x003ff9A0[n] = cl
005D2940   .  40            inc eax                                  ;  n++
005D2941   .  3BC6          cmp eax,esi
005D2943   .^ 7C EB         jl X005D2930                             ;  ------------
005D2945   >  C68404 780200>mov byte ptr ss:[esp+eax+0x278],0x0
005D294D   .  33D2          xor edx,edx
005D294F   .  90            nop
005D2950   >  8A82 E00A5F00 mov al,byte ptr ds:[edx+0x5F0AE0]        ;  al = 0x00CE0AE1[n]
005D2956   .  8ACA          mov cl,dl
005D2958   .  328414 780200>xor al,byte ptr ss:[esp+edx+0x278]       ;  al = al ^ 0x003ff9A0[n]
005D295F   .  D2C0          rol al,cl                                ;  rol al , n
005D2961   .  888414 780200>mov byte ptr ss:[esp+edx+0x278],al       ;  0x003ff9A0[n] = AL
005D2968   .  42            inc edx
005D2969   .  3BD6          cmp edx,esi
005D296B   .^ 7C E3         jl X005D2950                             ;  ---------------------
005D296D   .  8D8C24 780200>lea ecx,dword ptr ss:[esp+0x278]
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:[ecx]               ;  判断加密后的key与0x5F78D8内存处数组的数据是否相等
005D2982   .  3B02          cmp eax,dword ptr ds:[edx]
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:[ecx]
005D2994   .  66:3B02       cmp ax,word ptr ds:[edx]
005D2997   .  75 48         jnz X005D29E1
005D2999   .  8A41 02       mov al,byte ptr ds:[ecx+0x2]
005D299C   .  3A42 02       cmp al,byte ptr ds:[edx+0x2]
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:[0x5EB200]            ; \MessageBoxA

我们在内存窗口中查看0x5f78d8地址处的数组的数据。
26Q[2H1HO1~NWZ1VE4G4L{L.png

接着我们根据逆向算法写出程序求得真正的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[32] = {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[32] = {0};
        for(int i = 0; i < 31; i++)
        {

                a[i] = ror(b[i],i) ^ c[i];

        }
        BYTE flag = 0;
        while(1)
        {

                for(int i = 0; i < 31; i++)
                {
                        d[i] = flag ^ a[i];

                }

                BYTE WW = 2;
                BYTE WW2 = 1;
                while((d[4] % 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写进去。
UCOW9DEZ}{%QMKGME2DP@QF.png

900[U~_P]$]Y8ZQ~]P93O$T.png

Checkin


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

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

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

我们在WaitForSingleObject调用的下一条指令下断点,运行程序输入flag回车后,显示no,且WaitForSingleObjet函数返回,程序中断在刚刚下的断点处。
3IX[[A1U3[$SNR@T`{Q_R~N.png
M0_B%ETPPDM[@][5@0A0Z)E.png

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

TQTZ}VDJI53%{W4QO7ALUIN.png
我们在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。

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

`G3OIM{((WC}N2EG{PTF.png

WannaFlag.zip

121.32 KB, 下载次数: 11, 下载积分: 吾爱币 -1 CB

challenge.zip

668 Bytes, 下载次数: 6, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 7威望 +1 吾爱币 +26 热心值 +7 收起 理由
qdam + 1 + 1 谢谢@Thanks!
shng + 1 + 1 我很赞同!
万一赢了呢 + 1 + 1 用心讨论,共获提升!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
gink + 1 + 1 我很赞同!
__不说 + 1 + 1 谢谢@Thanks!
混子 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

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名才有机会。后面的都是陪跑我觉得没什么关系才发的,要不然我是不会发的

点评

@gink 说的很有道理,比赛没结束,确实禁止公开讨论,现在结束了吗?如果没结束把帖子权限编辑一下,不要公开。  详情 回复 发表于 2020-9-3 18:03
Airey 发表于 2020-9-1 17:22
坐等大佬
dravenkali 发表于 2020-9-1 17:43
抓紧学习一下
lifz888 发表于 2020-9-2 07:56
不错的分析,支持分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-19 02:55

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表