Ask Sawal

Discussion Forum
Notification Icon1
Write Answer Icon
Add Question Icon

Why jmp esp?

4 Answer(s) Available
Answer # 1 #

ESP points directly to the start of your payload (after execution of the ret in the function you're attacking) because you put the payload right after the 4 bytes that overwrite the return address on the stack. ret pops 4 (or 8) bytes into EIP, leaving ESP pointing to the payload that directly follows.

But you don't know what value ESP will have at that point, because of stack ASLR and because a different depth of call stack leading up to this point could change the address. So you can't hard-code a correct return address.

But if there are bytes that decode as jmp esp or call esp anywhere at a fixed (non-ASLRed) address in the process's memory, you can hard-code that address as the return address in your exploit. Execution will go there, then to your payload.

This is in fact often the case: Some DLLs don't have ASLR enabled for their code, and the main executable's code may not be ASLRed either.

Code ASLR for all code defeats a jmp esp attack, unless the attacker can cause the target process to leak addresses.

Note that for 64-bit code, you're unlikely to be able to use jmp rsp for string-based buffer overflows, because code addresses will contain some leading 0 bytes.

Thus, jmp esp gives you a much more reliable exploit than repeatedly guessing a return address (with a very large NOP sled).

Repeated guessing will crash the target process every time you're wrong, but a jmp esp can give you a high chance of success on the first try. This will avoid leaving crash logs. It could also defeat an intrusion-detection system that looks for crashing server processes and blocks connections from your IP address, or similar.

Note that the 2-byte instruction you're looking for can appear as part of another instruction when the program executes normally, or as static data (especially read-only data is often in executable pages). So you just need to search for the 2-byte sequence, not for jmp esp in disassembly of the program. Compilers will never use jmp esp, so you won't find one that way.

More generally, any function that ends with a buffer pointer in any register (e.g. from a memcpy or especially strcpy) can allow a ret2reg attack, by looking for a jmp eax instruction.

This can work in 64-bit mode, where addresses have some high zero bytes; if strcpy's trailing zero writes that high address byte for you, the end of your exploit string could be the non-zero address bytes that overwrite the return address on the stack.

[4]
Edit
Query
Report
Jymn Townsend
Chief Cloud Officer
Answer # 2 #

This is a continuation of the exploit research series, check out the blog before this here. For the sake of brevity, I will not reiterate some of the ideas covered earlier like ‘the stack’ or how to generate a payload using ‘msfvenom’ etc since this exploit will be primarily reusing them with some slight modification.

The stack is the the section of the memory which is used like a temporary scratchpad where a lot of variables and functions are stored, here we will be using the same idea of buffer overflow but with a slight change. The function we are trying to exploit, filters out some characters which will need us to make changes in our exploit design.

So what’s different?We are trying to exploit a remote echo server, which uses ‘strcpy’ function. Though it suffers from the buffer overflow as the exploit before, strcpy puts certain restrictions on the strings we can send to it. Certain characters are considered as string delimiters and the function treats it as the end of string. If these characters are present in our exploit, they will be dropped and the string will be truncated, and the characters beyond it.To take this into account, we would have to make sure none of these characters are included in our exploit. Since we are not crafting our own shellcode for this challenge, we can leave the exclusion of these characters to msfvenom, and focus on the return address since that is the only part of the exploit string we supply based on our deductions.

The first step would be to identify these ‘bad characters’. This can be done by sending the exploit string and seeing where the payload is getting truncated. Usual culprits are newlines, nulls, tabs etc (In hex 0A,00,0D).

The payload we generated using msfvenom, we can have these characters excluded by generating the payload by supplying an extra-parameter “— bad-chars ‘\x00\x0a\x0d’”

Though metasploit does it seamlessly, when we get into the art of writing shellcode ourselves, we explore different techniques so that it does not have the bad characters, how to encode it to bypass string based detection, and also making it position independent.

Problem solved?The payload doesn’t have the bad characters anymore, but we aren’t done yet.

In our last exploit we had a hardcoded address in the stack where our shellcode was located at. This would be all dandy, but a wrench in the works is thrown, since stack addresses now have (“0x00”)

Here we bring in a technique called ‘JMP ESP’. So we have our shellcode on the stack, and we need to move to that address without specifying the shellcode hardcoded address directly. We can use the JMP instruction, to jump to the stack, and stack top is pointed to by the ESP register.

So we overwrite the return address with the address of this “JMP ESP” instruction, and when the return address executes this instruction, it will return to the stack.

Now we just need to find this instruction within the loaded libraries , and Immunity debugged (in general any debugger) can help us find the address of any this command.

One of the addresses out of the many results is “7e429353”. Pasting the prefix part, (the shellcode can be generated by msfvenom, appended and sent over in similar fashion using python as the last challenge).

[3]
Edit
Query
Report
Malina Fürmann
Petroleum Geologist
Answer # 3 #

long answer:

ANY mapped unprotected executable memory in your process will be executed if the Instruction register is set to its address.

MAPPED: means the memory is mapped to your process by the operating system, some addresses may not be mapped and any and all access will cause operating system memory fault signals to be raised.

EXECUTABLE: mapped memory often has permissions set to it, sometimes it is enough for the memory to be readable yet with newer processors with NX-bits it may be required to be mapped executable

UNPROTECTED: means that the memory is not mapped as a guard page. memory pages that are protected by guard pages will raise processor interrupt. the handling of these depends on your operating system and may be used to implement non-executable pages on processors that do not implement NX-bits.

if the memory in your executable file fulfils these demands it CAN be used for your exploit. whether you can FIND this address during runtime is another question and can be very difficult for real world exploits. sticking to non relocatable DLLs and EXEs is a good idea for beginners.

as for your comment:

trying to overrun previous addresses with new addresses that contain '\0' characters may cause problems for exploits that use an overrun in string based functions (eg. strcpy or gets) to overflow the buffer because those stop on '\0' characters.

[3]
Edit
Query
Report
Hollye Staenberg
Renal Nursing
Answer # 4 #

Finding a jmp esp at a semi-predictable place in memory allows you to redirect execution to the top of the stack reliably. So the process would be something like: Overwrite saved instruction pointer (ebp+4) on the stack with the address of jmp esp in the .

[0]
Edit
Query
Report
Aatmaj Prashad
Educational Administrator