hws硬件营线上选拔赛

2021-02-06 18:02:00
ctf - wp - hws

NodeMce

不清楚是否非预期,一个strings直接能看到flag

STM

stm32单片机,给了一个bin文件,根据http://www.crystalradio.cn/thread-637028-1-1.html来反编译。

_BYTE *sub_8000314()
{
  _BYTE *v0; // r4
  unsigned __int8 *v1; // r5
  int v2; // r6
  char v3; // t1

  v0 = (_BYTE *)sub_80003F0(48);
  v1 = (unsigned __int8 *)&byte_8000344;
  v2 = 0;
  while ( v2++ != 0 )
  {
    v3 = *v1++;
    *v0++ = (v3 ^ 0x1E) + 3;
    sub_8000124(v1);
  }
  return v0;
}

Xor:

enc = [0x7D, 0x77, 0x40, 0x7A, 0x66, 0x30, 0x2A, 0x2F, 0x28, 0x40, 
  0x7E, 0x30, 0x33, 0x34, 0x2C, 0x2E, 0x2B, 0x28, 0x34, 0x30, 
  0x30, 0x7C, 0x41, 0x34, 0x28, 0x33, 0x7E, 0x30, 0x34, 0x33, 
  0x33, 0x30, 0x7E, 0x2F, 0x31, 0x2A, 0x41, 0x7F, 0x2F, 0x28, 
  0x2E, 0x64]
#flag{1749ac10-5389-11eb-90c1-001c427bd493}
for word in enc:
 print(chr((word^0x1e)+3),end='')

decryption

main函数:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int Buf1; // [esp+18h] [ebp-CCh] BYREF
  _BYTE v5[96]; // [esp+1Ch] [ebp-C8h] BYREF
  int Str; // [esp+7Ch] [ebp-68h] BYREF
  _BYTE v7[96]; // [esp+80h] [ebp-64h] BYREF

  __main();
  Str = 0;
  memset(v7, 0, sizeof(v7));
  printf("Please input your flag:");
  scanf("%s", &Str);
  if ( strlen((const char *)&Str) != 32 )
  {
    puts("Wrong!");
    system("pause");
    exit(0);
  }
  Buf1 = 0;
  memset(v5, 0, sizeof(v5));
  encrypt((unsigned __int8 *)&Buf1, (char *)&Str);
  if ( !memcmp(&Buf1, &buf, 0x20u) )
  {
    puts("Orz!666!");
    printf("Here is your flag: flag{%s}\n", (const char *)&Str);
  }
  else
  {
    puts("Sorry, try again~");
  }
  system("pause");
  return 0;
}

直接看到encrypt函数:

unsigned __int8 *__cdecl encrypt(unsigned __int8 *a1, char *a2)
{
  unsigned __int8 *result; // eax
  char v3; // [esp+8h] [ebp-8h]
  char v4; // [esp+Ah] [ebp-6h]
  char v5; // [esp+Bh] [ebp-5h]
  int i; // [esp+Ch] [ebp-4h]

  for ( i = 0; i <= 31; ++i )
  {
    v5 = a2[i];
    v4 = i;
    do
    {
      v3 = 2 * (v4 & v5);
      v5 ^= v4;
      v4 = v3;
    }
    while ( v3 );
    result = &a1[i];
    a1[i] = v5 ^ 0x23;
  }
  return result;
}

可以爆破,也可以直接逆就完事:

str1 = [  0x12, 0x45, 0x10, 0x47, 0x19, 0x49, 0x49, 0x49, 0x1A, 0x4F, 
  0x1C, 0x1E, 0x52, 0x66, 0x1D, 0x52, 0x66, 0x67, 0x68, 0x67, 
  0x65, 0x6F, 0x5F, 0x59, 0x58, 0x5E, 0x6D, 0x70, 0xA1, 0x6E, 
  0x70, 0xA3]

for i in range(0,len(str1)):
    v7 = str1[i]^0x23
    v6 = i
    while True:
        v7 = v7 ^ v6
        v4 = 2 * (v6 & v7)
        v6 = v4
        if v4==0:
            break
    print(chr(v7),end="")

挺有意思的题,给了个路由器固件,必联路由器,抓包时发现是goahead服务器,在bin中找到goahead,漏洞出现在formDefineCGIjson函数中:

追入函数中发现:

int __fastcall sub_44D41C(int a1)
{
  const char *v2; // $s5
  int v3; // $v0
  int v4; // $s0
  int v5; // $v0
  int v6; // $s2
  char v8[8200]; // [sp+20h] [-2008h] BYREF

  v2 = (const char *)websGetVar(a1, "cmd", "");
  bl_print(3, "CGI_json.c", "set_cmd", 3968, "cmd = %s\n", v2);
  v4 = cJSON_CreateObject();
  v3 = cJSON_CreateString("setcmd");
  cJSON_AddItemToObject(v4, "type", v3);
  v5 = cJSON_CreateString(v2);
  cJSON_AddItemToObject(v4, "cmd", v5);
  v6 = cJSON_PrintUnformatted(v4);
  memset(v8, 0, 8196);
  bs_SetCmd(v6, v8);
  bl_print(3, "CGI_json.c", "set_cmd", 3976, "back = %s\n", v8);
  websResponse(a1, 200, v8, 0);
  free(v6);
  return cJSON_Delete(v4);
}

发现bs_SetCmd,在共享库中:

cat ./*|grep -ri "bs_SetCmd"
cat: ./bin: 是一个目录
cat: ./customer: 是一个目录
cat: ./dev: 是一个目录
cat: ./etc: 是一个目录
cat: ./etc_ro: 是一个目录
cat: ./home: 是一个目录
匹配到二进制文件 bin/goahead
匹配到二进制文件 lib/libshare-0.0.26.so
int __fastcall bs_SetCmd(const char *a1, int a2)
{
  int v4; // $s1
  int v5; // $s0
  int v6; // $v0
  int v7; // $v0
  int v8; // $fp
  int v9; // $v0
  int v10; // $fp
  int v11; // $v0
  int v12; // $s2
  int v13; // $fp
  int v14; // $v0
  int v15; // $v0
  int v16; // $a0
  const char *v17; // $a1
  int v18; // $s5
  char v20[256]; // [sp+20h] [-1F00h] BYREF
  char v21[500]; // [sp+120h] [-1E00h] BYREF
  char v22[1024]; // [sp+314h] [-1C0Ch] BYREF
  char v23[6148]; // [sp+714h] [-180Ch] BYREF
  int v24; // [sp+1F18h] [-8h]

  memset(v23, 0, 6144);
  memset(v22, 0, sizeof(v22));
  memset(v21, 0, sizeof(v21));
  memset(v20, 0, sizeof(v20));
  v4 = cJSON_Parse(a1);
  if ( v4 )
  {
    bl_print(3, "libshare.c", "bs_SetCmd", 16411, "in == %s\n", a1);
    v5 = cJSON_CreateObject();
    v6 = cJSON_CreateString("setcmd");
    cJSON_AddItemToObject(v5, "type", v6);
    v7 = cJSON_GetObjectItem(v4, "type");
    if ( v7 && (v8 = *(_DWORD *)(v7 + 16), v24 = strlen(v8), v9 = strlen("setcmd"), v24 == v9) && !memcmp(v8, "setcmd") )
    {
      v10 = cJSON_GetObjectItem(v4, "cmd");
      if ( !v10 )
      {
        bl_print(3, "libshare.c", "bs_SetCmd", 16423, "command execute fail\n");
        v11 = cJSON_CreateNumber(0, 1072693248);
        cJSON_AddItemToObject(v5, "result", v11);
        v12 = cJSON_PrintUnformatted(v5);
        cJSON_Delete(v5);
        cJSON_Delete(v4);
        strcpy(a2, v12);
        free(v12);
        return 0;
      }
      memset(v20, 0, sizeof(v20));
      strcpy(v20, *(_DWORD *)(v10 + 16));
      sprintf(v22, &off_4F2CC, v20);
      v13 = popen(v22, "r");

最后可以看到可以直接命令执行



本文原创于HhhM的博客,转载请标明出处。



CopyRight © 2019-2020 HhhM
Power By Django & Bootstrap
已运行
粤ICP备19064649号