Computer system experiment 2: bomb experiment bomb

Problem Description

bomb test

Purpose

This experiment is an experiment to familiarize yourself with the assembler and its debugging method.
The experimental content contains 2 files bomb (executable file) and bomb.c (c source file).
The subject of the experiment is: the program runs in the linux environment. There are 6 checkpoints (6 phases) in the running of the program, and each phase requires the user to enter specific characters or numbers on the terminal to pass the level, otherwise the bomb will be detonated! So how do you know what to type? This requires you to use the gdb tool to disassemble the assembly code, and combine the c language file to find the entry function of each level. Then analyze the assembly code, find the place where the boot program jumps to the "explode_bomb" program segment in each phase program segment, and analyze the conditions for its successful jump, and use this as a breakthrough to find out what characters should be entered on the command line to clear the level .
The experiment needs to use the gdb tool, and you can find the gdb usage method and parameters on the Internet.

lab environment

Ubuntu 16.04 32 bit

Experimental content and steps

A piece of advice from an old school sister:
To be honest, this bomb experiment is quite interesting. I suggest you try it yourself. If you really have no idea, then look at the online solution. After the completion, the ability to analyze and compile is really greatly improved! ! ! Also, you must work hard to do this experiment. It is best to find a day to dismantle it. There is also a hidden gate. Don't be scared by it. It is not difficult, the main thing is to see how to get in.
Alright, let's stop nagging senior sister
Let's continue our learning journey
I love learning! ! ! !

【Experimental principle】
Binary bomb is a program provided to students as an object code file. When running, it prompts the user to input 6 different character strings. If any of these are incorrect, the bomb "explodes": an error message is printed. Students use disassembly and reverse engineering to determine which six strings are used to detonate their respective bombs
[Experimental process]
1. Preparation stage
1. After downloading the 32-bit experimental code, decompress the file and share the file Folder operation to add the file to the virtual machine, double-click to view the bomb.c code, and read the c code completely, and found that the c code here is impossible to start with. The code only contains the main function, and the process of triggering the bomb is hidden. stand up. After reading the readme file given by the teacher, I learned that the answer to this question needs to be analyzed and debugged in the Linux terminal.
2. Enter objdump -d bomb to disassemble the executable file into an assembly file. For easy viewing, you can use objdump -d bomb >1.txt to output the assembly code to a txt file. 3. To test the effect of the bomb explosion,
gdb Debug the executable file, input a random string, and it exploded.
insert image description here
2. Start dismantling the bomb
First find the main function and find that it calls six functions from phase1 to phase6. These functions are the functions that need to be understood for each level.
The first level: first find phase1, which should represent the first level, the code is as follows:
insert image description here
First, analyze the assembly code. Firstly, the esp pointer moves down to create a larger space. Then the code $0x804a1e4, 0x4(%esp) has an immediate value, which is to transfer the value of this address to %esp+0x4 location, enter gdb bomb to enter the debugging state, use x/s 0x804a1e4 to view the content of the address, press Enter to display the string "I am not part of the problem. I am a Republican.", the following code statement mov 0x20(% esp), %eax is to put the input string into %eax, and then the following sentence is to put it into %esp, and then call the function <string_not_equal>, it is easy to guess that the content to be input should be the address 0x804a1e4.
je is to jump if it is equal, and test %eax %eax is to perform a logical AND operation on the two. Analysis shows that if %eax!=0, <explode_bomb> will be called.
Verification: set breakpoint b phase_1, enter run to run, enter the program, enter "I am not part of the problem. I am a Republican." in the next line of the input prompt, and the terminal displays "phase 1 defused. How about the next one ?”, the first level was successfully passed.
insert image description here

The second level: Find phase2, which represents the second level. The assembly code is as follows: The
insert image description here
following is the analysis of the assembly code: first, it is easy to observe that there is a call to the function <read_six_number> in phase_2. Through the analysis, we can know that the second level needs to input six A correct number, how to calculate the number needs to look at the following assembly code.
jns 8048bf5 <phase_2+0x41> compares %esp+0x18 with 0, jumps if %esp+0x18 is not negative, and triggers a bomb if it is negative. %esp+0x18 is the first number we need to input. It is speculated that a non-negative number needs to be input here. Here I choose the favorite 1 according to my own preferences, and then jump to a loop. The second number goes to the first All six numbers are deduced by the loop. First set eax and ebx to 1, and then the key instructions are add 0x14(%esp,%ebx,4),%eax and cmp %eax,0x18(%esp,%ebx,4), to judge the current input number and the above Whether a number + the current value of %eax is equal, if not, the bomb will be triggered. Then add 1 to eax and ebx, and continue to loop until the loop condition is not satisfied.
Let the numbers be num[1]-num[6], where num[1] is a non-negative number, and the numbers from num[2] to num[6] The law can be summarized by the following equation: num[n]=num[n-1]+n-1
Verification: Terminal input "1 2 4 7 11 16" displays "That's number 2. Keep going!" The second level is successful pass.
insert image description here
The third level: find phase_3, its assembly code is as follows:
insert image description here
analyze the assembly code below:
first, you can clearly find the call of the function scanf, before calling the function, notice that there is immediate addressing: movl $0x804a23e,0x4(% esp). Enter the command x/s 0x804a23e, and the content stored in this address is: %d %c %d:
insert image description here

That is, enter three contents, two numbers plus one character. cmp $0x2,%eax indicates that at least two parameters must be entered. Go down to cmpl $0x7,0x28(%esp) and ja 8048d41 <phase_3+0x140>, the first parameter entered must be less than 7, otherwise it will explode. Further down, you can see jmp 0x804a260(,%eax,4), which is a typical switch statement, which jumps to the jump table based on address 0x804a260. Enter p/x *0x804a260, you can see that the corresponding address is 0x8048c50.
insert image description here
For the sake of simplicity, I choose 0 for the first parameter, so the calculated address here is 0x8048c50, find this address, execute the instruction mov $0x78,%eax and cmpl $0x39f,0x2c(%esp), guess %esp+2c The value must be equal to 0x39f, then jump to 0x08048d4b, which is cmp 0x27(%esp), %al, it is speculated that the value of %esp+0x27 should be equal to the value of %al, %al is the lower 8 bits of %eax, that is 0x78 assigned before the jump. So it is concluded that in the case where the first number entered is 0, the answer is 0 x 927 respectively.
Use the Linux terminal to verify:
input 0 x 927, press Enter to display "Halfway there", and pass the third level successfully.
insert image description here
The fourth level: find phase_4, its assembly code is as follows:
insert image description here
analyze the assembly code below:
first find movl $0x804a3cf,0x4(%esp), here is another immediate value, use gdb to check the value of this address, it shows " %d %d", it can be inferred that this level needs to input two numbers. Then to judge the return value of the scanf function, two parameters must be input. Next: cmpl $0xe, 0x18(%esp) requires that the first number must first meet the condition of being less than 0xe, and then call the function func4(), the assembly code of this function is as follows:
insert image description here

The return value after calling the function func4() must be less than or equal to 3, so there is a further restriction on the first number. After analyzing the function of func4(), it is found that it is actually a recursion, and it is converted to c Language, because calculating the recursion is cumbersome, so I used the code to calculate all the numbers that meet the requirements.
insert image description here

The running results are: 12, 13, so the value of the first number is only 12 or 13. For the second number to be input, cmpl $0x3,0x1c(%esp) limits the second input number to only 3.
Verification: Take one of the answer combinations: 13, 3, press Enter to display "So you got that one. Try this one", and pass the fourth level successfully.
insert image description here

Fifth level: find phase_5, its assembly code is as follows:
insert image description here

The following is the analysis of the assembly code:
from string_length and the subsequent cmp $0x6,%eax, it can be speculated that a string with a length of 6 is to be input. Next is a loop, first set edx and eax to 0, then add 1 to eax each time, and exit the loop until 6, in each loop movzbl (%ebx,%eax,1),%ecx and and $0xf, %ecx is to take out the last byte of the characters in the string in turn, and then add this value to the value in the address after adding 0x0804a280 to the last value and compare it with 0x45. Now it is difficult to analyze to such an extent to get the answer. Use gdb to view the values ​​stored in the 16 addresses starting from 0x0804a280 (because it is hexadecimal)
insert image description here

Look at the lower four bits of a to z in the ASCII code table, corresponding to the above. At this time, it is relatively easier to piece together, and it is 0x45=0xe+5*0xb. That is the corresponding jllllll.
Verification: Enter jllllll in the Linux terminal, and press Enter to display "Good work! On to the next...", the fifth pass is successfully passed.
insert image description here

The sixth level: find phase_6, its assembly code is as follows:
insert image description here
insert image description here
insert image description here

The following is the analysis of the assembly code:
first of all, it is still a quick glance to find out the purpose of this level, call 80491dc <read_six_numbers> indicates that this level needs to input six numbers again. Followed by a slightly complicated cycle, the first key part of the cycle is sub $0x1, %eax, cmp $0x5, %eax and jbe 8048e9c <phase_6+0x2f>, that is, each number must be less than or equal to 6. The statement in the second key part is a nested loop, mov 0x10(%esp,%ebx,4),%eax, cmp %eax,0xc(%esp,%esi,4), the meaning of this part It means that the number behind the current number in each cycle cannot be equal to it. In one sentence, the six numbers are not equal to each other and are less than or equal to 6. After judging that
each number is not equal to each other, it then jumps to the address 0x8048ee3. The code is too complicated, and when I solve the problem, I rely on guesswork. When analyzing mov $0x804c13c,%edx, it is found that there is another immediate value. Based on the principle that no immediate value can be missed in the bomb experiment, open the terminal and try to enter "x/s 0x804c13c" to view the content in string format. But the content of the output is very strange, and try "x/50w 0x804c13c" to print out the 50 sentences starting from the address 0x804c13c, but the content of the output is still incomprehensible, so I refer to the information and find that the address here is a pointer to a linked list. So try to enter "p/x *0x0804c13c@32" to view the list content, the result is as shown in the figure below:
insert image description here

A group of three numbers, the first number is a weight, the second number is sorted by 123456, and the third number is the first address of the next node. I only understand a part of the code in the middle, cmp %eax,(%ebx), jge 8048f32 <phase_6+0xc5>, there are a lot of comparison and movement data in this part of the code, it is speculated that it may be sorting, according to the specific sorting, I also guessed that it might be sorted by weight, and the answer obtained by sorting by weight in this list is: 6 2 5 3 4 1 Verification:
Enter 6 2 5 3 4 1 in the terminal, and press Enter to display "Congratulations! You 've defused the bomb!" The sixth level was successfully passed. The bomb was successfully defused!

insert image description here

Hidden level:
Since phase_defused has never appeared in the previous level, it is speculated that it may be related to the hidden level. Let’s analyze it below: The following
is the assembly code:
insert image description here

According to the above experience, check the value of all immediate values, you can get:
insert image description here

This shows that the parameter must have two integers and a string
insert image description here

There is a function for judging the equality of strings. Checking the content of the address shows that you need to enter DrEvil after the fourth level to start hiding the level.
insert image description here

Secret_phase assembly analysis:
insert image description here

The function fun7 is analyzed below, the return value of fun7 should be 3, check the assembly code of fun7;
convert it to c++ code,
insert image description here

This function will be used to query a binary tree. The address initially passed into the function is the address of the root node. The specific return value is as written in the code. When the value of the current node is equal to the query operation , return 0, otherwise judge whether to continue to query the left subtree or the right subtree according to the size of the value.
A binary tree is stored as follows:
insert image description here

To think about getting 3, the method is 2*(0*2+1)+1, that is, the traversal order of the binary tree is right-right. According to this, you should input 0x6b, which is 107 in decimal.
Verification: Enter 107, display "Wow, you 've defused the secret stage!"

So far, all bombs have been successfully disarmed!
insert image description here

Guess you like

Origin blog.csdn.net/weixin_51295681/article/details/124236582