Don't wanna be here? Send us removal request.
Text
Something Awesome Report
Report for my project
My chosen project was to make a rootkit for the Linux kernel. I chose this because it is a very modular project- there’s always another feature I could work on when I finished something. The objective of the project was to expand my operating systems knowledge through the eyes of an attacker and consider what one might do with access to a system’s kernel.
The project is up on github at https://github.com/seb-sec/trivial-rootkit/
The milestones I set at the start were quite vague because I didn’t particularly know what I should be doing or how feasible any of the tasks were. It also required some revising as I further expanded my understanding. The original milestones were to implement a Linux kernel module, have capabilities to raise the privileges of a process, have the rootkit able to hide itself, other files and processes, implement some sort of persistence and some log modification capabilities. However as it went on I found the need for log modification was minimal, and decided to replace this with more thoughtful stealth in the form of inline function hooking.
I managed to accomplish most of my milestones to a good degree, except for persistence and the more advanced stealth. I implemented a basic form of persistence and blogged about how I would handle a more thought out, stealthy form of persistence here. I didn’t get around to implementing inline function hooking capabilities but I did write about how it worked here.
The implementation of each milestone was documented in a blog post
Kernel module
https://seb-sec.tumblr.com/post/185603839144/project-simple-kernel-module
https://seb-sec.tumblr.com/post/185632234179/project-character-device
Privilege escalation
https://seb-sec.tumblr.com/post/185700538344/project-process-privilege-updating
Stealth- rootkit, files and processes
https://seb-sec.tumblr.com/post/185905269004/project-stealth-pt1
https://seb-sec.tumblr.com/post/185954316594/project-stealth-pt2-electric-boogaloo
https://seb-sec.tumblr.com/post/186276992714/project-process-hiding
Unimplented milestones-
Persistence- https://seb-sec.tumblr.com/post/186461666614/project-persistence-writeup
Inline function hooking- https://seb-sec.tumblr.com/post/186462541949/project-more-advanced-syscall-hooking-writeup
This was a fun project which really expanded my understanding of rootkit capabilities and implementation.
1 note
·
View note
Text
Comp6441 ctf
In a desperate attempt to scavenge more marks I’m participating in the 6441 ctf thats currently being hosted, and I’ve made some decent progress.
My account name is ‘#jazzsoc 2- except its just seb’, and I’ve managed to solve all of the challenges in the binary category which I was quite happy with. I’ve also manage to solve ‘vinegar’ in the crypto category and ‘guess’ in misc (what a pain) for now. I would go through my solutions for the challenges but I wouldn’t want to spoil them for anyone else!!
My current goal is to learn heap exploitation and do ‘trivial’ which should be horrendous fun, wish me luck
5 notes
·
View notes
Text
Google yourself activity
I downloaded my facebook and google information and oh boy is there a lot of it, particularly on facebook. If someone datamined my information they would probably impersonate me better than I could. Just look at what they determined my ad interests to be:
Terrifying.
With the amount of data they have on my comments. search history, event participation and the like, building up a profile of who I am is trivial, and I assume this data is auctioned off to the lowest bidder.
Luckily for me google didn’t seem to have any data on my location history, but that wouldn’t be of much use to anyone considering I never leave my house.
This activity has definitely made me more aware that literally every move I make is being noted and sold, but hey I dig the attention
1 note
·
View note
Text
Project video
https://vimeo.com/349456637
password is:
~~~~~~~~~~~password
audio sucks ✔
giant watermark ✔
over 2 minutes ✔
must be a great something awesome video
1 note
·
View note
Text
Project: More advanced syscall hooking writeup
Currently we can hook syscalls by replacing their entries in the syscall table with our own, but it becomes very obvious that there’s malicious activity as soon as anyone looks at values in the table. What if we could keep the original pointers to the syscalls, but still use our versions- turns out we can by using inline function hooking instead:
There’s nothing really special at a given syscall’s address- just instructions. What if we replaced the first few instructions with a jump to our own syscall implementation? When a syscall is made, we go to the system call table- which has the pointer to the original syscall as you would expect- but it instead executes a jump to our function. Sneaky!
There’s a problem though: Often we want to call the regular syscall and then modify some return values, which isn’t possible with our current implementation. Instead we can be even more sneaky: We can save the first few instructions of the original syscall and then replace them with the jump. We can then append to the saved instructions a jump to the original syscall, as well as saving where to return to. The jump will be offset after the inserted jump to our own function.
In this way we build a trampoline to seamlessly call the original syscall if required. We would have to be careful calculating the amount of bytes to copy from the original syscall as we could break an instruction in half, leading to a crash.
I cracked open paint to illustrate my point
graphic design is my passion
This is how you would retain a syscall hook with the original, non-suspicious function pointer in the syscall table.
2 notes
·
View notes
Text
Project: Persistence writeup
Since I don’t have time to fully implement the last few features I wanted to, I will instead discuss what I wanted to do and some ideas about how I would go about doing it.
First off is rootkit persistence. Currently the rootkit is wiped on reboot- but is that really such a bad thing? If it was installed on some server for example, this wouldn’t be too much of an issue since servers are rarely restarted. However, there are probably cases where persistence is handy.
If we run man modules, we are given that the file /etc/modules lists the modules to be automatically loaded at boot time. Sounds handy. If we append our module name there, then stick the module .ko file somewhere in /lib/modules/{version}/ we should be good to go. We also run sudo depmod -a to properly integrate our module (this does a few things such as generating instructions to make a device file for the module- see man depmod for more info). After rebooting:
That wasn’t too bad, but we left traces everywhere. My /etc/modules file was empty before adding the reference to the module, so it sticks out like a sore thumb. Additionally, the changes depmod made to the module files in /lib/modules/{version}/ also aren’t good for us.
If we could hook into the shutdown/restart procedure we could probably do some sneaky maneuvers to get around the traces we are leaving. Luckily there’s a syscall designed to do just that- reboot, which is called on any shutdown/restart attempts. We already know how to hook syscalls, so that part would be trivial.
Inside the hooked reboot call we would first append the module name to the /etc/modules file, then insert the .ko module file into the appropriate place in /lib/modules/{version}/. We could then execute the depmod command to build the dependencies with our kernel object file and afterwards call the regular reboot syscall as normal. Upon restart, the module initialisation function would have to reverse our steps, removing traces of the rootkit- including running depmod again without the .ko present to remove any mention of us from the module dependency files.
How could we hide the .ko file between reboots? We could just allocate a bunch of memory in the kernel and copy the contents of the file over, keeping the pointer to reconstruct the file from later. Persistence achieved (theoretically)
However there are drawbacks to this. If the system wasn’t restarted, and instead the disk was run through some sort of forensics software, the traces of the rootkit could be spotted which is bad news. Probably better to wipe on a restart than be detected.
2 notes
·
View notes
Text
Weekly plan: 22-27th July
Last week was not pleasant in terms of workload so I couldn’t do much in terms of course activity. Time to catch up this week in hopes of scraping a few more marks
Mon: Project writeups for unimplemented features
Tue: Project video, case prereading
Wed:Case review
Thurs: Weekly review, activities
Fri: activities
Sat:Job application
0 notes
Text
Secsoc ctf review
I participated in the secsoc ctf under the team #jazzsoc, and we managed to get first place. I got completely carried, but it was a fun experience nonetheless.
One of the first flags I got was a simple cipher that I just chucked into an online decoder to get the flag- trivial.
The other one I got was for one of the reversing ones where you had to input 4 numbers that satisfied some internal calculations. I wasn’t a big fan, so I patched out all the correctness checks for the calculations with binary ninja. It appeared like the inputs I was putting in was changing the output (it would probably have given me the flag at this point if I actually did the maths part). After looking at it a bit more, it turned out that each input number was shifting a corresponding character in the output by the value of the number, so after a bit of fiddling I got the correct values to output the flag- trivial.
I was banging my head against some of the forensics challenges involving pdfs and images for quite a while with not much luck. I’m hoping the forensics course next term helps me out for next time.
That was the general trend of the ctf event- there were many things I don’t have a clue about, but I hope to develop those skills eventually along my sec journey.
5 notes
·
View notes
Text
Lightning talk: Syscall hooking
I did a lightning talk on hooking system calls in kernel space- something a rootkit might be interested in doing. Function hooking refers to intercepting a function call to instead go to your own custom version of it.
To start you need to find where the syscall table is- its symbol is not exported on modern kernels, so you can’t just find it... unless of course, you can. System call symbols such are sys_read are exported. This means we can simply brute force search through every address in kernel memory, offset by the position of sys_read in the table, and if we find a matching address for the sys_read function pointer we also get the address of the table.
So we have the table address, but unfortunately it is write-protected so we couldn’t possibly modify it... unless we can. There’s a control register, CR0 which has a specific bit that controls write-protection. There’s also a convenient function in the kernel to change the value of this register.
So we have the address of the syscall table and now can write to it. We simply place the pointer to our replacement function in place of the original and we’re in. Often we will want to use the original syscall and then modify some return values, so it’s a good idea to save a pointer to the original function.
3 notes
·
View notes
Text
Case prereading: Privacy
Some level of government surveillance is probably necessary to have a well functioning society, but how much is too much? Plans for facial recognition replacing opal cards and used to identify potential criminals, metadata retention laws and the like start seeming very dystopian.
Even if the government and law enforcement are entirely benevolent entities who truly respect their populace and wouldn’t misuse any of their power (lol), I still wouldn’t think increased surveillance systems are a good idea. What happens if the benevolence doesn’t last forever, or we develop into a dictatorship one day? These systems will still exists, and they can then be abused to target specific groups or otherwise oppress the populace. People may trust the current government to do the right thing (lol) but the future makes no such guarantees, so we need to be careful about how systems like this could be abused.
0 notes
Text
Weekly plan 15th - 20th July
Another week with assignments from all my courses due at the end of it, wooo.
This is the ideal (if unlikely) plan for this week
Mon: Project
Tue: Case prereading
Wed: Case review
Thur: Project, course activities
Fri: Project, course activities
Sat: Secsoc ctf hopefully
0 notes
Text
Weekly project review
We now have process hiding added to the arsenal, although technically the implementation allows hiding of arbitrary files as well. This covers most of the features I wanted to implement.
Over the next week, there’s a few remaining things I would like to look at and at least blog about the ideas behind them if I don’t have time to implement, including
- More advanced syscall hooking- without overwriting the syscall table
- Rootkit persistence across reboots
- Other last minute cool ideas
0 notes
Text
Project: Process hiding
After some more reading of rootkit examples (this time by Redhat, demonstrating the dangers that unknown kernel modules can bring), it was fairly easy to incorporate process hiding. Turns out that our getdents() is the key here. By hiding any entries that mention the process we want to hide, we effectively hide the process directory entry in /proc/, which ps uses to show the currently running processes. We can simply keep a global list of what processes we want to hide which enables us to add processes (or other files, since technically this just adds another blacklisted word to our getdents()) to the hide list on the fly.
We are apparently running an invisible bash process, nice
As with the regular file hiding, the process directory still exists if you try to access it directly, but won’t show up when accessed by any getdents() system calls.
0 notes
Text
Buffer overflow challenges
Since buffer overflows are now examinable course content, I though I’d go through the process of solving some of the beginner challenges posted to openlearning. I’ll only be using tools available in the lab environment (gdb and objdump mostly) and won’t be looking at the source code. Hopefully this is useful!
1.0-basic
First, lets run the program and see what happens.
No real clues here, so lets run objdump -d basic and see how this program works. We get a lot of unimportant information, the most interesting functions we want to look at are main, doCheck and win.
Main doesn’t seem to do much except call doCheck, so lets move on.
doCheck seems to be doing a fair amount, so lets scan the function calls and see if anything pops out at us.
There are a few interesting things here- there’s a call to gets(), so we know we can overflow the buffer in this function. Theres also a call to the win function after a comparison is made- something is being compared to 0x42, which is the hex value for ‘B’. This is stored in [ebp-0x5]. We can find this value referenced again further up in the disassembly.
So it seems 0x41 (ascii value of ‘A’) is placed into a variable which is later compared to ‘B’. If the comparison is true, the win function is called.
So we have our plan of action- overflow the buffer with values and overwrite the check variable with ‘B’. We don’t need to be particularly clever about our buffer length if all we want to do is overwrite the check variable with a ‘B’ so it passes the check (the variable is probably a character since the movb=move byte instruction is used).
We crash but we get the flag!
1.1-whereami
Here we’re given the address to a winning function which is probably handy. Let’s have a gander at the executable with gdb this time. Upon opening, we use disas main to have a look at the disassembly. We see our usual culprint gets(), but we see also see something more interesting:
We load some value into a register and continue execution there. This means that [ebp-0xc] is a local variable that probably contains a function pointer, and this is what we want to overwrite. But how much to write?
Just before gets() we see the address it is being passed points to [ebp-0x4c].
If we open up python and type in 0x4c we see that this is 76. The difference in location between the local variable function pointer and the top of the buffer is 0x4c-0xc = 64 bytes. This means if we write 64 bytes the next byte will be the start of the function pointer! The actual size of the buffer doesn’t matter since it’s filled using gets(). We solved the problem of how much to write.
We also want to display the address correctly formatted into the function pointer variable. Since the architecture is little-endian, we will also have to put the address in backwards. The \x symbol is used to format a byte of hex values next to it. This can be used in a number of different ways to print out what you need:
To solve the challenge, we will use the command line python method. The address of the win function given was 0x8048506. Each byte will use one \x modifier, and we must pad the address with leading 0′s if it doesn’t fit in the 4 byte size of a 32bit address. This means the format-ready address will take this form:
\x08\x04\x85\x06
However, remember that this will be interpreted backwards, so reverse the bytes:
\x06\x85\x04\x08
We can use python to easily print out an arbitrary number of random data then concatenate our address at the end, which forms our payload.
We can then just pipe this into input for our program with |
As discussed, this will fill the space between the function pointer and the start of the buffer with garbage (the letter ‘A’ in this case). Then we write the address of the winning function correctly formatted over the function pointer, which is then jumped to by the program later.
You now have all the skills necessary to solve 1.2-blind, so I’ll leave that as an exercise to the reader.
4 notes
·
View notes
Text
Hack sesh w/the boys
I hung out with some mates and learnt some stuff (thanks Adam and Jazz). We went over shellcode and format strings as well as some challenges. Group hacking is pretty lit, would recommend
Shellcode refers to a series of machine instructions used to perform some function (such as executing a shell, but it doesn’t have to be this), which you can stick into a buffer as part of a buffer overflow exploit then redirect program execution to the shellcode and make the program run those instructions.
Format strings are passed to printf() to interpret and display the printf arguments in specific ways. printf() is often used in bad ways with user input however, which leads to format string vulnerabilities where the user can perform arbitrary reads/writes.
I plan on doing some more posts about format strings, shellcode and the challenges to further cement my understanding in the near future
2 notes
·
View notes
Text
0x00 Challenge writeup
This is a writeup for a challenge that is part of Jazz’s exploitation challenges, available at https://github.com/jtalowell/exploitation. They are quite beginner friendly, and are handy for learning how to incorporate tools like pwntools into your hackermans arsenal. You should go there, star the repository and download the challenges.
So what does this challenge want us to do? Let’s have a look at the README:
We have to modify the value of a specific integer stored on the stack by overflowing a vulnerable buffer. Lets run the program and see what happens.
Not much happened. The flag is set to 0, and upon further testing seems to remain at 0 if we have a small input. What if we gave it more than a small amount?
We changed the value of the flag, but also changed the value of the return address to a bunch of ‘A’s, which is not a valid address so we crash. One method of figuring out how much input we need is by trial and error- keep running the program with different length inputs until the flag value changes. Completely valid, but lets see if gdb can help us.
Here I loaded the program with gdb (I also have pwndbg installed, but it doesn’t make much difference here). Of particular interest are the main<+4> and <+8> lines. The stack is being set up by subtracting 0x20=32 bytes from the stack pointer, then 0 is placed into the first 4 bytes in the next line. This value (rbp - 4) is referenced a few times, and so we can pretty safely assume this is the flag we want to change. We don’t really see more stack movement, so maybe we can make an educated guess and say that if we overwrite 32-4 = 28 bytes we might reach our flag.
Here we put 28 bytes of random input and a 29th byte set to ‘A’. This sets our flag to 65, which happens to be the decimal value of ‘A’. Our educated guess happened to be correct. If we needed to change the flag to some regular keyboard-friendly ascii value this challenge would be fairly straightforward, but 1337 is not such a value. Lets use this opportunity to get some practice with pwntools (download for python 2 with ‘pip install pwntools’) because its cool. You want to be cool, don’t you?
While doing this, lets also look at an alternative way to find the number of bytes required to change the flag. We use the pwntools function cyclic from the command line to generate a series of bytes that we can use as input to the program.
Cyclic has a lookup feature that will take in a value (such as the overwritten flag or an overwritten return address) and tell you how many bytes it took to cause the overflow. Back to gdb to demonstrate.
We set a breakpoint at main and step through the program until after the gets() call, where we provided our input from cyclic. Here we see the value of our flag (at rbp-4) is currently 0x61616168. We can use the cyclic lookup feature to find out how many bytes it took to overwrite the flag:
Seems like we’re on the right track. Lets write up a python script to use pwntools to overwrite the flag.
We simply select the program we want to run, ignore the first line of input, then construct our payload. This will fill the first 28 bytes with random data, then place our desired value formatted correctly afterwards (p32() will handle the endianness conversion for us). We send this line to the program and switch to interactive mode to see the results.
0 notes
Text
Case study review
Recommendations in case of cyber war
- Pentesting your own critical infrastructure systems. This has a dual effect: your own systems are strengthened and your pentesters skills are improved, making them more capable at defending these systems (and performing counter attacks)
- Make preparations in case of critical infrastructure failures- stockpiling of materials, fuel, food and water, and more importantly training the local populace on appropriate reactions to these events (similar to training that occurred during the cold war in case of nuclear attack). This lessens the chance of mass panic and anarchy.
- Have a counter-attack plan in case of attack. Disrupting an opponents systems as much as possible will lessen the impact they have on your systems.
- Be a small target- another option is to not give people reason to attack you. If things go south I know im moving to New Zealand
3 notes
·
View notes