羊城杯 2021Ez_android

runwu2204 Lv6

两个activity,需要注意

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" android:compileSdkVersion="30" android:compileSdkVersionCodename="11" package="top.zjax.login" platformBuildVersionCode="30" platformBuildVersionName="11">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application android:theme="@style/Theme.Login" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:allowBackup="true" android:supportsRtl="true" android:roundIcon="@mipmap/ic_launcher_round" android:appComponentFactory="androidx.core.app.CoreComponentFactory">
<activity android:name="top.zjax.login.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="top.zjax.login.CheckFlagActivity"/>
</application>
</manifest>

mainactivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package top.zjax.login;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/* loaded from: classes.dex */
public class MainActivity extends Activity implements View.OnClickListener {
Button loginBtn = null;
EditText useridEt = null;
EditText passEt = null;
TextView promptText = null;
String key = "";

@Override // android.app.Activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(C0818R.layout.activity_main);
Button button = (Button) findViewById(C0818R.C0821id.loginBtn);
this.loginBtn = button;
button.setOnClickListener(this);
this.useridEt = (EditText) findViewById(C0818R.C0821id.userId);
this.passEt = (EditText) findViewById(C0818R.C0821id.pass);
this.promptText = (TextView) findViewById(C0818R.C0821id.promptText);
}

@Override // android.view.View.OnClickListener
public void onClick(View v) {
String trim = this.useridEt.getText().toString().trim();
String trim2 = this.passEt.getText().toString().trim();
if (trim.equals("")) {
this.promptText.setText(C0818R.string.userIdError);
} else if (trim2.equals("")) {
this.promptText.setText(C0818R.string.passError);
} else if (checkUsername(trim) && checkPasswd(trim2)) {
Toast.makeText(this, (int) C0818R.string.loginSuccess, 1).show();
getKeyAndRedirect(trim2);
} else {
Toast.makeText(this, (int) C0818R.string.loginError, 1).show();
}
}

private boolean checkUsername(String username) {
return username.equals(getString(C0818R.string.username));
}

private boolean checkPasswd(String passwd) {
return getEncodeStr(passwd).equals(getString(C0818R.string.passwd));
}

private String getEncodeStr(String str) {
byte[] bArr = null;
try {
bArr = MessageDigest.getInstance(getString(C0818R.string.encode)).digest(str.getBytes(StandardCharsets.UTF_8));
for (int i = 0; i < bArr.length; i++) {
bArr[i] = (byte) (bArr[i] - 1);
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return new BigInteger(1, bArr).toString(16);
}

private void getKeyAndRedirect(final String passwd) {
new Thread(new Runnable() { // from class: top.zjax.login.-$$Lambda$MainActivity$6RDmmwJ9hKunKEQ8YxFB_mVwQ0E
@Override // java.lang.Runnable
public final void run() {
MainActivity.this.lambda$getKeyAndRedirect$0$MainActivity(passwd);
}
}).start();
while (this.key.length() == 0) {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Intent intent = new Intent(this, CheckFlagActivity.class);
intent.putExtra("key", this.key);
startActivity(intent);
finish();
}

public /* synthetic */ void lambda$getKeyAndRedirect$0$MainActivity(final String passwd) {
try {
Socket socket = new Socket("139.224.191.201", 20080);
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
bufferedWriter.write(passwd);
bufferedWriter.newLine();
bufferedWriter.flush();
setKey(bufferedReader.readLine().split(":")[1].trim());
bufferedReader.close();
bufferedWriter.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}

public void setKey(String key) {
this.key = key;
}
}

通过查字符串表获取username和passwd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private boolean checkUsername(String username) {
return username.equals(getString(C0818R.string.username));
}

private boolean checkPasswd(String passwd) {
return getEncodeStr(passwd).equals(getString(C0818R.string.passwd));
}
private String getEncodeStr(String str) {//此处是md5算法
byte[] bArr = null;
try {
bArr = MessageDigest.getInstance(getString(C0818R.string.encode)).digest(str.getBytes(StandardCharsets.UTF_8));
for (int i = 0; i < bArr.length; i++) {
bArr[i] = (byte) (bArr[i] - 1);
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return new BigInteger(1, bArr).toString(16);
}//此处将md5后的每2个16进制数减了1
1
2
3
<string name="encode">md5</string><!--上图的C0818R.string.encode-->
<string name="username">admin</string>
<string name="passwd">c232666f1410b3f5010dc51cec341f58</string><!--此处是经过md5和一个自定义编码的passwd-->

实际的md5(passwd)为

1
2
3
4
5
6
7
8
In [1]: str1='c232666f1410b3f5010dc51cec341f58'
In [8]: tmp1=''
...: for i in range(0,len(str1),2):
...: tmp1+='{:0>2X}'.format(int(str1[i]+str1[i+1],16)+1)
...:

In [9]: tmp1
Out[9]: 'C33367701511B4F6020EC61DED352059'

passwd

image-20230623192207082

其连接了一个链接输入了passwd获取了key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    public /* synthetic */ void lambda$getKeyAndRedirect$0$MainActivity(final String passwd) {
try {
Socket socket = new Socket("139.224.191.201", 20080);
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
bufferedWriter.write(passwd);
bufferedWriter.newLine();
bufferedWriter.flush();
setKey(bufferedReader.readLine().split(":")[1].trim());
bufferedReader.close();
bufferedWriter.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}

public void setKey(String key) {
this.key = key;
}
}
1
2
3
C:\Users\wrwrw>nc node4.anna.nssctf.cn 28110
654321
key: TGtUnkaJD0frq61uCQYw3-FxMiRvNOB/EWjgVcpKSzbs8yHZ257X9LldIeh4APom

其将key传给了另外的activity CheckFlagActivity

1
2
3
Intent intent = new Intent(this, CheckFlagActivity.class);
intent.putExtra("key", this.key);
startActivity(intent);

这个组件接受了key

1
2
3
4
5
6
7
8
9
10
11
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(C0818R.layout.activity_checkflag);
Button button = (Button) findViewById(C0818R.C0821id.flagBtn);
this.flagBtn = button;
button.setOnClickListener(this);
this.flagTx = (EditText) findViewById(C0818R.C0821id.flagTx);
this.promptText = (TextView) findViewById(C0818R.C0821id.promptText);
this.key = getIntent().getStringExtra("key");
}

通过如下方法验证密文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
    private boolean checkFlag(String flag) {
return new String(EncodeUtils.encode(flag.getBytes(StandardCharsets.UTF_8), false, this.key.getBytes(StandardCharsets.UTF_8))).equals(getString(C0818R.string.encodeFlag));
}//
/*************************************下面的是base64算法但encodeTable是之前获取到的key***************************/
//key=TGtUnkaJD0frq61uCQYw3-FxMiRvNOB/EWjgVcpKSzbs8yHZ257X9LldIeh4APom
public static byte[] encode(byte[] arr, boolean isMultiLine, byte[] encodeTable) {
if (arr == null) {
return null;
}
int length = arr.length;
if (length == 0) {
return new byte[0];
}
int i = (length / 3) * 3;
int i2 = length - 1;
int i3 = ((i2 / 3) + 1) << 2;
int i4 = i3 + (isMultiLine ? ((i3 - 1) / 76) << 1 : 0);
byte[] bArr = new byte[i4];
int i5 = 0;
int i6 = 0;
int i7 = 0;
while (i5 < i) {
int i8 = i5 + 1;
int i9 = i8 + 1;
int i10 = ((arr[i5] & 255) << 16) | ((arr[i8] & 255) << 8);
int i11 = i9 + 1;
int i12 = i10 | (arr[i9] & 255);
int i13 = i6 + 1;
bArr[i6] = encodeTable[(i12 >>> 18) & 63];
int i14 = i13 + 1;
bArr[i13] = encodeTable[(i12 >>> 12) & 63];
int i15 = i14 + 1;
bArr[i14] = encodeTable[(i12 >>> 6) & 63];
i6 = i15 + 1;
bArr[i15] = encodeTable[i12 & 63];
if (isMultiLine && (i7 = i7 + 1) == 19 && i6 < i4 - 2) {
int i16 = i6 + 1;
bArr[i6] = 13;
i6 = i16 + 1;
bArr[i16] = 10;
i7 = 0;
}
i5 = i11;
}
int i17 = length - i;
if (i17 > 0) {
int i18 = ((arr[i] & 255) << 10) | (i17 == 2 ? (arr[i2] & 255) << 2 : 0);
bArr[i4 - 4] = encodeTable[i18 >> 12];
bArr[i4 - 3] = encodeTable[(i18 >>> 6) & 63];
bArr[i4 - 2] = i17 == 2 ? encodeTable[i18 & 63] : (byte) 61;
bArr[i4 - 1] = 61;
}
return bArr;
}

1
2
<string name="encodeFlag">3lkHi9iZNK87qw0p6U391t92qlC5rwn5iFqyMFDl1t92qUnL6FQjqln76l-P</string>
<!--base64变表为 TGtUnkaJD0frq61uCQYw3-FxMiRvNOB/EWjgVcpKSzbs8yHZ257X9LldIeh4APom -->

用变表解密

image-20230623192902530

获取到了flag

  • 标题: 羊城杯 2021Ez_android
  • 作者: runwu2204
  • 创建于 : 2023-06-23 19:04:51
  • 更新于 : 2023-06-23 19:30:52
  • 链接: https://runwu2204.github.io/2023/06/23/CTF WP/Re/安卓/羊城杯 2021Ez_android/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
羊城杯 2021Ez_android