危险漫步博客
新鲜的“黑客思维”就是从全新的角度看待黑客技术,从更高的层面去思考;专注于黑客精神及技术交流分享的独立博客。
文章2289 浏览18982399

再战shellcode

好久没写shellcode了,今天危险漫步来写个关机功能的shellcode熟悉一下。相信大家对shellcode已经比较熟悉了,本节就写个简单ftjshellcode,介绍一下普通shellcode编写时应该注意的问题。

对于shellcode的用途以及含义就不再解释了。在写shellcode之前我们一般要先用汇编语言将目标函数写出来,这里我们实现的是关机功能,使用的是msvcrt.dll库中的system函数,命令:system(”shutdown.s—t 3000”).由于该函数在msvcrt.dll库中,所以我们在使用的时候需要将这个库载入,载入使用函数LoadLibraryA(”msvcrt.dll”)。LoadLibraryA函数在xp sp3的地址是Ox7C801D7B,当然如果为了更加通用,我们可以动态获取所有用到的函数的地址,不过这就有点麻烦了,这里就用了,直接硬编码xp sp3的地址了。下面是我们实现功能的汇编代码:

上面就是我们的汇编函数了,新手在写汇编的时候最容易犯的错误就是栈不平衡。在我们将函数名、文件名或者命令参数压入堆栈是一定要注意参数的字节顺序,例如:shutdown-s-a 3000对应的16进制是:73687574646F776E202D73202D612033303030但在我们压栈的时候需要逆序进行,就得到这样的命令:0003 t—s-nwodtuhs 16进制表示:3030303320742D20732D206E776F6474756873我们再来看一下我们对代码的栈处理。在第一个call eax后我们使用了指令add esp,Oxl0,我们千米那总共使用了5个push指令,投一个指令会有4个字节的数据入栈,总共是20个字节,但这里我们却使用了Oxl0总共16字节来恢复堆栈,是不是错了呢?没有,应为我们这里调用的函数是LoadLibraryA,这个函数是一个标准的windows api,其调用模式属于stdcall,函数内部会给我们自动平衡因为该函数的参数而造成的栈不平衡。这个函数一个参数,所以在我们的5个push中,有一个是他自己处理的,这个push就是push edx。所以我们只需要处理剩下的4AIpush就可以了。再看,在后面的cal中,我们使用了7个push,总共28个字节,对应的16进制就是lc,这里我们就用了add esp,Oxlc来恢复堆栈,为什么这里是lc了呢?我们在这里调用的函数是msvcrt.dll中的函数,这里的函数属于C运行时函数,属于标准的c调用(__cdecl)模式。对于C调用模式来说,堆栈的平衡需要调用者自行清理,函数内部并不会清理我们的堆栈,所以这里就需要我们全都清理了。对于调用约定,大家必须十分熟悉,因为在后面我们会经常用到。

我们把程序放到OD中开始提取shellcode,前面的花指令就是帮助我们找到函数的。  

下面就是我们提取的shellcode,我们用数组来存放:

我们在主程序中将其作为一个函数来进行调用测试,代码如下:    

运行程序.就可以看到结果了。成功执行我们的shellcode。本文演示了简单的shellcode编写方法,对于网络通信的shellcode也是同样的编写道理,这里面最关键的就是参数的入栈、函数地址获取以及堆栈的平衡。编写复杂的sheUcdoe需要注意的问题很多,比如说指令截断问题等等。要想写出优秀的shellcode来,我们必须数量的掌握汇编语言,当然如果你用C/C++的话也是可以的,但不如汇编直观。

相关推荐