BugKu reverse question type
This is the 10th day of my participation in the August Text Challenge.More challenges in August
1. Reverse entry
Files are analyzed directly by IDA
66h, 6CH, 61H, 67h: Under the flag of hexadecimal representation, hexadecimal conversion, transformation input online content, 66 h6ch61h67h7bh52h65h5fh31h73h5fh53h30h5fh43h30h4fh4ch7dh, get the result of the conversion, namely for the flag: flag{Re_1s_S0_C0OL}
2.Easy_vb
Open easy_vb.exe with IDA, you can see flag:
flag{N3t_Rev_1s_E4ay}
3.Easy_Re
Hex View (IDA); hex View (hex View)
DUTCTF{We1c0met0DUTCTF}
4. Pass the game
1-8 Type it once, okay?
As long as each number from 1 to 8 is entered only once, then you can get a flag.
Flag is obtained:
zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}
5. The Timer (CTF) ali
BugKuCTF 第 4 段 题目 标 题 writeup: Android reverse Timer(ali CTF)writeup:
flag{Y0vAr3TimerMa3te7}
6. Reverse entry
After opening it with Winhex and finding an image and taking its copy method like amdin.txt, Using the Data URL to generate a Data stream form for small images comes from placing the ASCII code of admin.txt in admin-image.html or online
bugku{inde_9882ihsd8-0}
Flag: bugku{inde_9882iHSd8-0}
7.love
Exe, drag into IDA main from bugkuCTF platform
flag{i_l0ve_you}
8.LoopAndLoop (Ali CTF)
Jeb decompilation into Java, view the main function
this.findViewById(2131492946).setOnClickListener(new View$OnClickListener(this.findViewById(2131492944), this.findViewById(2131492945), this.findViewById(2131492947)) {
public void onClick(View arg7) {
int v1;
String v2 = this.val$ed.getText().toString();
try {
v1 = Integer.parseInt(v2);
}
catch(NumberFormatException v0) {
this.val$tv1.setText("Not a Valid Integer number");
return;
}
if(MainActivity.this.check(v1, 99) = =1835996258) {
this.val$tv1.setText("The flag is:");
this.val$tv2.setText("alictf{" + MainActivity.this.stringFromJNI2(v1) + "}");
}
else {
this.val$tv1.setText("Not Right!"); }}});Copy the code
The key is that if check is equal to the following number, it will proceed to the flag paragraph and then use stringFromJNI2 to transform it
If v1 fails to convert numbers, the output 'Not a Valid Integer number' is displayed. If it is correct, the output 'Not right' is displayedCopy the code
So file is located in the lib folder at the same level as classes.dex. Enter IDA file for analysis. F5 search for the location string and find the main function. Result = _JNIEnv::CallIntMethod(v4, v9, *(&v10 + 2 * v8%3), v7, v8-1); This is a select statement that selects check1, 2,3
Reverse code 1. Details are as follows
#include <iostream>
#include <stdio.h>
using namespace std;
int ans=1835996258;
int main(a)
{
int j;
for(int i=99; i>1; i--) { j=i*2 % 3;
if(j==0)
{
ans-=4950;
}
else if(j==1)
{
if((i- 1) %2= =0)#include <iostream>
Copy the code
#include <stdio.h>
using namespace std;
int ans=1835996258;
int main(a)
{
int j;
for(int i=99; i>1; i--) { j=i*2 % 3;
if(j==0)
{
ans-=4950;
}
else if(j==1)
{
if((i- 1) %2= =0)
ans-=499500;
else
ans+=499500;
}
else
{
ans-=49995000; }}printf("%d\n",ans);
return 0;
}
ans-=499500;
else
ans+=499500;
}
else
{
ans-=49995000; }}printf("%d\n",ans);
return 0;
}
Copy the code
Or: reverse code 2, as follows
def check1(input,loop) :
a=input
for i in range(1.100):
a=a-i
return a
def check2(input,loop) :
a=input
if loop%2= =0:
for i in range(1.1000):
a=a-i
else:
for i in range(1.1000):
a=a+i
return a
def check3(input,loop) :
a=input
for i in range(1.10000):
a=a-i
return a
key=1835996258
target = key
for i in range(2.100) :if 2 * i % 3= =0:
target = check1(target,i - 1)
elif 2 * i % 3= =1:
target = check2(target,i - 1)
else:
target = check3(target,i - 1)
print(target)
# 236492408
Copy the code
LoopAndLoop: check (chec) : check (chec) : check (cheC) : check (cheC) : check (cheC) : check (cheC) : check (cheC) : check (cheC) : check (cheC) : check (cheC) The function chec in check2 calls check3 and chec in check3 calls check1. When the second argument is 1, cheC directly returns the value of argument 1, which is the recursive boundary. It is estimated that the native Chec function only does this, so there is no need to reverse liblhm.so. Check1 and check3 both add or remove a number based on the parity of the second parameter. So 99 steps forward from the final check condition, 1835996258, results in the correct input.
from ctypes import *
SA = sum(range(100))
SB = sum(range(1000))
SC = sum(range(10000))
S0 = 1835996258
for i in range(1.99) :if i % 3= =0:
S0 = c_int(S0-SC).value
if i % 3= =2:
S0 = c_int(S0-SA).value
if i % 3= =1:
if i % 2= =0:
S0 = c_int(S0-SB).value
else:
S0 = c_int(S0+SB).value
print S0
print hex(S0)
for i in range(98.0, -1) :if i % 3= =0:
S0 = c_int(S0+SC).value
if i % 3= =2:
S0 = c_int(S0+SA).value
if i % 3= =1:
if i % 2= =0:
S0 = c_int(S0+SB).value
else:
S0 = c_int(S0-SB).value
print hex(S0)
print S0
Copy the code
You get the number you should enter 236492408 so flag is
alictf{Jan6N100p3r}
9. Reverse easy100 (LCTF)
Reference 1, reference 2
Decompile first JEB decompile then export the project
(1) View MainActivity code
protected void onCreate(Bundle arg3) {
super.onCreate(arg3);
this.setContentView(2130968602);
ApplicationInfo v0 = this.getApplicationInfo();
v0.flags &= 2;
this.p();
this.findViewById(2131427413).setOnClickListener(new d(this));
}
Copy the code
(2) Analysis, Main function, first execute p function,p function will be used later, not talk about. Create a button listening event in classs D. The onclick function in class D, when we click on the Android button, triggers the function.
public void onClick(View arg5) {
if(MainActivity.a(this.a, MainActivity.a(this.a), this.a.findViewById(2131427414).getText().toString())) {
View v0 = this.a.findViewById(2131427412);
Toast.makeText(this.a.getApplicationContext(), "Congratulations!", 1).show();
((TextView)v0).setText(2131099682);
}
else {
Toast.makeText(this.a.getApplicationContext(), "Oh no.", 1).show();
}
}
Copy the code
The first argument is the handle. The second argument is that a was called (the other one) and returns a string. The third argument is the string we entered.
(3) Analysis of A function
private String v;
static String a(MainActivity arg1) {
return arg1.v;
}
Copy the code
By calling a, we return the string v in Main, which is initialized in p.
(4) P function analysis
private void p(a) {
try {
InputStream v0_1 = this.getResources().getAssets().open("url.png");
int v1 = v0_1.available();
byte[] v2 = new byte[v1];
v0_1.read(v2, 0, v1);
byte[] v0_2 = new byte[16];
System.arraycopy(v2, 144, v0_2, 0.16);
this.v = new String(v0_2, "utf-8");
}
catch(Exception v0) { v0.printStackTrace(); }}Copy the code
The p function reads the binary data of an image and retrieves the byte[144:144+16] data stored in the v string.
If statement (a); if statement (a);
static boolean a(MainActivity arg1, String arg2, String arg3) {
return arg1.a(arg2, arg3);
}
private boolean a(String arg4, String arg5) {
return new c().a(arg4, arg5).equals(new String(new byte[] {21, -93, -68, -94.86.117, -19, -68, -92.33.50.118.16.13.1, -15, -13.3.4.103, -18.81.30.68.54, -93.44, -23.93.98.5.59}));
}
Copy the code
It can be seen that function A (with three arguments) calls function A (with two arguments). Function A (with two arguments) calls c (with two arguments). After the calculation, compare with the following bytes. If they are equal, flag is displayed.
(6) Analysis of A function (two parameters)
public String a(String arg5, String arg6) {
String v0 = this.a(arg5);
String v1 = "";
a v2 = new a();
v2.a(v0.getBytes());
try {
v0 = new String(v2.b(arg6.getBytes()), "utf-8");
}
catch(Exception v0_1) {
v0_1.printStackTrace();
v0 = v1;
}
return v0;
}
Copy the code
and
this.a = new SecretKeySpec(arg4, "AES");
this.b = Cipher.getInstance("AES/ECB/PKCS5Padding");
Copy the code
Arg5 is a string taken from the image, and arg6 is what we typed. The following code is mainly AES encryption. Take the transformed string of arg5 as the password, and compare the input string with the given string after AES encryption. If it is equal, flag is obtained.
Summary algorithm topics mainly investigate AES encryption, ECB mode, PKCS5Padding, the key is the change of member V in MainActivity, and the plaintext is the content input in app. The AES encrypted result is then compared to the String converted from the Byte array. If they are the same, “warning” is displayed, indicating that “warning” is entered. From, then we can directly decrypt AES to get flag. See getkey.py to get the hexadecimal password, then decrypt AES to get flag:
LCTF{1t’s_rea1ly_an_ea3y_ap4}
10. SafeBox (NJCTF)
Put the code directly into Jeb for disassembly export code refer to 1, refer to 2
See line 18-37 at the key position of onCreate method, input an 8-digit number to meet the conditions, and then combine it with NJCTF{and f4N} after transformation. This 8-digit number is a palindrome number, and the restriction is relatively specific. Use the Python script to blow up the bomb. For details about the script, see flag-get.py.
I =48533584, flag: NJCTF{05# f4N}
This does not limit the middle two digits to be equal and is followed by +10. Continue with the script explosion, as shown in flag-get2.py
NJCTF{have05-f4n} 48539584 NJCTF{have05IF4n}
NJCTF{have05IF4n}
11.Mountain climbing
Run without a component, did not find a separate component. The download tool used PEID to check and found UPX shell. Download the shucking tool at 52pojie
12.Take the maze
Reference, PEID view, no shell, IDA analysis.