2017年陝西省網絡空間安全技術大賽Mobile部分WriteUp

0x0 拯救魯班七號

載入jeb,在Mainactivity裏面可以看到程序將輸入放到checkPass函數中驗證

 protected void onCreate(Bundle arg3) {
        super.onCreate(arg3);
        this.setContentView(2130903040);
        this.findViewById(2131165184).setOnClickListener(new View$OnClickListener() {
            public void onClick(View arg4) {
                MainActivity.this.checkPass(MainActivity.this.findViewById(2131165185).getText().toString().trim());
            }
        });
    }

在這個checkPass函數裏面會調用CheckUtil的checkPass函數驗證是否正確,此函數爲humen.so文件中的函數,將humen放到ida中進行分析。無用代碼比較多,下面只將關鍵代碼發出來。

length = strlen(input);
  while ( 1 )
  {
    v23 += 2;
    if ( length <= v23 )
      break;
    v7 = input[v23 - 2];
    input[v23 - 2] = input[v23 - 1];
    v8 = 0;
    input[v23 - 1] = v7;
    if ( length > 4 )
    {
      for ( i = 4; ; i += 4 )
      {
        v10 = (char *)&input[v8];
        v9 = v10;
        v11 = *v10;
        v10 += 4;
        *v9 = *v10;
        *v10 = v11;
        v8 = i;
        if ( length <= i + 4 )
          break;
      }
    }
  }
 v14 = (&t_ptr)[v4 - 12208];
  v15 = 0;
  if ( *input == *v14 )
  {
    do
      v16 = v14[v15++ + 1];
    while ( input[v15] == v16 );
  }

程序將輸入的字符串奇數和偶數做交換並且前八位的0,4,8,位分別與4,8,12,做交換,最後與t進行比較,直接附上腳本。

stt="S!@#@1FD23154A34"
st=list(stt)
v6=len(st)
for j in range(14,0,-2):
    if v6>4:
        for i in range(12,1,-4):
            st[i-4],st[i]=st[i],st[i-4]
    st[j-1],st[j-2]=st[j-2],st[j-1]

flag=''
for i in range(len(st)):
    flag+=st[i]
print flag

0X1 The Marauder’s Map

依照慣例,拖進jeb分析。發現和數據庫有關,最近剛好了解了一下安卓連接數據庫,只能說好巧。

package com.example.icontest;

public class ReadSe {
    private boolean a;

    static {
        System.loadLibrary("test");
    }

    public ReadSe() {
        super();
        this.a = false;
    }

    public final boolean a(String arg3, String arg4) {
        boolean v0 = false;
        if(arg3 != null && arg3.length() > 0 && arg4 != null && arg4.length() > 0 && (arg4.equals(this.readbin(arg3)))) {
            v0 = true;
        }

        return v0;
    }

    private native String readbin(String arg1) {
    }
}

代碼簡單明瞭,將readbin函數的返回值與arg4進行比較,arg4爲user數據庫中讀到的id爲2的生日列。

 public a() {
        super();
        this.a = "";
        this.b = "dGVzdA==";
        this.c = "WWVhaH4h";
        this.d = "dXNlcnM=";
        this.e = "Mg==";
    }

    public final String a(Context arg10) {
        String v0 = a.a(this.b);
        String v1 = a.a(this.d);
        a.a(this.c);
        String v6 = a.a(this.e);
        SQLiteDatabase v0_1 = new b(arg10, v0, null, 1).getReadableDatabase();
        Cursor v1_1 = v0_1.query(v1, new String[]{"userid", "age", "birthday", "id"}, "id=?", new String[]{v6}, null, null, null);
        while(v1_1.moveToNext()) {
            v1_1.getString(v1_1.getColumnIndex("userid"));
            v1_1.getString(v1_1.getColumnIndex("age"));
            this.a = v1_1.getString(v1_1.getColumnIndex("birthday"));
        }

        v0_1.close();
        return this.a;
    }

    private static String a(String arg3) {
        return new String(new String(Base64.decode(arg3.getBytes(), 0)).toCharArray());
    }
}

數據庫可以通過sqlitebrowser軟件查看。
然後,我們分析一下readbin函數,
關鍵代碼在sub_1220()中

 s = (char *)a1;
  v7 = strlen(a1);
  v5 = 0;
  v6 = 0;
  src = (char *)operator new[](2 * v7 + 1);
  do
  {
    v1 = (unsigned __int8)s[v5];
    src[v6] = sub_1078(~(_BYTE)v1 & 0xF);
    v2 = v6 + 1;
    src[v2] = sub_1078((v1 >> 4) ^ 0xE);
    ++v5;
    v6 = v2 + 1;
  }
  while ( v5 < v7 );
  src[2 * v7] = 0;
  strncpy(s, src, 2 * v7 + 1);
  return s;

代碼如上,只能說算法還是挺簡單的
將輸入的每一位經過運算化爲src的兩位,然後返回得到的字符串。
邏輯大概就是這樣,flag可以經過爆破得出,直接上腳本。

s="9838e888496bfda98afdbb98a9b9a9d9cdfa29"
st=list(s)
def subl(a):
    v1=0
    if(a>9 or a<0):
        if(a<=9 or a>15):
            v1=255
        else:
            v1=a+87
    else:
        v1=a+48
    return v1
print len(s)
key=""
for i in range(0,38,2):
    for j in range(32,128):

        if subl(~j&0xF)==ord(st[i]) and subl((j>>4)^0xE)==ord(st[i+1]):
            key+=chr(j)
            break;
print key

0x2取證密碼

輸入在GetString.encrypt函數裏面進行驗證,encrypt爲XTU.so文件的函數,代碼如下

v3 = a1;
  _JNIEnv::NewStringUTF(a1, "yInS567!bcNOUV8vwCDefXYZadoPQRGx13ghTpqrsHklm2EFtuJKLzMijAB094W");
  _JNIEnv::NewStringUTF(v3, "Welc0meT0XTUCTF");
  v4 = (const char *)_JNIEnv::GetStringUTFChars((int)v3);
  str = (const char *)_JNIEnv::GetStringUTFChars((int)v3);
  input = (char *)_JNIEnv::GetStringUTFChars((int)v3);
  v7 = j_j_strlen(v4);
  v8 = j_j_strlen(str);
  temp = (char *)j_operator new[](v7 + 1);
  v10 = (char *)j_operator new[](v8 + 1);
  v11 = j_j_strlen(input);
  v15 = (char *)j_operator new[](v11 + 1);
  j_j_memcpy(&dest, &unk_2018, 0x3Cu);
  j_j_strcpy(temp, v4);
  j_j_strcpy(v10, str);
  j_j_strcpy(v15, input);
  for ( i = 0; i < j_j_strlen(v4); ++i )
    temp[i] = v10[*((_DWORD *)&dest + i)];
  v13 = 0;
  while ( (unsigned __int8)v15[v13] == (unsigned __int8)temp[v13] )
  {
    if ( ++v13 == 15 )
      return 1;
  }
  return 0;

看見這個代碼開始我是蒙逼的,,找不到代表輸入的臨時變量是哪個,,
只能大膽的猜測,v15既input爲輸入,str爲yInS567!bcNOUV8vwCDefXYZadoPQRGx13ghTpqrsHklm2EFtuJKLzMijAB094W,取dest的值作爲str的下標賦值給temp,然後與input進行比較,腳本如下。

s="yInS567!bcNOUV8vwCDefXYZadoPQRGx13ghTpqrsHklm2EFtuJKLzMijAB094W"
dest=[0x39,0x20,7,0xA,0x20,0x29,0x13,2,0x3A,0xC,0x11,0x31,0x3B,0xB,7]
s=list(s)
flag=""
for i in range(len(dest)):
    flag+=s[dest[i]]
print flag

沒想到真的是這樣,,getflag。

0x3 人民的名義-抓捕趙德漢1

由於是jar文件,所以直接用jd-gui軟件打開。
將輸入的字符串載入checkPassword函數驗證。
無用代碼比較多,差點就被迷惑了~~

將輸入的字符串進行md5加密,然後與fa3733c647dca53a66cf8df953c2d539進行比較。
由於以前做的md5加密的題比較多,這個題還挺簡單的。
將fa3733c647dca53a66cf8df953c2d539解密md5即可。

0x4 人民的名義-抓捕趙德漢2

程序載入jd-hui後亂碼比較多,這個題難度比上一個題提升了不少。

 public static void main(String[] args)
  {
    JFrame frame = new JFrame("Key check");
    JButton button = new JButton("Click to activate");

    button.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent ae)
      {
        String str = JOptionPane.showInputDialog(null, "Enter the product key: ", 
          "xxxx-xxxx-xxxx-xxxx", 1);
        if (????????????.???(str)) {
          JOptionPane.showMessageDialog(null, "Well done that was the correct key", 
            "Key check", 1);
        } else {
          JOptionPane.showMessageDialog(null, "               Sorry that was the incorrect key \nRemember it is a crime to use software without paying for it", 
            "Key check", 1);
        }
      }
    });
    JPanel panel = new JPanel();
    panel.add(button);
    frame.add(panel);
    frame.setSize(300, 100);
    frame.setDefaultCloseOperation(3);
    frame.setVisible(true);
  }
}

這裏需要注意的一點就是,輸入是以xxxx-xxxx-xxxx-xxxx格式進行輸入的!
將驗證函數修改一下如下,

public class iiiiiiiiiiii
{
  static String key1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  static String _ii = "ZYXWVUTSRQPONMLKJIHGFEDCBA";

  public static boolean iii(String str)
  {
    if ((str != null) && (str.length() == 19))
    {
      key1 = System.arraycopy(_ii, 0, key1, 5, 5);

      boolean keyGuessWrong = true;
      int i = 0;
      for (int i = 0; i < 4; i++)
      {
        for (int j = 0; j < 4; j++) {
          if (str.charAt(i + j) != key1.charAt(Start.operate(i + j, key1))) {
            keyGuessWrong = false;
          }
        }
        i += 5;
      }
      return keyGuessWrong;
    }
    return false;
  }

將i+j,和key1放到operate函數進行變換,然後與輸入進行比較。
其中key1爲start.main()得到的字符串。

public static String main(String... args)
  {
    String x = "";
    char[] arrayOfChar;
    int j = (arrayOfChar = "v??��??????v?��??????����??".toCharArray()).length;
    for (int i = 0; i < j; i++)
    {
      int $ = arrayOfChar[i];
      x = x + (char)(($ >> 1) + 15);
    }
    return x;
  }

但是這有個亂碼,,,很是難爲了一番。最後經Simp1er表哥提示換種別工具可以得到這一個字符串,如下圖。
image
最後,按照慣例附上腳本

key1="JsnatterrtJuaththovacke"
li=[0x76,0xC3,0x88,0xC2,0xBE,0xC2,0xA4,0xC3,0x8A,0xC3,0x8A,0xC2,0xAC,0xC3,0x86,
    0xC3,0x86,0xC3,0x8A,0x76,0xC3,0x8C,0xC2]
key=""
for i in li:
    key+=chr((i>>1)+15)
s=list(key1)
def digui(a):
    if a>2:
        return digui(a-1)+digui(a-2)
    else:
        return 1
flag=""
for i in range(4):
    a=i*5
    for j in range(4):
        flag+=s[digui(a+j)%len(s)]
    if i!=3:    
        flag+="-"
print flag

附上題目及工具:http://pan.baidu.com/s/1eRI2HSA
密碼:xpxn

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章