- 数据库密码(即加密密钥):AIDoc#2024Secure
- 原始哈希:用于验证日志完整性的 SHA256
<?php $data = file_get_contents('/var/www/html/uploads/admin/upload_logs/access.log.backup'); $key = 'AIDoc#2024Secure'; $decrypted = ''; for ($i = 0; $i < strlen($data); $i++) { $decrypted .= chr(ord($data[$i]) ^ ord($key[$i % strlen($key)])); } echo nl2br(htmlspecialchars($decrypted)); ?>解密结果:
{"time":"2024-10-10 14:30:12","ip":"192.168.1.100","action":"upload","file":"report.pdf","status":"success"} {"time":"2024-10-10 15:14:51","ip":"203.0.113.88","action":"shell_exec","command":"cat /opt/secrets/operation_darknet.txt","log_id":"LOG-20241010-88239","severity":"critical"} {"time":"2024-10-10 15:15:22","ip":"203.0.113.88","action":"file_steal","file":"operation_darknet.txt","size":4521,"log_id":"LOG-20241010-88240","severity":"critical"} 从解密后的日志中提取出三条关键证据:- 攻击者 IP:203.0.113.88(执行 shell_exec 和 file_steal 操作的 IP)
- 关键日志 ID:LOG-20241010-88239(首次 shell_exec 的日志条目,标记为 critical 严重级别)
- 被窃取的机密文件:operation_darknet.txt(攻击者从 /opt/secrets/ 目录窃取的文件)
访问 submit.php,提交三个值:
Attacker IP: 203.0.113.88 Key Log ID: LOG-20241010-88239 Confidential File Name: operation_darknet.txt返回结果:
Verification passed: flag{1jsm71kr3inr981udk4j7jq5s2s5iia7}re
CodeSign
一个移动保险库显示访问已被允许,但秘密仍然没有出现在眼前。请理解应用如何决定展示内容,并还原隐藏结果。
apk安卓逆向
跳到主activity
public class MainActivity extends AppCompatActivity { private static final byte[] SECRET_DATA = {86, 10, 3, 1, 77, 124, 123, 97, 109, 37, 64, 90, 2, 89, 8, 5, 111, 115, 64, 66, 4, 16, 65, 62, 123, 8, 88, 81, 30}; @Override // androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity protected void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.activity_main); final TextView textView = (TextView) findViewById(R.id.tv_console); final TextView textView2 = (TextView) findViewById(R.id.tv_flag); ((Button) findViewById(R.id.btn_unlock)).setOnClickListener(new View.OnClickListener() { // from class: com.icqctf.signcheck.MainActivity$$ExternalSyntheticLambda0 @Override // android.view.View.OnClickListener public final void onClick(View view) { this.f$0.m125lambda$onCreate$0$comicqctfsigncheckMainActivity(textView2, textView, view); } }); } /* renamed from: lambda$onCreate$0$com-icqctf-signcheck-MainActivity, reason: not valid java name */ /* synthetic */ void m125lambda$onCreate$0$comicqctfsigncheckMainActivity(TextView textView, TextView textView2, View view) { String strDecrypt = decrypt(SECRET_DATA, SignUtils.getAppSignature(this)); textView.setText(strDecrypt); if (strDecrypt.startsWith("flag{")) { textView2.setText("> ACCESS GRANTED.\n> DATA RENDERED TO BUFFER.\n> UI OUTPUT: DISABLED (Security Mode)"); textView2.setTextColor(-16711936); } else { textView2.setText("> SIGNATURE MISMATCH.\n> DECRYPTION FAILED.\n> OUTPUT GARBAGE."); textView2.setTextColor(SupportMenu.CATEGORY_MASK); } } private String decrypt(byte[] bArr, String str) { if (str == null || str.length() == 0) { return ""; } byte[] bytes = str.getBytes(); byte[] bArr2 = new byte[bArr.length]; for (int i = 0; i < bArr.length; i++) { bArr2[i] = (byte) (bArr[i] ^ bytes[i % bytes.length]); } return new String(bArr2); } }直接找关键逻辑
if (strDecrypt.startsWith("flag{")) { textView2.setText("> ACCESS GRANTED.\n> DATA RENDERED TO BUFFER.\n> UI OUTPUT: DISABLED (Security Mode)");要String strDecrypt以flag{开头
再去看String strDecrypt的逻辑
String strDecrypt = decrypt(SECRET_DATA, SignUtils.getAppSignature(this)); private String decrypt(byte[] bArr, String str) { if (str == null || str.length() == 0) { return ""; } byte[] bytes = str.getBytes(); byte[] bArr2 = new byte[bArr.length]; for (int i = 0; i < bArr.length; i++) { bArr2[i] = (byte) (bArr[i] ^ bytes[i % bytes.length]); } return new String(bArr2); }逻辑不复杂,把SECRET_DATA和SignUtils.getAppSignature进行异或
继续跳转去看getAppSignature