简体   繁体   中英

How does XOR prevent NULL bytes in shellcode

I had been trying to follow this tutorial ( https://paraschetal.in/writing-your-own-shellcode ) on how to write your own shellcode. 99% of it makes sense to me but there is just two lingering doubts in my mind - this relates to writing shellcode in general

Firstly, I think I understand why we want to avoid the null byte but how does using the following avoid null bytes?

xor eax, eax

Doesn't eax now contain exactly null bytes? Or does it contain 0s? When we XOR something with itself, it returns False, correct?

Secondly, the tutorial says:

Finally, we'll load the syscall number(11 or 0xb) to the eax register. However if we use eax in our instruction, the resulting shellcode will contain some NULL(\\x00) bytes and we don't want that. Our eax register already is NULL. So we'll just load the syscall number to the al register instead of the entire eax register.

mov byte  al, 0x0b

Now I do understand what is going on here, the number 11 (for execve ) is being loaded into the first 8 bits of eax register (which is al ). But the rest of eax still contains null bytes so what exactly is achieved here?

Please note, I've come here as a last resort after spending most of the day trying to understand this, so please take it easy on me :)

The exploits usually attack C code, and therefore the shell code often needs to be delivered in a NUL-terminated string . If the shell code contains NUL bytes the C code that is being exploited might ignore and drop rest of the code starting from the first zero byte .

This concerns only the machine code . If you need to call the system call with number 0xb, then naturally you need to be able to produce the number 0xb in the EAX register, but you can only use those forms of machine code that do not contain zero bytes in the machine code itself.


xor eax, eax

will invert all the 1 bits in the eax , ie zero it. It is a functional equivalent to

mov eax, 0

except that the latter will have the 0 coded as zero bytes in the machine code .


The machine code for

xor eax, eax
mov byte al, 0x0b

is

31 c0 b0 0b

As you can see, there are no embedded zero bytes in it. The machine code for

mov eax, 0xb

is

b8 0b 00 00 00

Both these programs are functionally equivalent in that they set the value of EAX register to 0xb.

If the latter shell code is handled as a null-terminated string by a C program, the rest of it after the b8 0b 00 could be discarded by the program and be replaced by other bytes in the memory, essentially making the shellcode not work.

The instruction mov eax, 0 assembles to

b8 00 00 00 00

which contains NUL bytes. However, the instruction xor eax, eax assembles to

31 c0

which is free of NUL bytes, making it suitable for shell code.

The same applies to mov al, 0x0b . If you do mov eax, 0x0b , the encoding is

b8 0b 00 00 00

which contains NUL bytes. However, mov al, 0x0b encodes to

b0 0b

avoiding NUL bytes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM