-
-
[原创]看雪.京东 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直播授课
赞赏
他的文章
看原图
赞赏
雪币:
留言: