In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly introduces the Linux kernel intrusion process address space and modify the process memory example analysis, the article is very detailed, has a certain reference value, interested friends must read!
Isolation of process address space is a prominent feature of modern operating systems. This is also a distinguishing feature from "ancient" operating systems.
Process address space isolation means that process P1 cannot access process P2's memory in any arbitrary manner unless the memory is declared shared.
It's easy to understand, let me give you an example.
We know that in primitive savage societies, there is no concept of family, all resources are shared within the tribe, and all savages can interact with any other savages in any way at any time. This is true of operating systems such as DOS, where memory address space is not segregated. Processes can access other processes 'memory at will.
Then came the idea of the family, and the resources of the family were segregated, and people could not break into people's homes, and people could not enter other people's homes and things in a random way, unless this was allowed by the owner. When the operating system enters modern mode, processes also have a family-like concept.
But the concept of family is virtual, people just keep the agreement and do not break other people's families. The house serves as a physical infrastructure that protects the family. In an operating system, a home is similar to a virtual address space, and a house is a page table.
Neighbors can't break into your house, but police can, and so can government officials with good reason. The so-called privileged management agencies can enter ordinary people's houses and touch their things as long as they have good reasons. For operating systems, this is what the kernel can do, and the kernel can access the address space of any process.
Of course, the Core doesn't break into people's homes for no reason, any more than the police break into people's homes.
But you can get the kernel to do it on purpose, to do something rogue.
Let's try it out. Let's look at a program first:
// test.c// gcc test.c -o test#include #include #include #include #include int main(){ char* addr = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); strcpy(addr, "Zhejiang wenzhou pixie shi"); printf("addr: %lu pid:%d\n", addr, getpid()); printf("before:%s \n", addr); getchar(); printf("after:%s\n", addr); return 0;}
The output of this program is very simple, before and after will output "Zhejiang wenzhou pixie shi", but we want to change this sentence, how to do it? Obviously, if the test process does not change it, then there is nothing to do…but you can force the kernel to change it, and let the kernel break into the house.
Next I write a kernel module:
// test.c// make -C /lib/modules/`uname -r`/build SUBDIRS=`pwd` modules#include #include static int pid = 1;module_param(pid, int, 0644);static unsigned long addr = 0;module_param(addr, long, 0644);//Find a process's page table based on its virtual address, which is equivalent to finding the family's house address and breaking in! static pte_t* get_pte(struct task_struct *task, unsigned long address){ pgd_t* pgd; pud_t* pud; pmd_t* pmd; pte_t* pte; struct mm_struct *mm = task->mm; pgd = pgd_offset(mm, address); if(pgd_none(*pgd) || pgd_bad(*pgd)) return NULL; pud = pud_offset(pgd, address); if(pud_none(*pud) || pud_bad(*pud)) return NULL; pmd = pmd_offset(pud, address); if(pmd_none(*pmd) ||pmd_bad(*pmd)) return NULL; pte = pte_offset_kernel(pmd, address); if(pte_none(*pte)) return NULL; return pte;}static int test_init(void){ struct task_struct *task; pte_t* pte; struct page* page; //Find this family task = pid_task(find_pid_ns(pid, &init_pid_ns), PIDTYPE_PID); //Find where this family lives if(! (pte= get_pte(task, addr))) return -1; page = pte_page(*pte); //barge-in addr = page_address(page); //sdajgdoiewgikwnsviwgvwgvw strcpy(addr, (char *)"rain flooding water will not get fat!" "); //something to brush clothes away, hidden power and name return 0;}static void test_exit(void){}module_init(test_init);module_exit(test_exit);MODULE_LICENSE("GPL");
Come on, let's try it:
[root@10 page_replace]# ./ testaddr: 140338535763968 pid:9912before:Zhejiang wenzhou pixie shi
At this point, we load the kernel module test.ko
[root@10 test]# insmod test.ko pid=9912 addr=140338535763968[root@10 test]#
Enter Enter in the test process:
[root@10 page_replace]# ./ testaddr: 140338535763968 pid:9912before:Zhejiang wenzhou pixie shiafter:rain flooding water will not get fat! [root@10 page_replace]#
Obviously,"Zhejiang Wenzhou shoes wet" has been changed to "rain water will not fat."
Take a closer look at the get_pte function of the kernel module above. To write this function correctly, you must have some knowledge of the MMU of the machine on which you want to destroy the process, such as whether it is a 32-bit system or a 64-bit system, a level 3 page table, a level 4 page table or a level 5 page table. This...
The playability of Linux is that you can do it yourself, and you can have someone do it for you. For example, get a virtual address of a process page table entry indicates the physical page, you can get directly.
Is there such an API? Yes, don't forget that everything is a file. It happens that in the proc file system, there is such a file:
/proc/$pid/pagemap
Read this file and get the page table entry of the process virtual address. The following figure is taken from the kernel Doc:
Documentation/vm/pagemap.txt
Virtual address space is per-process, while physical address space is shared by all processes. In other words, physical addresses are global.
Now, according to the interpretation of Document/vm/pagemap.txt, write a program to get the global physical address of any virtual address of any process:
// getphys.c// gcc getphys -o getphys#include #include #include int main(int argc, char **argv){ int fd; int pid; unsigned long pte; unsigned long addr; unsigned long phy_addr; char procbuf[64] = {0}; pid = atoi(argv[1]); addr = atol(argv[2]); sprintf(procbuf, "/proc/%d/pagemap", pid); fd = open(procbuf, O_RDONLY); size_t offset = (addr/4096) * sizeof(unsigned long); lseek(fd, offset, SEEK_SET); read(fd, &pte, sizeof(unsigned long)); phy_addr = (pte & ((((unsigned long)1)
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.