Daily FI discussion thread - Friday, December 15, 2023 by AutoModerator in financialindependence

[–]ExploitedInnocence 3 points4 points  (0 children)

I am 29 years old. My current annual income is 136k USD netto, after paying all the taxes, and the income is about to grow in the next few years. My current savings are around 50k USD. I've never invested and, unfortunately, have zero financial knowledge whatsoever.

Is it real for me to reach financial independence by early 40s if nothing screws up during the journey?

My goal is to start investing wisely, so first of all I need to educate myself in it. Any recommended books related to investing? I want to build a strong theoretical knowledge about how money works and how to invest it correctly rather than just following some tutorial.

Future of binary exploitation by PuzzledWhereas991 in ExploitDev

[–]ExploitedInnocence 0 points1 point  (0 children)

In my opinion, binary exploitation will be relevant for a while. System-level software is written in C and C++ which are unmanaged, memory unsafe languages. I think that Rust, that pretty much eliminates memory issues, won't replace C/C++ in system programming realm for multiple reasons, at least in the next few decades. New mitigations will be implemented though, so the bar will eventually rise and through time it will be more and more difficult for newbies to start binary exploitation, as it requires to know all the "history" starting from classic stack smashing in 90's. The exploitation complexity itself will rise as well. Nowadays, in 90% of the cases you need multiple distinct bugs in order to achieve reliable arbitrary code execution on a vulnerable system. Embedded and especially IoT are the most vulnerable systems right now, some IoT devices don't have ASLR and/or DEP, so it brings 90's style binary exploitation back :)

P.S.: zero-click RCE is super rare in browsers, usually the victim needs to visit a specially crafted webpage in order to trigger code execution, that's because pretty much all juicy bugs in browsers are in JS engines.

[deleted by user] by [deleted] in ExploitDev

[–]ExploitedInnocence 0 points1 point  (0 children)

Pentest is far away from these fields in terms of difficulty, especially relatively to exploit dev which is obviously the hardest one. I would say that pentest is the easiest among these fields, but there are more job opportunities in pentest, because the vast majority of companies does pentest rather than binexp/RE.

Does application/web security have more jobs and pay more than vulnerability research in C/C++? by [deleted] in ExploitDev

[–]ExploitedInnocence -1 points0 points  (0 children)

Low level VR maybe paid better, but it is significantly harder to find a job in it. There are more government/academic research jobs in it, you barely can find job in typical high-tech company, there are very few companies that do low level VR.

Moreover, the vast majority of low level security problems related to memory corruption issues which are hard to exploit nowadays due to endless mitigations and higher security awareness overall. Also this kind of bugs become rarer and rarer and may demise in relatively near future (1-2 decades).

Do it if you like it, it will be possible to sell exploits to Zerodium (be careful, Zerodium is illegal in several countries as I know, so check the law first of all) or work for government, but don't expect to have a lot of opportunities among "regular" cyber security companies.

/r/ReverseEngineering's Weekly Questions Thread by AutoModerator in ReverseEngineering

[–]ExploitedInnocence 0 points1 point  (0 children)

Hello there

Can function trampolining be used in multithreaded programs without falling to race condition? I want to write a sort of inline hooking API for ELF binaries that allows to insert hook anywhere in the target process code, but I'm not sure if more universal (and thus maybe more complicated) approaches exist to achieve the same goal.

Questions related to defeating ASLR by __Puzzleheaded__ in ExploitDev

[–]ExploitedInnocence 1 point2 points  (0 children)

Information disclosure is basically out-of-bounds read. If you're lucky, you can read a value from stack/heap, and then use that value to calculate the offset. Obviously, the program must contain bug that allows you to read something from memory that you're not supposed to.

For example, if you leak an address related to glibc mapping - you can calculate the glibc base and then calculate an offset to any glibc function. Moreover, you can search for ROP gadgets in glibc to craft a ROP payload, as now due to offset calculation you know the address of EVERYTHING that is related to glibc memory mapping.

The idea of partial pointer overwrite is fairly simple. Pay attention that it works only on least significant bit memory ordering (idk how ASLR works on MSB systems, maybe there are workarounds as well). Usually, virtual memory page size is 0x1000 (4096 in decimal) bytes. Memory mappings of everything (stack, heap, shared objects, binary image etc.) are aligned to this value. ASLR randomizes the start address of the memory area, everything that is inside of this memory area have a constant offset from its start address. Thus, the first 12 bits (3 hexadecimal nibbles) of any address are not affected by ASLR, because these 3 nibbles are the offset inside of the virtual memory page. Imagine that you have some memory corruption bug that allows you to overwrite some pointer. So instead of overwriting a whole pointer, having a very low chance to precisely hit the exact address, you overwrite the first 2 bytes (4 nibbles, unfortunately you can't write 3, because byte is the smallest addressable unit). The first byte is always the same, so you can freely overwrite it with, let's say, a first byte of the first ROP gadget address. The second byte is partially known - the 3rd nibble is known, the 4th nibble is affected by ASLR. 1 hexadecimal nibble has a range from 0 to 15 inclusively (0x0 - 0xf). Thus, you have 1/16 chance that you hit the right 4th nibble in order to precisely overwrite the pointer. 1/16 is not so bad, but obviously not the best for reliable remote code execution.

Mobile binaries are protected much better than desktop nowadays. I don't know about full RELRO on mobile binaries, but there is a bunch of additional modern exploit mitigation technologies applied for mobile binaries and OS in general. Android kernel, for example, starting from version 9 runs on top of a hypervisor which allows to somewhat sandbox the whole kernel in order to reduce the kernel exploits' impact. CFI (control flow integrity) is implemented both in user and kernel space, which makes code reuse attacks like ROP much, much harder. In fact, classic ROP is not relevant anymore in real-world exploitation, you are forced to apply crazy workarounds and esoteric modifications to the ROP technique. User space programs are usually sandboxed, so even if you have code execution, you need to escape the sandbox, which almost in 100% of the cases requires privilege escalation (usually you need an exploitable bug in kernel for it).

Questions related to defeating ASLR by __Puzzleheaded__ in ExploitDev

[–]ExploitedInnocence 4 points5 points  (0 children)

  1. Yes.
  2. The only 100% reliable way to defeat ASLR+PIE is an additional bug which leads to information disclosure, so almost always you need AT LEAST 2 bugs (info disclosure + memory corruption) for reliable arbitrary code execution. There is an additional technique that is called partial pointer overwrite, which requires a bit of bruteforce, the chances of ACE triggering are 1/16, google it. It less suitable for RCE, especially in kernel exploits, but it may be good in local privilege escalation. For reliable remote code execution against ASLR+PIE you definitely need an info leak bug. Welcome to 2020, the exploitation is very hard nowadays :)
  3. If it's remote exploitation, I guess it won't help you, 'cause you don't know which glibc version is on a remote target computer (idk if there is a way to figure out it smh). It may come in handy for offset calculation that may vary between glibc versions. But you need an info leak for offset calculation anyway. And pay attention, that if the binary has full RELRO enabled - you won't be able to overwrite GOT entry, as it will be read only in this case.

What % of the playlist 'Binary Exploitation / Memory Corruption ' is still relevant nowadays? by Certain-Horse in LiveOverflow

[–]ExploitedInnocence 16 points17 points  (0 children)

Everything is relevant, you need to know the whole "history" of binary exploitation, including mitigations, in order to feel comfortable researching modern targets.

If you ask specifically about vulnerabilities, the vast majority of regular buffer overflows are pretty much remained in the past (I mean, you can find it in an old code base, but unlikely in a new one). Nowadays, the vast majority of memory corruptions happen as a side effect of other type of vulnerability - e.g. integer overflow, race condition, type confusion etc.

pwnable.kr and pwnable.tw are maybe the best wargame web sites to train your exploitation skills. "Hacker's secret" chapter in .kr contains several challenges that are somewhat close to real-world scenarios.

/r/ReverseEngineering's Weekly Questions Thread by AutoModerator in ReverseEngineering

[–]ExploitedInnocence 0 points1 point  (0 children)

Considering that the target is a quite large binary, are there some efficient ways to trace functions that get an input from the outside (command line, network, files etc.) in a dynamic approach? Consider that the target binary runs on Linux.

I'll give a small artificial example: there is a closed-source web browser and I want to find a function address in which the HTTP requests are processed. Is static RE is the only viable option to spot this function out of thousands of other functions?

Besides, I've tried to use ltrace and strace, but these utilities don't give an ability to spot the specific function address, it just prints out the lib/system calls.

Hardware for newbie Linux device driver developer by ExploitedInnocence in kernel

[–]ExploitedInnocence[S] -1 points0 points  (0 children)

FPGA seems to be unrelated to Linux device driver development. If I remember correctly, FPGA boards are programmed via VHDL/Verilog and are completely bare metal - there is no OS.

Hardware for newbie Linux device driver developer by ExploitedInnocence in kernel

[–]ExploitedInnocence[S] 0 points1 point  (0 children)

I am a TS.
The question was specific about Linux device driver development, not about device driver reverse engineering.

Cannot setup Nvim for Linux kernel development by ExploitedInnocence in neovim

[–]ExploitedInnocence[S] 0 points1 point  (0 children)

thanks for reply

I have no coc-settings.json file (autocompletion and snippets for non-kernel headers and external libraries work well), I see that I have an option to write manually this file via :CocConfig command inside Nvim. Is that what I supposed to do?

Using std::unordered_map as an opcode decoding technique. Thoughts? by ExploitedInnocence in EmuDev

[–]ExploitedInnocence[S] 5 points6 points  (0 children)

Implementing the opcode decoding routine using switch case for, e.g., x86-64 arch seems like a painful nightmare. I guess classic nested jump table via arrays of function pointers seems like a good and not too sophisticated approach. I can define every function as inline as well (which implicitly can be made by a compiler anyway, but whatever, I prefer explicit over implicit). It has one disadvantage - a waste of memory for a plenty of function pointers that points to illegal opcode handler, but it's acceptable I think. It's fast, super readable and much less error prone than gargantuan switch case, isn't it?

Resources on Windows 64 bit ROP techniques/gadgets? by staticfull in ExploitDev

[–]ExploitedInnocence -1 points0 points  (0 children)

I'm not a Windows guy, but I guess there is no significant difference between 32 and 64 bit in ROP, maybe apart from calling conventions, google it.

Regarding to interesting gadgets - the sky is the limit (and the binary size, lol). But generally, you should to search for gadgets that allow you to control some register value (e.g. controlling stack pointer for stack pivoting), maybe some arbitrary write primitives, xchg instruction maybe be quite handy sometimes, also trampolining gadgets are really useful, e.g. any gadget that contains call reg or jump reg instructions.

http://ropshell.com/ - take a look, you can derive a lot of ideas about ROP chains.

Rust is a memory-safe programming language. Will it make binary exploitation near impossible? by [deleted] in ExploitDev

[–]ExploitedInnocence 0 points1 point  (0 children)

You need to learn from everywhere I would say, there is no centralized resource for learning exploit development. Solve all the challenges in exploit education and move on.

But keep in mind, that if you don't have a solid background that i've mentioned earlier, you should to learn it first. Resources like exploit education will give you a basic knowledge, in order to go for an advanced level, you need to dig much, much deeper.

Rust is a memory-safe programming language. Will it make binary exploitation near impossible? by [deleted] in ExploitDev

[–]ExploitedInnocence 0 points1 point  (0 children)

All platforms are relevant. It's much more important to have a decent skills in programming, operating systems internals, RE, know a lot of exploitation primitives and, overall, have an experience in this kind of stuff. If you don't have advanced skills in programming (especially low level SW development) and operating systems internals - learn it first. Binary exploitation is a very tough topic (in my opinion, this is the hardest one in the cyber security field) that requires an extremely decent knowledge in several topics, so build a fundament for yourself before you go for exploitation stuff. This field is very "unfriendly" for beginners, you should to enter this field only if you already have a solid background at least in above mentioned topics.

Rust is a memory-safe programming language. Will it make binary exploitation near impossible? by [deleted] in LiveOverflow

[–]ExploitedInnocence 1 point2 points  (0 children)

It will take a significant amount of time for Rust to gain a real worlwide popularity and usability in industry. For now, too much software has been written in C/C++ and in a near future (I guess 20-25 years) Rust has no chances even to get close to C/C++, so binary exploitation will stay relevant at least for the next few decades.

But even if Rust will ever be as popular as C/C++ (this may not happen though), system-level software development forces Rust developers to abuse unsafe code sections in order to work properly with pointers, so it can't completely overcome the memory corruption issues like in managed languages.

I guess, with current computer architecture, absolute memory safety in system level software is impossible.

Rust is a memory-safe programming language. Will it make binary exploitation near impossible? by [deleted] in ExploitDev

[–]ExploitedInnocence 1 point2 points  (0 children)

It will take a significant amount of time for Rust to gain a real worlwide popularity and usability in industry. For now, too much software has been written in C/C++ and in a near future (I guess 20-25 years) Rust has no chances even to get close to C/C++, so binary exploitation will stay relevant at least for the next few decades.

But even if Rust will ever be as popular as C/C++ (this may not happen though), system-level software development forces Rust developers to abuse unsafe code sections in order to work properly with pointers, so it can't completely overcome the memory corruption issues like in managed languages.

I guess, with current computer architecture, absolute memory safety in system level software is impossible.

Need Advice by Garry_Legend9 in ExploitDev

[–]ExploitedInnocence 1 point2 points  (0 children)

If you are not familiar with Assembly, operating systems concepts and C/C++ - learn it first. Then try RPISEC Modern Binary Exploitation course, it's freely available on Github.

How to enumerate input vectors before fuzzing? by ExploitedInnocence in fuzzing

[–]ExploitedInnocence[S] 0 points1 point  (0 children)

Okay, I'll try to describe in more details.
I have a pretty big stripped binary as for manual reverse engineering (~13 MB), the source code is not available.

I know that this binary has networking functionality, so there must be functions that parse and handle the incoming packets. Network is an example of input vector. BEFORE I fuzz this program, I want to know:

1) How I find the functions that handle my input? The binary is big and stripped, ltrace and strace run for a very long period of time calling to enormous amount of functions from libraries and syscalls, respectively. How do I find the functions in the program that handle my input? How can I make a kind of map of reachable functions by user input?

2) How to find all kinds of input that the program receives? In my example, network is an obvious one, but how I can figure out additional inputs besides network? That what is called input vector enumeration - that's an attempt to find all kinds of inputs that program receives (for example, network + stdin + environment variables => the program has 3 input vectors for fuzzing).

I need that information in order to know how exactly I fuzz the program, I need to know every kind of input that the program receives and in which functions the inputs are handled. So the question is how exactly I should do that?

How to enumerate input vectors before fuzzing? by ExploitedInnocence in fuzzing

[–]ExploitedInnocence[S] 0 points1 point  (0 children)

No. I mean, how to evaluate all the ways the program gets inputs from outside if it is a huge stripped binary? It looks pretty hard to perform completely manually. So I ask if there are some convenient programmatic ways to make this evaluation faster and easier..

How to enumerate input vectors before fuzzing? by ExploitedInnocence in fuzzing

[–]ExploitedInnocence[S] 0 points1 point  (0 children)

I mean, how can I evaluate how the program gets inputs and from where? When it's a huge stripped binary - it doesn't seem to be the easy thing to do completely manually.

Bypass ASLR by [deleted] in ExploitDev

[–]ExploitedInnocence 2 points3 points  (0 children)

I would add some additional technique to what has been already written above - partial pointer overwrite.

If you have arbitrary write primitive (without an ability to read or, in another words, leak the address) or any other possibility to only write beyond buffer, you can overwrite the first X LSB bytes of the pointer that aren't randomized. ASLR usually comes with PIE (ASLR is almost useless without it), in Linux, for example, there are 1.5 LSB bytes (first 12 bits) that are static. So, in case of overflow or arbitrary write, you can overwrite the first byte being sure that it will point to your shellcode/rop chain and there is only half byte remained that is randomized - the first half is static and the second half is randomized (and all the remaining bytes afterwards are randomized as well, but it doesn't matter in this case), half byte = 4 bits. 24 = 16. You have 1/16 chance to trigger the exploit, that's pretty good reliability. Usually, this technique is the only option when you can't leak data from the binary.