当前位置:网站首页>HUST network attack and defense practice | 6_ IOT device firmware security experiment | Experiment 3 freertos-mpu protection bypass

HUST network attack and defense practice | 6_ IOT device firmware security experiment | Experiment 3 freertos-mpu protection bypass

2022-06-26 11:28:00 shandianchengzi

Write at the top : must do First the task3.sct The file is linked to the project , The specific operation is described below , And I explained in the attachment sct The meaning of the document .

Finally, I can say goodbye to this practice . You can add one sentence to your experience “ A large number of tasks , It is recommended to reduce the number of tasks ” Do you ?

Experiment three FreeRTOS-MPU Protection bypasses

The experimental requirements

MPU Preset :

 Insert picture description here

a) To write C The code implementation is based on FreeRTOS-MPU v10.4 Code and specified function search
b) Exploit the overflow vulnerability to realize in FreeRTOS MPU V10.4 Version of the system and Flag Function print

The subtasks 1

First , Similar to the previous experiment , Also take a look .c File structure .

main function :
① Define unsigned integer variables id, The assignment is at the end of the student ID 4 position ;
② call prvSetupHardware(), Hardware initialization ;
③ call StartFreeRTOS(id, vTask3);
④ Use for(;;) Let the program not exit .

vTask3 The content of , Only for(;;).

Header files and lib The function of the file is similar to that of the previous experiment .

therefore , All task requirements are focused on StartFreeRTOS In the , We need to do further reverse analysis .

Reverse analysis StartFreeRTOS

IDA Pro Open and decompile StartFreeRTOS as follows :

 Insert picture description here

You can see , This function has the following operations :

① take byte_7714 The content pointed to by the address of is copied to the task parameter xTask3Parameters;
② Set task parameters xTask3Parameters The function pointer of is vTask3;
③ val *= id;
④ call xTaskCreateRetricted, Combined with task parameters xTask3Parameters Create constrained tasks ;
⑤ call vTaskStartScheduler() Start the task sequence .

What we have to do is vTask3 Call the weight raising function in , Then call print flag Function of .

Print flag The function of is easy to find , Directly in IDA Pro String window on the line , Double click to open it , Then look at the references :

 Insert picture description here

In a word, we can find a man named vTaskRemove Function of , It is a parameterless function , Able to print flag.

Find the weight function , I didn't know how to find it at first .
Until I read the explanation of the experiment PPT, See the following picture :
 Insert picture description here

so , If ordinary tasks use the kernel API, Can't be used directly , Instead, add MPU_, Add this function , It includes the operation of raising rights . and , The right raising operation should use SVC interrupt .

therefore , We might as well IDA Pro Open any one in the MPU_ Reverse analysis of the function of , Find the right raising operation . I take MPU_vTaskDelete For example .IDA Pro The analysis is as follows :

 Insert picture description here

In the above figure, I frame the operation of raising rights . You can see , First, you do some stack pressing operations to enter the function , And then put forward the right Task Pass in R4, If R4 Not for 0 Just jump to the weighted function ( If 0 So it is a privilege level ). And then perform the routine xTaskDelete This kernel API.

Obviously , The weighting function is xPortRaisePrivilege, And using registers R4 The ginseng , So it's also a function with no parameters .

Don't rush to fill in the address , Because the address is being modified vTask3 The content will change later . Pretend to have found the address , And in vTask3 Call these functions with addresses in , such , After finding it, you just need to change it to the corresponding address . Add the following code :

Be careful , The address filled in casually shall not be all zeros 、 Must not be the same , It's better to fill it in like a little , Otherwise, after the second revision , The address will change again .

void (*pPrivilege)();
void (*pFunc)();
pPrivilege=(void(*)())0x00001051;
pFunc=(void(*)())0x000029AD;
pPrivilege();
pFunc();

Rebuild after , Go to IDA Pro Find function address in . When calling a function with an address , You need to add one .

It should be noted that , When the function address has been added correctly , but log.txt Zhongchalian vTask3 When there's no time , It is likely that there is something wrong with the configuration of the project , Such as memory address distribution , Something is wrong log.txt as follows :

 Insert picture description here

At this time, you must import the task3.srt, The import method is as follows :

 Insert picture description here

After import , Rebuild project , And reverse analyze the address .( I cut the image again after importing )

sct See the additional contents below for specific functions 1.

Print Flag Function name and address

name :vTaskRemove;
Address :0x000005F4.

The content is shown in the figure below :

 Insert picture description here

The name and address of the function used to raise the right

name :xPortRaisePrivilege;
Address :0x00008EDC.

The content is shown in the figure below :

 Insert picture description here

Filled in code

Be careful , You need to add... To the address found above 1 Then call . The code filled in is shown in the figure below :

 Insert picture description here

Screenshot of simulation operation

Run and print flag The results are as follows :

 Insert picture description here

log.txt as follows :

 Insert picture description here

The reason why log.txt Also take a screenshot , It's because in the previous analysis , You can see xPortRaisePrivilege The task of function weighting is R4 register , We simply call this function , Not right R4 Register processing . But it also succeeded .
see log.txt Will find , There is no obvious right R4 Contents of register processing , The last assignment was prvSVCHandler Of pop. I guess it's possible to just execute svc 2 Right withdrawal upon interruption , The details are not yet clear , But it has no effect on this experiment .

Later, I wrote flag5 When reporting , Realize that when R4 by 0 when , It should be this task that raises the right ; perhaps , Regardless of R4 The value of , Will be entitled to this task .

Additional content 1:sct Role of documents

On the left of the picture is the teacher's message sct file , The right side of the figure below is generated automatically by the software sct file .

 Insert picture description here

sct File is the memory mapped layout file .
General situation , When compiling , Just let all the functions ( As shown in the figure above .ANY (+R0)) Sort by function name and put it in memory , There is no access control for privileged access or user access .
After we set up MPU after , Compilation will not be affected . therefore , Nonprivileged functions may be put into our own MPU The area of the privileged function in , The non privileged function is stored in the address range of the privileged function ,MPU Will not be allowed to execute .

And the teacher revised sct file , Yes API The position of , Put the privilege function privileged_functions In the first paragraph ( Namely MPU Where only privilege execution is allowed in the ER_IROM1), Put the others in ER_IROM2. And put the privileged data privileged_data Put it in MPU Only privileged read / write segments are allowed in the RW_IRAM1, Put the others in RW_IRAM2.

such , Will make the memory map and MPU The settings are consistent .

The subtasks 2

Reverse analysis StartFreeRTOS

The reverse analysis function address of this task is similar to that of the previous task , I won't go into details here .

Print Flag Function name and address

name :vTaskDelayBackup;
Address :0x00001C7C.

The contents are as follows :

 Insert picture description here

The name and address of the function used to raise the right

name :xPortRaisePrivilege;
Address :0x000086E2.

The contents are as follows :

 Insert picture description here

The analysis process

Of the document main Function is too long , But it's simple , As shown in the figure below :

 Insert picture description here

For the time being, I can only see , Last input string InputBuffer Maximum length 0x63.

Just a little more StartFreeRTOS:

 Insert picture description here

Just run the constrained vTask3 Mission , Nothing else .

Because this is passed in by the parameter , You can't open it directly , So go back to the previous level first , Then I'll turn it on vTask3 Mission :

 Insert picture description here

vTask3 Called Function(), Based on experience , This is the code that went wrong .

Find the buffer that exists in the overflow

It opens at Function

 Insert picture description here

I found that Function Parameter passed in , What is more important is that length and InputBuffer, And assigned to HelperBuffer, also HelperBuffer The size of 12, explain HelperBuffer It may be an overflow buffer .

Display in assembly form Function Function as follows :

 Insert picture description here

Yes PUSH and POP The explanation of :ARM The architecture stack is a decreasing stack ,PUSH From right to left ,POP From left to right .

After viewing the assembly , You will find that strictly speaking , There is no overflow buffer at all .Function function , It starts with push 了 4 A register , Then use at the beginning of the function mov buffer, sp, Change the stack top pointer directly sp, Then immediately use InputBuffer Fill in the contents of one by one buffer( In my IDA The variable name is resolved to HelpBuffer). Last pop When ,pop The content is not HelpBuffer[0]HelpBuffer[1]HelpBuffer[2] Wait ?
Override the value of the register , Namely Function Purpose , It's also set up buffer The role of , It just wants to write on the stack 、 Write... To the register .
since , Each bit of the buffer , The purpose is to write data to registers or stacks that should not be written , It has nothing to do with normal function . It's like drawing on a piece of paper , Normal operation is drawn on paper , But too much paint spills over the table , This piece of paper is called an overflow buffer ; And this code doesn't even have paper .

Sum up , I don't think this is a typical buffer overflow code . If you have to say that there is an overflow buffer , That's the one deliberately constructed HelpBuffer, and The length of the overflow buffer is 0, No normal function .

Stack diagram

It opens at Function Of bp, You can see IDA Pro Stack frame in .

 Insert picture description here

however , This doesn't explain the stack very well . I redrawn the stack diagram .

When executed mov buffer, sp The diagram of the front and back stack is as follows :

 Insert picture description here

LR(Function) It needs to be covered as a weight lifting function , After calling the weight raising function , You also need to call print flag Function of , Therefore, it is necessary to construct the stack structure of the return address of the overflow call . The fully constructed stack is shown in the following “ Spillover claims ” Will draw .

Spillover claims

Overflow right raising call xPortRaisePrivilege, The address is 0x000086E2. The first line of the function is PUSH {xRunningPrivileged,LR}. If you execute this sentence , It will change the stack frame structure we have already constructed , Also, the return address cannot be overwritten , So we need to skip this sentence , From address 0x000086E4 Start . Plus the base address is 1, therefore LR(Function) Need to be covered with 0x000086E5.

After successfully entering and executing the weight lifting function , Continue printing flag Function of . On return, execute POP {xRunningPrivileged,LR} Therefore, it is necessary to construct 8 individual HelpBuffer byte , The complete stack diagram is as follows :

 Insert picture description here

Override the return address resolution process

stay Function The return value in is overwritten with xPortRaisePrivilege Add... To the address in the second line 1, namely 0x000086E5, So it will return from xPortRaisePrivilege The second line of code starts execution , And complete the right raising ;

stay xPortRaisePrivilege The return value in is overwritten with vTaskDelayBackup Address to add 1, namely 0x00001C7C, So it will return from vTaskDelayBackup The first line of code executes , And finish flag Print .

Screenshot of simulation operation

 Insert picture description here

End of the flower !!!

原网站

版权声明
本文为[shandianchengzi]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/177/202206261040305231.html