SUSCTF-Writeup(Reverse)
2018/10/29

60


下载载入IDA 查看

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [rsp+4h] [rbp-Ch]
  unsigned __int64 v5; // [rsp+8h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  v4 = -1;
  printf("Guess number: ", argv, envp);
  __isoc99_scanf("%d", &v4);
  if ( v4 == 2333333 )
  {
    printf("Congraz! You are right. This is your flag: ");
    get_flag();
  }
  else
  {
    puts("Nop. You should try harder~");
  }
  return 0;
}

逻辑很简单 输入2333333即可getflag

FLAG : SUSCTF{H3llo_wOr1d!}

70


提示工具 uncompyle6

安装完毕 运行

uncompyle6 HelloPython.pyc

得到源代码

➜  下载 uncompyle6 HelloPython.pyc
# uncompyle6 version 3.2.4
# Python bytecode 3.6 (3379)
# Decompiled from: Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34) 
# [GCC 7.3.0]
# Embedded file name: HelloPython.py
# Compiled at: 2018-09-27 23:27:58
# Size of source mod 2**32: 1227 bytes
import sys
if len(sys.argv) < 5:
    print("I can't give you flag :(")
    sys.exit(0)

def Fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        numfn1 = 0
        numfn2 = 1
        for i in range(2, n + 1):
            currentNum = numfn1 + numfn2
            numfn1 = numfn2
            numfn2 = currentNum

        return currentNum


def encrypt(key, s):
    b = bytearray(str(s).encode('gbk'))
    n = len(b)
    c = bytearray(n * 2)
    j = 0
    for i in range(0, n):
        b1 = b[i]
        b2 = b1 ^ key
        c1 = b2 % 16
        c2 = b2 // 16
        c1 = c1 + 65
        c2 = c2 + 65
        c[j] = c1
        c[j + 1] = c2
        j = j + 2

    return c.decode('gbk')


def decrypt(key, s):
    c = bytearray(str(s).encode('gbk'))
    n = len(c)
    if n % 2 != 0:
        return ''
    else:
        n = n // 2
        b = bytearray(n)
        j = 0
        for i in range(0, n):
            c1 = c[j]
            c2 = c[j + 1]
            j = j + 2
            c1 = c1 - 65
            c2 = c2 - 65
            b2 = c2 * 16 + c1
            b1 = b2 ^ key
            b[i] = b1

        return b.decode('gbk')


if int(sys.argv[1]) > 10:
    if Fibonacci(int(sys.argv[1])) == int(sys.argv[4]):
        print(decrypt(15, 'MFKFMFMELFJEEHIFMDDGMGAGCGKGAFLHAGAFPHGHLHHGAGBGICMHAFIHAGNHODLGCH'))
# okay decompiling HelloPython.pyc

分析 存在加密解密函数 如果满足第一个三处等于第四个参数且第一个参数大于10就输出解密后面的字符串

这里我们可以删除 if语句 以及最前面的长度判断 直接print
所以可以得到源码

# uncompyle6 version 3.2.4
# Python bytecode 3.6 (3379)
# Decompiled from: Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34) 
# [GCC 7.3.0]
# Embedded file name: HelloPython.py
# Compiled at: 2018-09-27 23:27:58
# Size of source mod 2**32: 1227 bytes
import sys
def Fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        numfn1 = 0
        numfn2 = 1
        for i in range(2, n + 1):
            currentNum = numfn1 + numfn2
            numfn1 = numfn2
            numfn2 = currentNum

        return currentNum


def encrypt(key, s):
    b = bytearray(str(s).encode('gbk'))
    n = len(b)
    c = bytearray(n * 2)
    j = 0
    for i in range(0, n):
        b1 = b[i]
        b2 = b1 ^ key
        c1 = b2 % 16
        c2 = b2 // 16
        c1 = c1 + 65
        c2 = c2 + 65
        c[j] = c1
        c[j + 1] = c2
        j = j + 2

    return c.decode('gbk')


def decrypt(key, s):
    c = bytearray(str(s).encode('gbk'))
    n = len(c)
    if n % 2 != 0:
        return ''
    else:
        n = n // 2
        b = bytearray(n)
        j = 0
        for i in range(0, n):
            c1 = c[j]
            c2 = c[j + 1]
            j = j + 2
            c1 = c1 - 65
            c2 = c2 - 65
            b2 = c2 * 16 + c1
            b1 = b2 ^ key
            b[i] = b1

        return b.decode('gbk')


print(decrypt(15, 'MFKFMFMELFJEEHIFMDDGMGAGCGKGAFLHAGAFPHGHLHHGAGBGICMHAFIHAGNHODLGCH'))

运行可以得到flag

SUSCTF{W3lcome_to_python's_wor1d}

150

载入ida分析

if ( strlen(s) == 30 )
{
  for ( i = 0; i <= 29; ++i )
  {
    if ( (s[i] ^ *(&v5 + i)) != *(&v35 + i) )
    {
      puts("Something wrong, you should try harder.");
      return 0;
    }
  }
  puts("Congrazzzzzz~ You got it!");
  result = 0;
}
else
{
  puts("Something wrong, you should try harder.");
  result = 0;
}

可以得出flag长度为30且 要满足 if中的xor操作 这里处理一下两个数组

得到可观代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax
  int v4[31]; // [rsp+Ch] [rbp-134h]
  int v5[30]; // [rsp+90h] [rbp-B0h]
  char s[8]; // [rsp+110h] [rbp-30h]
  __int64 v7; // [rsp+118h] [rbp-28h]
  __int64 v8; // [rsp+120h] [rbp-20h]
  __int64 v9; // [rsp+128h] [rbp-18h]
  __int64 v10; // [rsp+130h] [rbp-10h]
  unsigned __int64 v11; // [rsp+138h] [rbp-8h]

  v11 = __readfsqword(0x28u);
  v4[1] = 48;
  v4[2] = 46;
  v4[3] = 96;
  v4[4] = 101;
  v4[5] = 116;
  v4[6] = 9;
  v4[7] = 73;
  v4[8] = 125;
  v4[9] = 25;
  v4[10] = 84;
  v4[11] = 5;
  v4[12] = 23;
  v4[13] = 109;
  v4[14] = 26;
  v4[15] = 28;
  v4[16] = 100;
  v4[17] = 17;
  v4[18] = 64;
  v4[19] = 21;
  v4[20] = 52;
  v4[21] = 74;
  v4[22] = 122;
  v4[23] = 29;
  v4[24] = 68;
  v4[25] = 54;
  v4[26] = 17;
  v4[27] = 31;
  v4[28] = 80;
  v4[29] = 73;
  v4[30] = 8;
  v5[0] = 99;
  v5[1] = 123;
  v5[2] = 51;
  v5[3] = 38;
  v5[4] = 32;
  v5[5] = 79;
  v5[6] = 50;
  v5[7] = 5;
  v5[8] = 41;
  v5[9] = 38;
  v5[10] = 90;
  v5[11] = 38;
  v5[12] = 30;
  v5[13] = 69;
  v5[14] = 121;
  v5[15] = 80;
  v5[16] = 98;
  v5[17] = 57;
  v5[18] = 74;
  v5[19] = 64;
  v5[20] = 5;
  v5[21] = 37;
  v5[22] = 111;
  v5[23] = 119;
  v5[24] = 64;
  v5[25] = 116;
  v5[26] = 109;
  v5[27] = 101;
  v5[28] = 44;
  v5[29] = 117;
  *(_QWORD *)s = 0LL;
  v7 = 0LL;
  v8 = 0LL;
  v9 = 0LL;
  v10 = 0LL;
  printf("Give me flag: ", argv, envp);
  __isoc99_scanf("%s", s);
  if ( strlen(s) == 30 )
  {
    for ( v4[0] = 0; v4[0] <= 29; ++v4[0] )
    {
      if ( (s[v4[0]] ^ v4[v4[0] + 1]) != v5[v4[0]] )
      {
        puts("Something wrong, you should try harder.");
        return 0;
      }
    }
    puts("Congrazzzzzz~ You got it!");
    result = 0;
  }
  else
  {
    puts("Something wrong, you should try harder.");
    result = 0;
  }
  return result;
}

分析代码 若要获得flag 需要将v4的每一位与v5的每一位xor操作 即可

EXP

v4 = [48,46,96,101,116,9,73,125,25,84,5,23,109,26,28,100,17,64,21,52,74,122,29,68,54,17,31,80,73,8]
v5 = [99,123,51,38,32,79,50,5,41,38,90,38,30,69,121,80,98,57,74,64,5,37,111,119,64,116,109,101,44,117]

str = ''
for i in range(0,30):

    str += chr((v4[i]^v5[i]))

print str

运行即可

FLAG : SUSCTF{x0r_1s_e4sy_tO_r3ver5e}

150


载入IDA 分析

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax
  signed int i; // [rsp+Ch] [rbp-44h]
  char s[48]; // [rsp+10h] [rbp-40h]
  __int16 v6; // [rsp+40h] [rbp-10h]
  unsigned __int64 v7; // [rsp+48h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  memset(s, 0, sizeof(s));
  v6 = 0;
  srand(0xDEADBEEF);
  printf("Give me flag: ", argv);
  __isoc99_scanf("%s", s);
  if ( strlen(s) == 39 )
  {
    for ( i = 0; i <= 38; ++i )
    {
      if ( (rand() % 127 ^ s[i]) != c_text[i] )
      {
        puts("Wrong");
        return 0;
      }
    }
    puts("Right");
    result = 0;
  }
  else
  {
    puts("Wrong");
    result = 0;
  }
  return result;
}

核心操作

for ( i = 0; i <= 38; ++i )
{
  if ( (rand() % 127 ^ s[i]) != c_text[i] )
  {
    puts("Wrong");
    return 0;
  }
}

和上一题类似 只不过需要猜测随机数
但是srand 可以预测 所以我们 先写一个随机数预测脚本

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
intmain(void)
 {

 srand(0xDEADBEEF);
 for(int i=0;i<50;i++){
   printf("%d,",rand()%127);
 }
 return 0;

 }

EXP



c = [0,0x51,0x32,0x7B,0x78,0x76,0x23,0x22,0x25,0x61,0x77,0x4C,0x28,0x6D,0x37,0x67,0x2B,0xA,1,0x2C,0xE,0x34,8,0x35,0x5F,0x2C,0x3B,0x49,0x68,0x1F,0x7E,0x61,0xD,0x67,0x75,0x78,0x5E,0x6D,0x18]
srand = [83,4,97,56,44,48,88,80,68,15,19,124,69,50,90,83,82,104,100,115,96,91,63,106,44,77,93,122,55,108,49,12,104,19,68,21,59,30,101,119,37,120,116,99,36,80,55,118,49,20]
str =''
for i in range(0,39):

    str += chr((c[i]^srand[i]))

print str
SUSCTF{rand0m_m4ybe_no7_saf3_sOmet1mes}
请杯咖啡呗~
支付宝
微信
本文作者:ios
版权声明:本文首发于ios的博客,转载请注明出处!