First update the first experiment about the stack of analysis, here I directly handwritten pictures.
Add here that the 5th step of call F is actually equal to PUSHL%EIP,MOVL F%eip, that is, the EIP address of F is stacked, the call G principle is the same. Leave equals MOVL%ebp,%esp,popl%ebp that is, the EBP out of the stack, EPB point to the stack of their stored values, and then pay the value of EBP to ESP, to achieve the release of the stack.
Next is the experiment:
September 24, 2014, Bash found a serious vulnerability shellshock, which can be used on many systems and can be triggered either remotely or locally.
What is Shellshock:shellshock, also known as Bashdoor, is a security vulnerability in a widely used bash shell in Unix that was first disclosed on September 24, 2014. Many Internet daemons, such as Web servers, use Bash to handle certain commands, allowing an attacker to execute arbitrary code on a vulnerable bash version. This could allow an attacker to access the computer system without authorization.
Experiment Preparation:
Install version 4.1 bash with root privileges
Download:
# wget http://labfile.oss.aliyuncs.com/bash-4.1.tar.gz
Installation:
# Tar XF bash-4.1.tar.gz# cd bash-4.1#./configure# Make & make Install
Link:
# rm/bin/bash# Ln-s/usr/local/bin/bash/bin/bash
Detect the presence of a Shellshock vulnerability:
$ env x= ' () {:;}; echo vulnerable ' bash-c "echo this is a test"
Here are the experiments:
Problems and Solutions:
When the first experiment was careless, there was no problem with Sudo having insufficient authority.
After resolving the new problem, when executing bash-version, the following prompt message appears:
Follow the prompts to execute sudo apt-get install bash after the following error occurs:
Internet Baidu a bit, is dpkg mistake, tried several methods on the net, failed to solve successfully. The experimental environment was then returned to the experimental building.
Attack Set-uid Program:
$ sudo ln-sf/bin/bash/bin/sh
Compile the code below and set it to the SET-UID program to ensure that its owner is root. We know that the system () function will call "/bin/sh-c" to run the specified command, which also means that/bin/bash will be called
#include <stdio.h>void main () { setuid (Geteuid ());//make real UID = effective UID. System ("/bin/ls-l");}
If the setuid (Geteuid ()) statement is removed, try the attack again and it will not succeed.
void Initialize_shell_variables () {//loops through all environment variables for (string_index = 0; string = env[string_index++];) { /*...*//* If there is an export function, define * //* Cannot import functions defined in privileged mode (root) */if (Privmode = = 0 && read_but_ Dont_execute = = 0 && streqn ("() {", String, 4)) { [...] Here is where Shellshock happened //Transfer function definition + run additional instruction Parse_and_execute (temp_string, name, seval_nonint| Seval_nohist); [...]} }
This is the same line of judgment logic led to the difference between the two, Primode is the private mode, requires the real UID and effective UID consistency.
This is basically the end of the experiment.
Summary of the contents of the book:
Linux device includes three kinds, block device, character device, network equipment, the 17th chapter mainly discusses kernel function black chicken device drive implementation and device tree management, including modules, Kobject and SYSFS.
Portability of Linux:
1. Bytes and data types
The data that can be processed once by the machine is called the number of words, digits. So we often hear how many bits of the machine, that is, the length of the machine. The size of the processor's universal register is the same as its word length. The long type defined by the C language equals the machine word length. For each of the supported architectures, Linux defines the Bits_per_long in <asm/types.h> as the length of the C long type, which is the word size of the system. Opaque types are those that are declared by Typeder. In addition, we often need to use a well-defined type in the program, and the kernel defines these well-defined types in Asm/types.h, and the file is included in the file Linux/types.h, as shown in the following table:
There are less symbolic variables. Next is the char type: Divided into signed ( -128~127) and unsigned (0~255).
2. Data alignment
If the memory address of a variable is exactly the integer multiple of its length, it is called natural alignment. The content of the byte alignment is still quite tedious, I'm not going to talk about it here, I will have a special topic for this question.
3. Byte order
Byte order refers to the order of the individual bytes in a word. The processor can take the byte that is the least significant bit as the first byte (the leftmost byte) or as the last byte (the rightmost byte) when the word is evaluated. If the byte with the most significant bit is placed at the highest byte position, and the other bytes are placed in the low byte position, then the byte order is called high priority (Big-endian) [store left big right small], otherwise it is called little-endian[left small and large]. Give an example directly, as follows:
00000000 00000000 00000100 00000011
The following is how the above data is arranged in two different byte-order types:
Although not used to, it is true that high-priority architectures are used to store the highest byte bits on the smallest memory address. The code below can determine the given machine byte alignment type:
int x = 1;if (* (char *) &x = = 1)/ * Little endian */else/* big endian */
In each architecture supported by the Linux kernel, the corresponding kernel defines one of the __big_endian or __littile_endian in its asm/byteorder.h based on the byte order used by the machine. , this header file also contains a set of macro commands to complete the conversion of byte order from Include/linux/byteo Rd er, the most commonly used Macro command is as follows:
U23 __cpu_to_be32 (u32); /* Convert CPU ' s byte order to Big-endian */u32 __cpu_to_le32 (u32); /* Convert CPU ' s byte order to Little-endian */u32 __be32_to_cpu (u32); /* Convert Big-endian to CPU ' s byte order */u32 __le32_to_cpus (u32); /* Convert Little-endian to CPU ' s byte order */
4. Time
For kernel time issues, never assume that the frequency at which the clock interrupts occur, that is, the number of jiffies produced per second. Instead, you should use Hz to correctly measure time.
5. Page length
When working with page-managed memory, never assume the length of the page. Different architectures use pages that are not the same length. When working with page organization-managed memory, the page length expressed in bytes is used by Page_size, and the value of Page_shift defines how many bits are masked from the far right to get the page number of the page that corresponds to that address.
In summary, there are a number of issues to consider when writing portable code: Word length, data type, alignment, byte order, page size, processor sequencing, and so on.
20169217 "Linux kernel Fundamentals and analysis" 11th Week work