title: buu-re-rome
tags:

  • buu
  • RE
  • CTF
    abbrlink: deb1f1bd
    date: 2021-03-19 19:30:45

初识程序

拿到程序后,先放入PEID进行检测

buu-re-rome - 图1

程序无壳,是32位的,可以直接放入IDA32进行反编译

开始整活

进入后找到main函数入口,解析为C语言

buu-re-rome - 图2

有两个函数,一个是_main()函数,一个是func()函数,进入__main发现只有一个if判定没有

没有什么实质性的东西,然后转只能回头找func,进入后确认是主要判定的函数

  1. int func()
  2. {
  3. int result; // eax
  4. int v1; // [esp+14h] [ebp-44h]
  5. int v2; // [esp+18h] [ebp-40h]
  6. int v3; // [esp+1Ch] [ebp-3Ch]
  7. int v4; // [esp+20h] [ebp-38h]
  8. unsigned __int8 v5; // [esp+24h] [ebp-34h]
  9. unsigned __int8 v6; // [esp+25h] [ebp-33h]
  10. unsigned __int8 v7; // [esp+26h] [ebp-32h]
  11. unsigned __int8 v8; // [esp+27h] [ebp-31h]
  12. unsigned __int8 v9; // [esp+28h] [ebp-30h]
  13. int v10; // [esp+29h] [ebp-2Fh]
  14. int v11; // [esp+2Dh] [ebp-2Bh]
  15. int v12; // [esp+31h] [ebp-27h]
  16. int v13; // [esp+35h] [ebp-23h]
  17. unsigned __int8 v14; // [esp+39h] [ebp-1Fh]
  18. char v15; // [esp+3Bh] [ebp-1Dh]
  19. char v16; // [esp+3Ch] [ebp-1Ch]
  20. char v17; // [esp+3Dh] [ebp-1Bh]
  21. char v18; // [esp+3Eh] [ebp-1Ah]
  22. char v19; // [esp+3Fh] [ebp-19h]
  23. char v20; // [esp+40h] [ebp-18h]
  24. char v21; // [esp+41h] [ebp-17h]
  25. char v22; // [esp+42h] [ebp-16h]
  26. char v23; // [esp+43h] [ebp-15h]
  27. char v24; // [esp+44h] [ebp-14h]
  28. char v25; // [esp+45h] [ebp-13h]
  29. char v26; // [esp+46h] [ebp-12h]
  30. char v27; // [esp+47h] [ebp-11h]
  31. char v28; // [esp+48h] [ebp-10h]
  32. char v29; // [esp+49h] [ebp-Fh]
  33. char v30; // [esp+4Ah] [ebp-Eh]
  34. char v31; // [esp+4Bh] [ebp-Dh]
  35. int i; // [esp+4Ch] [ebp-Ch]
  36. v15 = 'Q';
  37. v16 = 's';
  38. v17 = 'w';
  39. v18 = '3';
  40. v19 = 's';
  41. v20 = 'j';
  42. v21 = '_';
  43. v22 = 'l';
  44. v23 = 'z';
  45. v24 = '4';
  46. v25 = '_';
  47. v26 = 'U';
  48. v27 = 'j';
  49. v28 = 'w';
  50. v29 = '@';
  51. v30 = 'l';
  52. v31 = '\0';
  53. printf("Please input:");
  54. scanf("%s", &v5);
  55. result = v5;
  56. if ( v5 == 'A' )
  57. {
  58. result = v6;
  59. if ( v6 == 'C' )
  60. {
  61. result = v7;
  62. if ( v7 == 'T' )
  63. {
  64. result = v8;
  65. if ( v8 == 'F' )
  66. {
  67. result = v9;
  68. if ( v9 == '{' )
  69. {
  70. result = v14;
  71. if ( v14 == '}' )
  72. {
  73. v1 = v10;
  74. v2 = v11;
  75. v3 = v12;
  76. v4 = v13;
  77. for ( i = 0; i <= 15; ++i )
  78. {
  79. if ( *((_BYTE *)&v1 + i) > 64 && *((_BYTE *)&v1 + i) <= 90 )
  80. *((_BYTE *)&v1 + i) = (*((char *)&v1 + i) - 51) % 26 + 65;
  81. if ( *((_BYTE *)&v1 + i) > 96 && *((_BYTE *)&v1 + i) <= 122 )
  82. *((_BYTE *)&v1 + i) = (*((char *)&v1 + i) - 79) % 26 + 97;
  83. }
  84. for ( i = 0; i <= 15; ++i )
  85. {
  86. result = (unsigned __int8)*(&v15 + i);
  87. if ( *((_BYTE *)&v1 + i) != (_BYTE)result )
  88. return result;
  89. }
  90. result = printf("You are correct!");
  91. }
  92. }
  93. }
  94. }
  95. }
  96. }
  97. return result;
  98. }

对有关的字符进行转换后发现逻辑比较简单,就是对字符串进行一个分支结构的判断,根据前面嵌套的if语句判断开头是ACTF{,结尾有一个}(废话),处理以后再和前面的一个字符串连接起来,即可得到解

加大力度

分析到这里问题就很简单了,直接开始脚本

  1. a="ACTF{"
  2. v15="Qsw3sj_lz4_Ujw@l"
  3. s=""
  4. for k in range(len(v15)):
  5. for s in range(128):
  6. i=s
  7. if i>64 and i <=90:
  8. i=(i-51)%26+65
  9. if i>96 and i<=122:
  10. i=(i-79)%26+97
  11. if i==ord(v15[k]):
  12. a=a+chr(s)
  13. print(a+"}")

最后找到了flagACTF{Cae3ar_th4_Gre@t}