)
数据库密码即加密密钥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} 从解密后的日志中提取出三条关键证据攻击者 IP203.0.113.88执行 shell_exec 和 file_steal 操作的 IP关键日志 IDLOG-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}reCodeSign一个移动保险库显示访问已被允许但秘密仍然没有出现在眼前。请理解应用如何决定展示内容并还原隐藏结果。apk安卓逆向跳到主activitypublic 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