首页
社区
课程
招聘
[原创]看雪.京东 2018CTF 第十五题 智能设备 Writeup
发表于: 2018-7-15 13:51 3786

[原创]看雪.京东 2018CTF 第十五题 智能设备 Writeup

2018-7-15 13:51
3786
按题目说明运行QEMU,屏幕显示"please input your key",
看到此题的说明,知道a9rootfs是个磁盘镜像文件,在ubuntu下用mount命令挂载到/mnt 下:
sudo mount ./a9rootfs /mnt
打开/mnt文件夹,看到是个linux的根目录结构,之后搜"please input your key",在文件/mnt/bin/sh中找到,从而知道sh就是验证文件,拖到IDA中分析:
很容易找到输入及验证代码:
void __fastcall __noreturn sub_11374(int a1, int a2, int a3)
{
  int len; // [sp+4h] [bp-518h]
  char buf[100]; // [sp+14h] [bp-508h]
  int buf2; // [sp+114h] [bp-408h]
  char pOut; // [sp+214h] [bp-308h]
  char a1a; // [sp+314h] [bp-208h]
  char v8; // [sp+414h] [bp-108h]
  int v9; // [sp+514h] [bp-8h]

  v9 = dword_97F8C;
  while ( 1 )
  {
    while ( 1 )
    {
      while ( 1 )
      {
      printf("please input your key:"); //这句怎么没加密?一下就搜到了
        scanf("%100s", buf, a3); //输入key
        len = strlen(buf); //计算长度
        encode(buf, &a1a, len); //加密输入串,验证没用到, 不过后面计算flag要用
        keyCalc(buf, (char *)&buf2, len); //计算函数
        btoa((unsigned __int8 *)&buf2, &pOut, len); //计算结果转串
        //对计算结果比较,为下列串就通过
        if ( !strcmp((unsigned __int8 *)&pOut, "C1371DA51A9030079E21DCDC5B78E38563872139C13F6F") )
        {
          atob((int)&v8, (int)"5B7B541D49541B0847551A16435D060D0A66", 18); //flag:you got it [
          decode1(&v8, 18);
          keyCalc(&a1a, (char *)&buf2, len); //对加密的输入KEY再计算一次,其16进制串就是flag
          btoa((unsigned __int8 *)&buf2, &a1a, len);
          sub_18010((int)"%s%s%c\n", &v8, &a1a, ']');
        }
        if ( strcmp((unsigned __int8 *)&pOut, "2A20D1EE7374B49EE12BCB5809A19") ) //ctf_pediy_2018
          break;
        atob((int)&v8, (int)"5B7B541D49541B0847551A16435D060D0A66", 18); //flag:you got it [
        decode1(&v8, 18);
        puts(&v8);
      }
      if ( strcmp((unsigned __int8 *)&pOut, "8D8A79E3749EBAO60E57D00A6A") )
        break;
      atob((int)&v8, (int)"721D1D001745531A49591C0E4B52071A1679", 18); //your key is error
      decode1(&v8, 18);
      puts(&v8);
    }
    if ( !strcmp((unsigned __int8 *)buf, "exit") )
      break;
    atob((int)&v8, (int)"721D1D001745531A49591C0E4B52071A1679", 18); //your key is error
    decode1(&v8, 18);
    puts(&v8);
  }
  if ( v9 != dword_97F8C )
    sub_2B5FC();
}


再来看计算函数:
signed int __fastcall keyCalc(char *pIn, char *pOut, signed int len)
{
  signed int result; // r0
  char buf[256]; // [sp+14h] [bp-108h]
  int v7; // [sp+114h] [bp-8h]

  v7 = dword_97F8C;
  if ( len > 128 )
    len = 128;
  strncpy(pOut, pIn, len, len);
  btoaChg1(pOut, buf, len); //变换串为"FDB08642ECA97531"
  atobChg1(pOut, buf, len); //变换串为"13579BDF02468ACE"
  decode1(pOut, len);
  btoaChg2(pOut, buf, len); //变换串为"0369CF258BE147AD"
  atobChg3(pOut, buf, len); //变换串为"FA50B61C72D83E94"
  decode1(pOut, len);
  btoaChg1(pOut, buf, len); //变换串为"FDB08642ECA97531"
  atobChg3(pOut, buf, len); //变换串为"FA50B61C72D83E94"
  decode1(pOut, len);
  btoaChg2(pOut, buf, len); //变换串为"0369CF258BE147AD"
  atobChg1(pOut, buf, len); //变换串为"13579BDF02468ACE"
  decode1(pOut, len);
  result = 1;
  if ( v7 != dword_97F8C )
    sub_2B5FC();
  return result;
}

encode算法:
signed int __fastcall encode(char *pIn, char *pOut, int len)
{
  int i; // [sp+14h] [bp-8h]

  for ( i = 0; i < len; ++i )
    pOut[i] = i * pIn[i] + 0x1F;
  return 1;
}

decode1算法:
signed int __fastcall decode1(char *s, signed int len)
{
  int i; // [sp+Ch] [bp-8h]
  signed int j; // [sp+Ch] [bp-8h]

  for ( i = 0; len / 2 > i; ++i )
  {
    s[i] ^= s[len - 1 - i]; //第N个字符同倒数第N个字符交换,也就是对输入串倒序
    s[len - 1 - i] ^= s[i];
    s[i] ^= s[len - 1 - i];
  }
  for ( j = 1; j < len; ++j ) //后一个字符 ^= 前一个
    s[j] ^= s[j - 1];
  return len;
}

其中btoaChg1-btoaChg3和atobChg1-atobChg3都只是相当于用不同的字符替代原来的,也就是字母变换,算法一样,只是用的变换串不一样,各列出一个:

signed int __fastcall btoaChg1(char *pIn, char *pOut, int len)
{
  signed int v3; // r3
  signed int result; // r0
  int i; // [sp+14h] [bp-20h]
  char v6[16]; // [sp+18h] [bp-1Ch]
  int v7; // [sp+2Ch] [bp-8h]
  char v8[4]; // [sp+30h] [bp-4h]

  v7 = dword_97F8C;
  if ( pIn && pOut )
  {
    strcpy(v6, "FDB08642ECA97531");
    for ( i = 0; i < len; ++i )
    {
      pOut[2 * i + 1] = v8[(pIn[i] & 0xF) - 0x18];
      pOut[2 * i] = v8[(((unsigned __int8)pIn[i] >> 4) & 0xF) - 0x18];
    }
    pOut[2 * i] = 0;
    v3 = 1;
  }
  else
  {
    v3 = -1;
  }
  result = v3;
  if ( v7 != dword_97F8C )
    sub_2B5FC();
  return result;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//