姚小宝 发表于 2019-3-28 17:12

安恒周周练-西湖论剑特别版

本帖最后由 yechen123 于 2019-3-28 17:14 编辑


题目虽然简单   但是蛮有意思的


Mysterious



从DialogBoxParamA 函数中定位处理函数
int __stdcall sub_401090(HWND hWnd, int a2, int a3, int a4)
{
char v5; //
CHAR Text; //
char v7; //
__int16 v8; //
char v9; //
int v10; //
CHAR String; //
char v12; //
char v13; //
char v14; //

memset(&String, 0, 0x104u);
v10 = 0;
if ( a2 == 16 )
{
    DestroyWindow(hWnd);
    PostQuitMessage(0);
}
else if ( a2 == 273 )
{
    if ( a3 == 1000 )
    {
      GetDlgItemTextA(hWnd, 1002, &String, 260);
      strlen(&String);
      if ( strlen(&String) > 6 )
      ExitProcess(0);
      v10 = atoi(&String) + 1;
      if ( v10 == 123 && v12 == 120 && v14 == 122 && v13 == 121 )
      {
      strcpy(Text, "flag");
      memset(&v7, 0, 0xFCu);
      v8 = 0;
      v9 = 0;
      _itoa(v10, &v5, 10);
      strcat(Text, "{");
      strcat(Text, &v5);
      strcat(Text, "_");
      strcat(Text, "Buff3r_0v3rf|0w");
      strcat(Text, "}");
      MessageBoxA(0, Text, "well done", 0);
      }
      SetTimer(hWnd, 1u, 0x3E8u, TimerFunc);
    }
    if ( a3 == 1001 )
      KillTimer(hWnd, 1u);
}
return 0;
}


输入的字符不能超过6位要为6位

if ( v10 == 123 && String == 120 && String == 122 && String == 121 )
可以得知 经过atoi函数转为数字后 +1 要等于123后边三位是xyz
所以key是122xyz




findKey


打开软件后发现没有输入窗口
查看函数

ATOM __cdecl sub_4011D0(HINSTANCE hInstance)
{
WNDCLASSEXA v2; //

v2.cbSize = 48;
v2.style = 3;
v2.lpfnWndProc = (WNDPROC)sub_401014;
v2.cbClsExtra = 0;
v2.cbWndExtra = 0;
v2.hInstance = hInstance;
v2.hIcon = LoadIconA(hInstance, (LPCSTR)0x6B);
v2.hCursor = LoadCursorA(0, (LPCSTR)0x7F00);
v2.hbrBackground = (HBRUSH)6;
v2.lpszMenuName = (LPCSTR)109;
v2.lpszClassName = ClassName;
v2.hIconSm = LoadIconA(hInstance, (LPCSTR)0x6C);
return RegisterClassExA(&v2);
}


发现处理函数sub_401014


在函数中发现调用了 DialogBoxParamA

.text:00401721 loc_401721:                           ; CODE XREF: .text:00401714↑j
.text:00401721               mov   esi, esp
.text:00401723               push    0
.text:00401725               push    offset sub_40100A
.text:0040172A               mov   eax,
.text:0040172D               push    eax
.text:0040172E               push    67h
.text:00401730               mov   ecx, hInstance
.text:00401736               push    ecx
.text:00401737               call    ds:DialogBoxParamA
.text:0040173D               cmp   esi, esp


处理函数是sub_40100A
int __stdcall sub_401B20(HWND hDlg, int a2, int a3, int a4)
{
switch ( a2 )
{
    case 272:
      return 1;
    case 273:
      if ( (unsigned __int16)a3 != 1 && (unsigned __int16)a3 != 2 )
      goto LABEL_6;
      EndDialog(hDlg, (unsigned __int16)a3);
      return 1;
    case 514:
LABEL_6:
      byte_428C54 = 49;
      return 0;
    case 517:
      byte_428C54 = 51;
      break;
    case 520:
      if ( dword_428D58 < 3 )
      ++dword_428D5C;
      byte_428C54 = 50;
      break;
    default:
      return 0;
}
return 0;
}
可以看到是通过特定的消息让缓冲区赋值 1 2 3


再看
.text:004018CB loc_4018CB:                           ; CODE XREF: .text:004018B8↑j
.text:004018CB               push    offset byte_428C54 ; 1
.text:004018D0               call    _strlen
.text:004018D5               add   esp, 4
.text:004018D8               test    eax, eax
.text:004018DA               jbe   loc_401A80
.text:004018E0               push    100h
.text:004018E5               push    0
.text:004018E7               lea   edx,
.text:004018ED               push    edx
.text:004018EE               call    _memset         ; 初始化
.text:004018F3               add   esp, 0Ch      ; 0x100
.text:004018F6               push    offset byte_428C54
.text:004018FB               call    _strlen
.text:00401900               add   esp, 4
.text:00401903               push    eax
.text:00401904               push    offset byte_428C54
.text:00401909               lea   eax,
.text:0040190F               push    eax
.text:00401910               call    _memcpy
.text:00401915               add   esp, 0Ch
.text:00401918               push    offset byte_428C54
.text:0040191D
.text:0040191D loc_40191D:                           ; CODE XREF: .text:0040193D↓j
.text:0040191D               push    offset byte_428C54
.text:00401922               call    _strlen
.text:00401927               add   esp, 4
.text:0040192A               push    eax
.text:0040192B               push    offset byte_428C54
.text:00401930               call    j_md5_en      ; 加密后再放到c54
.text:00401935               add   esp, 0Ch
.text:00401938               nop
.text:00401939               jz      short loc_401948
.text:0040193B               jnz   short loc_401948
.text:0040193D               jmp   short near ptr loc_40191D+2
.text:0040193F ; ---------------------------------------------------------------------------
.text:0040193F               push    eax
.text:00401940               mov   eax, ds:MessageBoxA
.text:00401945               call    eax ; MessageBoxA
.text:00401947               pop   eax
.text:00401948
.text:00401948 loc_401948:                           ; CODE XREF: .text:00401939↑j
.text:00401948                                       ; .text:0040193B↑j
.text:00401948               nop
.text:00401949               mov   ecx, 8
.text:0040194E               mov   esi, offset a0kkD1a55k222k2 ; "0kk`d1a`55k222k2a776jbfgd`06cjjb"
.text:00401953               lea   edi, ;
.text:00401959               rep movsd
.text:0040195B               movsb
.text:0040195C               mov   ecx, 37h      ; 55
.text:00401961               xor   eax, eax
.text:00401963               lea   edi, ; 2cb清0
.text:00401969               rep stosd
.text:0040196B               stosw
.text:0040196D               stosb
.text:0040196E               mov   cx, ds:word_423048 ; 0x5353
.text:00401975               mov   , cx
.text:0040197C               mov   dl, ds:byte_42304A ; 0
.text:00401982               mov   , dl
.text:00401988               xor   eax, eax
.text:0040198A               mov   , eax ; 0
.text:00401990               mov   , ax
.text:00401997               mov   , al
.text:0040199D               lea   ecx,
.text:004019A3               push    ecx
.text:004019A4               call    _strlen
.text:004019A9               add   esp, 4
.text:004019AC               push    eax             ; len
.text:004019AD               lea   edx,
.text:004019B3               push    edx
.text:004019B4               lea   eax,
.text:004019BA               push    eax
.text:004019BB               call    sub_401005      ; 异或
.text:004019C0               add   esp, 0Ch
.text:004019C3               lea   ecx,
.text:004019C9               push    ecx
.text:004019CA               push    offset byte_428C54
.text:004019CF               call    __strcmpi
.text:004019D4               add   esp, 8
.text:004019D7               test    eax, eax
.text:004019D9               jnz   short loc_401A37
.text:004019DB               push    32h
.text:004019DD               push    offset unk_423030
.text:004019E2               lea   edx,
.text:004019E8               push    edx
.text:004019E9               call    _memcpy
.text:004019EE               add   esp, 0Ch
.text:004019F1               lea   eax,
.text:004019F7               push    eax
.text:004019F8               call    _strlen
.text:004019FD               add   esp, 4
.text:00401A00               push    eax
.text:00401A01               lea   ecx,
.text:00401A07               push    ecx
.text:00401A08               lea   edx,
.text:00401A0E               push    edx
.text:00401A0F               call    sub_401005      ; 异或
.text:00401A14               add   esp, 0Ch
.text:00401A17               mov   esi, esp
.text:00401A19               push    32h
.text:00401A1B               push    0
.text:00401A1D               lea   eax,
.text:00401A23               push    eax
.text:00401A24               mov   ecx,
.text:00401A27               push    ecx
.text:00401A28               call    ds:MessageBoxA
.text:00401A2E               cmp   esi, esp
.text:00401A30               call    __chkesp
.text:00401A35               jmp   short loc_401A80
发现会调用缓冲区的数据 判断是不是6位
在传入一个函数
int __cdecl md5_en(BYTE *pbData, DWORD dwDataLen, LPSTR lpString1)
{
int result; // eax
DWORD i; //
CHAR String2; //
BYTE v6; //
DWORD pdwDataLen; //
HCRYPTHASH phHash; //
HCRYPTPROV phProv; //

if ( !CryptAcquireContextA(&phProv, 0, 0, 1u, 0xF0000000) )
    return 0;
if ( CryptCreateHash(phProv, 0x8003u, 0, 0, &phHash) )
{
    if ( CryptHashData(phHash, pbData, dwDataLen, 0) )
    {
      CryptGetHashParam(phHash, 2u, v6, &pdwDataLen, 0);
      *lpString1 = 0;
      for ( i = 0; i < pdwDataLen; ++i )
      {
      wsprintfA(&String2, "%02X", v6);
      lstrcatA(lpString1, &String2);
      }
      CryptDestroyHash(phHash);
      CryptReleaseContext(phProv, 0);
      result = 1;
    }
    else
    {
      CryptDestroyHash(phHash);
      CryptReleaseContext(phProv, 0);
      result = 0;
    }
}
else
{
    CryptReleaseContext(phProv, 0);
    result = 0;
}
return result;
}
查文档 发现它应该是windows提供的一个加密库
看CryptCreateHash 的参数应该是MD5加密

后边的代码
.text:00401949               mov   ecx, 8
.text:0040194E               mov   esi, offset a0kkD1a55k222k2 ; "0kk`d1a`55k222k2a776jbfgd`06cjjb"
.text:00401953               lea   edi,
.text:00401959               rep movsd
.text:0040195B               movsb
.text:0040195C               mov   ecx, 37h      ; 55
.text:00401961               xor   eax, eax
.text:00401963               lea   edi, ; 2cb清0
.text:00401969               rep stosd
.text:0040196B               stosw
.text:0040196D               stosb
.text:0040196E               mov   cx, ds:word_423048 ; 0x5353
.text:00401975               mov   , cx
.text:0040197C               mov   dl, ds:byte_42304A ; 0
.text:00401982               mov   , dl
.text:00401988               xor   eax, eax
.text:0040198A               mov   , eax ; 0
.text:00401990               mov   , ax
.text:00401997               mov   , al
.text:0040199D               lea   ecx,
.text:004019A3               push    ecx
.text:004019A4               call    _strlen
.text:004019A9               add   esp, 4
.text:004019AC               push    eax             ; len
.text:004019AD               lea   edx,
.text:004019B3               push    edx
.text:004019B4               lea   eax,
.text:004019BA               push    eax
.text:004019BB               call    sub_401005      ; 异或
程序中的一串字符会传入sub_401005 这个函数 和字符"SS"异或
得到一串md5c8837b23ff8aaa8a2dde915473ce0991

解密之后是123321

此时 可以下断点修改程序逻辑 让程序运行到上边的函数然后byte_428C54这个缓冲区里边的数据改成123321就可以弹出flag了

本来以为是错误的没想到提交对了。。


CrackRTF

int main_0()
{
DWORD password_len; // eax
DWORD v1; // eax
CHAR String; //
int v4; //
CHAR String1; //
BYTE password; //

memset(&password, 0, 0x104u);
memset(&String1, 0, 0x104u);
v4 = 0;
printf("pls input the first passwd(1): ");
scanf("%s", &password);
if ( strlen((const char *)&password) != 6 )
{
    printf("Must be 6 characters!\n");
    ExitProcess(0);
}
v4 = atoi((const char *)&password);
if ( v4 < 100000 )                            // 大于100000
    ExitProcess(0);
strcat((char *)&password, "@DBApp");
password_len = strlen((const char *)&password);
sub_40100A(&password, password_len, &String1);
if ( !_strcmpi(&String1, "6E32D0943418C2C33385BC35A1470250DD8923A9") )// shal加密
{
    printf("continue...\n\n");
    printf("pls input the first passwd(2): ");
    memset(&String, 0, 0x104u);
    scanf("%s", &String);
    if ( strlen(&String) != 6 )
    {
      printf("Must be 6 characters!\n");
      ExitProcess(0);
    }
    strcat(&String, (const char *)&password);
    memset(&String1, 0, 0x104u);
    v1 = strlen(&String);
    sub_401019((BYTE *)&String, v1, &String1);
    if ( !_strcmpi("27019e688a4e62a649fd99cadaafdb4e", &String1) )// md5加密
    {
      if ( !sub_40100F(&String) )
      {
      printf("Error!!\n");
      ExitProcess(0);
      }
      printf("bye ~~\n");
    }
}
return 0;
}

先输入第一个密码 必须是6数字 并且要大于100000
在后边加字符串"@DBApp"后再传入 sub_40100A 加密
int __cdecl sub_401230(BYTE *pbData, DWORD dwDataLen, LPSTR lpString1)
{
int result; // eax
DWORD i; //
CHAR String2; //
char v6; //
DWORD pdwDataLen; //
HCRYPTHASH phHash; //
HCRYPTPROV phProv; //

if ( !CryptAcquireContextA(&phProv, 0, 0, 1u, 0xF0000000) )
    return 0;
if ( CryptCreateHash(phProv, 0x8004u, 0, 0, &phHash) )
{
    if ( CryptHashData(phHash, pbData, dwDataLen, 0) )
    {
      CryptGetHashParam(phHash, 2u, (BYTE *)v6, &pdwDataLen, 0);
      *lpString1 = 0;
      for ( i = 0; i < pdwDataLen; ++i )
      {
      wsprintfA(&String2, "%02X", (unsigned __int8)v6);
      lstrcatA(lpString1, &String2);
      }
      CryptDestroyHash(phHash);
      CryptReleaseContext(phProv, 0);
      result = 1;
    }
    else
    {
      CryptDestroyHash(phHash);
      CryptReleaseContext(phProv, 0);
      result = 0;
    }
}
else
{
    CryptReleaseContext(phProv, 0);
    result = 0;
}
return result;
}

应该是shal加密

直接写脚本爆破
import hashlib

flag2 = "@DBApp"

for i in range(100000,999999):
      h2 = hashlib.sha1(str(i)+flag2)
      flags = h2.hexdigest()
      if "6e32d0943418c2c" in flags:
                print (str(i)+flag2)
                print flags
得到123321@DBApp

然后在输入第二个密码但是没有限制这个密码的范围
在第二个密码后边加上123321@DBApp后经过md5加密
传入sub_40100F 函数    6位不确定范围字符爆破太久

可以看看 sub_40100F这个函数
char __cdecl sub_4014D0(LPCSTR lpString)
{
LPCVOID lpBuffer; //
DWORD NumberOfBytesWritten; //
DWORD nNumberOfBytesToWrite; //
HGLOBAL hResData; //
HRSRC hResInfo; //
HANDLE hFile; //

hFile = 0;
hResData = 0;
nNumberOfBytesToWrite = 0;
NumberOfBytesWritten = 0;
hResInfo = FindResourceA(0, (LPCSTR)0x65, "AAA");
if ( !hResInfo )
    return 0;
nNumberOfBytesToWrite = SizeofResource(0, hResInfo);
hResData = LoadResource(0, hResInfo);
if ( !hResData )
    return 0;
lpBuffer = LockResource(hResData);
sub_401005(lpString, (int)lpBuffer, nNumberOfBytesToWrite);
hFile = CreateFileA("dbapp.rtf", 0x10000000u, 0, 0, 2u, 0x80u, 0);
if ( hFile == (HANDLE)-1 )
    return 0;
if ( !WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0) )
    return 0;
CloseHandle(hFile);
return 1;
}
里边查找名为“AAA”的资源
取出数值 并跟 输入的密码2+输入的密码1+“@DBApp” 异或

并生成.rtf文件最终的flag应该就在.rtf文件里边
用ResourceHacer 软件查看资源

取出里边的数据 虽然猜一个6位的密码2异或试试
i = [0x05,0x7D,0x41,0x15,0x26,0x01,0x6D,0x53,0x5D,0x40,0x5B,0x6D,0x21,0x2A,0x31,0x28,0x13,0x00,0x19,0x18,0x00,0x57,0x1C,0x54,0x54,0x54,0x55,0x03,0x6E,0x55,0x25,0x22,
0x2E,0x20,0x1E,0x17,0x4F,0x11,0x00,0x52,0x1C,0x54,0x54,0x54,0x5F,0x52,0x5C,0x56,0x26,0x21,0x70,0x71,0x45,0x42,0x05,0x7D,0x55,0x0E,0x2E,0x44,0x45,0x50,0x5F,0x48,
0x6E,0x57,0x70,0x18,0x24,0x2C,0x1F,0x14,0x1B,0x53,0x5D,0x3D,0x26,0x40,0x43,0x43,0x05,0x6F,0x54,0x52,0x28,0x25,0x30,0x32,0x15,0x04,0x4F,0x12,0x07,0x41,0x1C,0x17,
0x52,0x50,0x6F,0x14,0x51,0x54,0x1C,0x63,0x21,0x22,0x2C,0x57,0x1B,0x14,0x08,0x1C,0x3D,0x3D,0x3B,0x49,0x6F,0x19,0x6E,0x56,0x25,0x2A,0x27,0x33,0x11,0x04,0x11,0x53,
0x13,0x2C,0x33,0x56,0x45,0x57,0x57,0x5A,0x46,0x11,0x75,0x6A,0x76,0x70,0x5E,0x41,0x4B,0x0F,0x02,0x54,0x71,0x05,0x0A,0x4F,0x6F,0x45,0x5B,0x54,0x37,0x2F,0x2B,0x2F,
0x14,0x44,0x22,0x54,0x50,0x50,0x1C,0x40,0x50,0x40,0x57,0x6F,0x5E,0x50,0x2E,0x23,0x70,0x71,0x45,0x42,0x22,0x47,0x03,0x3D,0x26,0x43,0x03,0x02,0x13,0x75,0x5E,0x50,
0x27,0x18,0x39,0x0F,0x40,0x2F,0x33,0x11,0x41,0x04,0x1F,0x76,0x43,0x57,0x56,0x6C,0x70,0x44,0x27,0x37,0x1E,0x3C,0x2C,0x00,0x1F,0x53,0x3E,0x6B,0x3D,0x3D,0x3B,0x32]

flag = "123321123321@DBApp"
cout = len(flag)
for q in range(len(i)):
      i ^= ord(flag)
flags= ""
for q in i:
      flags += chr(q)
print i
print flags


有flag了 但是不完整

此时 可以从本地中搜索.rtf的文件 查看格式

前面6位的格式应该是{\rtf1
逆推的到密码2~!3a@0

再异或
i = [0x05,0x7D,0x41,0x15,0x26,0x01,0x6D,0x53,0x5D,0x40,0x5B,0x6D,0x21,0x2A,0x31,0x28,0x13,0x00,0x19,0x18,0x00,0x57,0x1C,0x54,0x54,0x54,0x55,0x03,0x6E,0x55,0x25,0x22,
0x2E,0x20,0x1E,0x17,0x4F,0x11,0x00,0x52,0x1C,0x54,0x54,0x54,0x5F,0x52,0x5C,0x56,0x26,0x21,0x70,0x71,0x45,0x42,0x05,0x7D,0x55,0x0E,0x2E,0x44,0x45,0x50,0x5F,0x48,
0x6E,0x57,0x70,0x18,0x24,0x2C,0x1F,0x14,0x1B,0x53,0x5D,0x3D,0x26,0x40,0x43,0x43,0x05,0x6F,0x54,0x52,0x28,0x25,0x30,0x32,0x15,0x04,0x4F,0x12,0x07,0x41,0x1C,0x17,
0x52,0x50,0x6F,0x14,0x51,0x54,0x1C,0x63,0x21,0x22,0x2C,0x57,0x1B,0x14,0x08,0x1C,0x3D,0x3D,0x3B,0x49,0x6F,0x19,0x6E,0x56,0x25,0x2A,0x27,0x33,0x11,0x04,0x11,0x53,
0x13,0x2C,0x33,0x56,0x45,0x57,0x57,0x5A,0x46,0x11,0x75,0x6A,0x76,0x70,0x5E,0x41,0x4B,0x0F,0x02,0x54,0x71,0x05,0x0A,0x4F,0x6F,0x45,0x5B,0x54,0x37,0x2F,0x2B,0x2F,
0x14,0x44,0x22,0x54,0x50,0x50,0x1C,0x40,0x50,0x40,0x57,0x6F,0x5E,0x50,0x2E,0x23,0x70,0x71,0x45,0x42,0x22,0x47,0x03,0x3D,0x26,0x43,0x03,0x02,0x13,0x75,0x5E,0x50,
0x27,0x18,0x39,0x0F,0x40,0x2F,0x33,0x11,0x41,0x04,0x1F,0x76,0x43,0x57,0x56,0x6C,0x70,0x44,0x27,0x37,0x1E,0x3C,0x2C,0x00,0x1F,0x53,0x3E,0x6B,0x3D,0x3D,0x3B,0x32]

flag = "~!3a@0123321@DBApp"
cout = len(flag)
for q in range(len(i)):
      i ^= ord(flag)
flags= ""
for q in i:
      flags += chr(q)
print i
print flags

得到flag

姚小宝 发表于 2019-4-3 16:43

qdam 发表于 2019-4-3 16:07
请问如何快速判断一个加密函数是常用的加密方式呢,例如md5,sha

作者自己写的加密源码就看特征值或者加密方式。帖子中的题目调用加密库的话就看参数的值,不同的参数代表不同的加密。

姚小宝 发表于 2019-4-1 22:50

qdam 发表于 2019-4-1 22:32
请问为什么要从DialogBoxParamA 函数中定位处理函数,是就这个程序单独而言还是说所有带有消息窗口程序都是 ...

针对DialogBoxParamA这个api,可以看看这个api的定义

韩喻V 发表于 2019-3-28 17:52

提前点赞666

bdpqnumw 发表于 2019-3-28 21:01

感谢分享,支持一下。

萌牛工厂 发表于 2019-3-28 21:15

谢谢分享 学习学习

ri5e 发表于 2019-3-28 21:49

tql 谢谢分享

17679286631 发表于 2019-3-28 22:08

感谢分享0

夜步城 发表于 2019-3-28 22:29

来学习一下

rememory 发表于 2019-3-28 23:13

打卡,滴滴

ts0001 发表于 2019-3-29 05:51

学习了、谢谢楼主发帖分享

hcoolman33 发表于 2019-3-29 08:07

谢谢LZ分享。
页: [1] 2 3 4
查看完整版本: 安恒周周练-西湖论剑特别版