From mboxrd@z Thu Jan 1 00:00:00 1970 From: osalvador.vilardaga@gmail.com (Oscar Salvador) Date: Wed, 7 Sep 2016 17:38:59 +0200 Subject: check if a kernel page is read-only In-Reply-To: References: <11599.1473094678@turing-police.cc.vt.edu> <43701.1473191229@turing-police.cc.vt.edu> Message-ID: To: kernelnewbies@lists.kernelnewbies.org List-Id: kernelnewbies.lists.kernelnewbies.org 2016-09-07 15:47 GMT+02:00 Oscar Salvador : > > > 2016-09-06 21:47 GMT+02:00 : > >> On Tue, 06 Sep 2016 13:23:48 +0200, Oscar Salvador said: >> > I guess I explained it wrong. I'm not writing neither a rootkit nor a >> > module which is messing with kernel memory. I'm writing a module to be >> able >> > to r/w kernel/ user linear memory. It's for a forensic tool. >> >> And this, my friends, is an example of why things like this are *really* >> difficult to do correctly. >> >> There are very good reasons why (a) CONFIG_PROC_KCORE exists at all, and >> (b) >> why it only provides a read interface, not writing. >> >> If the module is "to be able to r/w kernel/user lineal memory", it's only >> a matter of semantics away from "messing with kernel memory". >> >> There's a *long* history of miscreants abusing security/forensic tools >> (which >> often run with extended privs) to pwn a system. For example, there's been >> multiple holes found in wireshark, where a bugger overflow in one of the >> protocol dissectors allows the attacker to send a hand-crafted packet >> which >> takes over the wireshark process, and hilarity ensues.... >> >> If you don't believe me... >> >> [~/src/metasploit] find . -name '*wires*' >> ./modules/exploits/multi/misc/wireshark_lwres_getaddrbyname_loop.rb >> ./modules/exploits/multi/misc/wireshark_lwres_getaddrbyname.rb >> ./modules/exploits/windows/misc/wireshark_lua.rb >> ./modules/exploits/windows/misc/wireshark_packet_dect.rb >> ./modules/exploits/windows/fileformat/wireshark_packet_dect.rb >> ./modules/exploits/windows/fileformat/wireshark_mpeg_overflow.rb >> ./modules/auxiliary/dos/wireshark >> >> So what *secure* way are you using for your kernel module to tell that a >> request came from your forensic tool, and not from malware code that's >> been >> injected into the forensic tool? (Hint - checking the return address of >> the >> syscall isn't secure, because (a) it will move around every time the >> binary is >> rebuilt for new releases, and more importantly (b) the syscall is almost >> certainly in a function called "probe_memory()" or similar that is called >> from >> all over the place, and can't protect against a subverted call. >> >> You can't even have probe_memory() use __builtin_return_address(0) to >> check >> where it was called from, because the attacker can set up a properly >> crafted >> stack, patch the instruction following the call to branch back to malware, >> and then branch directly to the instruction that does the call.... >> >> (And yes, having the check done in userspace is broken no matter *how* >> you do it, because it's trusting a check that's potentially subverted by >> the attacker) >> > > You are right regarding security stuff, but was not my will either > bypassing memory protections or crashing the system. > I wanted to write a module to read from a kernel address or from a virtual > address space from a certain pid, and write too, but just to those pages > that can be written. (and even if it's a topical it helped me to > understand how the memory subsystem is working, since this was one of the > motivations) > > But I get your point, thanks for that. > > Nevertheless, I have another question: > > > - I write a user program which allocates a buffer, then writes something > to it and calls a my module via read/write > - The driver tries to get the user page of the buffer's address with > "get_user_pages", then tries to kmap this page and prints the content of > the returned addr of kmap, so I can read what the userspace was put into > that buffer. (let's say a "hello!" string) > > This only works if the buffer allocated from userspace was allocated with > some kind of mem_align (like posix_memalign with posix_memalign(&pointer, > 4096, 4096)), but not without it. > I guess it's because posix_memalign reserves a whole page for that buffer, > then the addr that kmap is giving to you points at the beginning, but > without the mem_align stuff, I guess the content of the buffer is just in > the "middle" of the page. > > is that right? > > thanks > > > I found a way by getting the beginning of the vma and then read from the offset generated from (my_address - beginning) > >> So given all this, why are you bothering with a kernel module which >> re-invents >> the wheel already done for you in the /proc/kcore support? :) >> >> _______________________________________________ >> Kernelnewbies mailing list >> Kernelnewbies at kernelnewbies.org >> https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20160907/71c5f2a0/attachment.html