首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>本站原创>linux原创>文章内容
unix入侵及防御心得(一)(1)
来源:www.vfocus.net 作者:vitter 发布时间:2007-01-05  
vitter的unix入侵及防御心得(一)

 

By:vitter@www.safechina.net
<vitter@safechina.net>


前言: 今天(12.28)考试完没事,最近心情不好,写点东西打发时间,希望对大家有点帮助,也希望是抛砖引玉。由于水平有限如有什么不对的地方请大家斧正。
关于unix的查点和踩点不包括在本文的论述之中,本文也不可能包括全面的unix的安全综合介绍,本文讨论的前提条件是踩点工作你已经做好。

目录:
1: 远程访问(remote access)
1.1 暴力破解
1.2 数据驱动攻击(data driven attack)
1.2.1 缓冲区溢出
1.2.2 输入验证攻击
1.3 shell
1.3.1 X Window
1.3.2 反向通道
1.4 常见类型远程攻击
1.4.1 TFTP
1.4.2 FTP
1.4.3 sendmial
1.4.4 RPC
1.4.5 NFS
1.4.6 DNS劫持

2: 本地访问(local access)
2.1 密码的脆弱性
2.2 本地缓冲区溢出
2.2.1 symbolic link
2.2.2 file descriptor攻击
2.2.3 core文件操作
2.2.4 shared library
2.2.5 内核错误
2.2.6 服务配置
2.2.7 shell攻击

3: 得到root之后
3.1 木马
3.2 嗅探
3.3 日志
3.4 rootkit

4: 小结

--[ 1.0 远程访问(remote access)

远程绕过unix系统的安全有3个主要方法:
1.发现某个建立在TCP/UDP的监听ing的漏洞
2.经由1个或多个网络之间unix系统路由
3.由用户自己发起的远程执行攻击(比如访问恶意WEB网站)

--[1.1 暴力破解

虽然暴力破解没有什么意思,但是往往暴力破解是攻击者取得unix系统的访问权的最有效的方法之一。最常见的可能成为暴力破解的对象的服务有:
Telnet
FTP
“R”命令(比如rlogin、rsh等)
SSH
POP
HTTP/HTTPS
finger、 rusers、sendmial之类的服务都可用来标示系统上用户帐号,如果攻击者获取了用户帐号之后,就能猜测其中某个ID相关的密码,进而获得系统访问权。虽然手工猜测密码很有可能,但是大多数情况下是用自动执行的暴力破解工具猜测。比如:Brutus、pop.c、TeeNet、sadmind- brute-force等。

暴力破解对策:使用强壮的密码。一次性密码机制最理想。或者利用第三方软件。

--[1.2 数据驱动攻击(data driven attack)

数据驱动攻击(data driven attack)是通过向某个活动中的服务发送将导致非预期结果的数据来执行。他分缓冲区溢出(buffer overflow attack)和输入验证攻击(input validation attack)2种:

--[1.2.1 缓冲区溢出

几十年来,缓冲区溢出一直引起许多严重的安全性问题。其中最著名的例子是:1988 年,因特网蠕虫程序在 fingerd 中利用缓冲区溢出感染了因特网中的数万台机器,使得各地的服务器管理员都对此极为头痛。但是,缓冲区溢出问题并非已成古老的历史。据统计,仅去年缓冲区溢出就占使 CERT/CC 提出建议的所有重大安全性错误的百分之五十以上。(CERT/Coordination Center 是位于匹兹堡的“软件工程协会”的一个部门)并且数据显示这一问题正在扩大,而不是在缩减。

很明显,至此您不会认为缓冲区溢出错误将是过时的。所以,为什么现在仍产生缓冲区溢出这种致命错误呢?这是因为引起灾难的方法总是惊人地简单。一部分采用错误的语言设计(通常是 C 和 C++),再结合程序员拙劣的编写手段,就会发生这种大问题。尽管象 Java 这样不具备某些令人难以置信的异常编程方式的、现代“安全”的语言避免了缓冲区溢出,但这一问题缓冲区溢出也会发生在非 C 和 C++ 的语言。在任何情况下,合理的原因通常都证明诸如 C 和 C++ 等语言的使用是正确的,因此了解它们的缺陷就非常重要了。

引起缓冲区溢出问题的根本原因是 C(与其后代 C++)本质就是非安全的。没有边界来检查数组和指针的引用,也就是开发人员必须检查边界(而这一行为往往会被忽视),否则会冒遇到问题的风险。标准 C 库中还存在许多非安全字符串操作,包括:

strcpy()
strcat()
sprintf()
gets()

出于这些原因,对编写苛求安全性代码的 C 和 C++ 程序员必须自我进行有关缓冲区溢出问题的教育。最佳的防范就是关于这些问题的良好的教育。

什么是缓冲区溢出?
缓冲区溢出开始于每个程序都需要的一些情况:放置位元的空间。多数计算机程序都在内存中创建多个地址用于信息存储。C 编程语言允许程序员在运行时在内存的两个不同部分(堆栈和堆)中创建存储器。通常,分配到堆的数据是那些 malloc() 或新建时获得的数据。而分配到堆栈的数据一般包括非静态的局部变量和所有按值传递的参数。大部分其它信息存储在全局静态存储器中。(从现在开始,我们将在两个专栏中论述它们的实质细节。)在分配同一数据类型的相邻块时,这块内存区域称为缓冲区。

在写入缓冲区时,C 程序员必须注意存储在缓冲区中的数据不能超过它所能容纳的量。缓冲区只能容纳一定数量的位,就象一个杯子只能盛一定量的水。如果放到杯子中的水太多,多余的水就会溢出到别的地方。相似地,如果试图放入缓冲区的数据比它能装入的要多,额外的数据就会溢出到别处,并且您不希望它到其它地方!

当程序写入超过缓冲区的边界时,这就是所谓的“缓冲区溢出”。发生缓冲区溢出时,会覆盖下一个相邻的内存块。由于 C 语言本质上的不安全性,所以它允许程序随意(或者更准确地说是完全出于偶然)溢出缓冲区。没有运行时检查来这一防止写入超过缓冲区末尾,所以程序员必须在其自己的代码中执行这一检查,否则继续下去会遇到问题。

读取或写入超过缓冲区的末尾时,会导致许多不同(并且通常是不可预料的)行为:1) 程序的执行很奇怪,2) 程序完全失败,或者 3) 程序可以继续,而且在执行中没有任何明显不同。缓冲区溢出的副作用取决于:

写入的数据中有多少超过缓冲区边界
当缓冲区已满并且溢出时,覆盖了哪些数据(如果有的话)
程序是否试图读取溢出期间被覆盖的数据
哪些数据最终替换被覆盖的内存

存在缓冲区溢出的程序的不确定行为使得对它们的调试异常棘手。最坏的情况是:程序可能正发生缓冲区溢出,但根本没有任何副作用的迹象。因此,缓冲区溢出问题常常在标准测试期间是发现不了的。认识缓冲区溢出的重要一点是:在发生溢出时,会潜在地修改碰巧分配在缓冲区附近的任何数据。

下面给一个例子:

我们假设有一个有漏洞的服务器程序(vulnerable.c). 然后写一个 exploit 来利用该漏洞,这样将能得到一个远程 shell。
一、理解有漏洞程序:
------------------------------------vulnerable.c-------------------------------
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>

#define BUFFER_SIZE 1024
#define NAME_SIZE 2048

int handling(int c)
{
char buffer[BUFFER_SIZE], name[NAME_SIZE];
int bytes;
strcpy(buffer, "My name is: ");
bytes = send(c, buffer, strlen(buffer), 0);
if (bytes == -1)
return -1;
bytes = recv(c, name, sizeof(name), 0);
if (bytes == -1)
return -1;
name[bytes - 1] = ’\0’;
sprintf(buffer, "Hello %s, nice to meet you!\r\n", name);
bytes = send(c, buffer, strlen(buffer), 0);
if (bytes == -1)
return -1;
return 0;

}


int main(int argc, char *argv[])

{
int s, c, cli_size;
struct sockaddr_in srv, cli;
if (argc != 2)
{
fprintf(stderr, "usage: %s port\n", argv[0]);
return 1;
}
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1)
{
perror("socket() failed");
return 2;
}
srv.sin_addr.s_addr = INADDR_ANY;
srv.sin_port = htons( (unsigned short int) atol(argv[1]));
srv.sin_family = AF_INET;
if (bind(s, &srv, sizeof(srv)) == -1)
{
perror("bind() failed");
return 3;
}
if (listen(s, 3) == -1)
{
perror("listen() failed");
return 4;
}
for(;;)
{
c = accept(s, &cli, &cli_size);
if (c == -1)
{
perror("accept() failed");
return 5;
}
printf("client from %s", inet_ntoa(cli.sin_addr));
if (handling(c) == -1)
fprintf(stderr, "%s: handling() failed", argv[0]);
close(c);
}
return 0;
}

----------------------------------EOF----------------------------------

下面将编译并运行该程序:
vitter@linux:~/ > gcc vulnerable.c -o vulnerable
vitter@linux:~/ > ./vulnerable 8080
../vulnerable 8080 说明你能在8080端口运行该项服务
vitter@linux~/ > gdb vulnerable
GNU gdb 4.18
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-suse-linux"...
(gdb) run 8080
Starting program: /home/user/directory/vulnerable 8080
现在该程序监听8080端口并等待连接。
vitter@linux:~/ > telnet localhost 8080
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
My name is: Robin
, nice to meet you!
Connection closed by foreign host.
vitter@linux:~/ >
看来没有什么破绽,但是这时gdb会在屏幕上显示:
client from 127.0.0.1 0xbffff28c (访地址因不同机器类型而异)

二、令有漏洞程序发生缓冲区溢出

重新连上该服务,为 "My name is:..." 命令行提供超过1024个字节长的输入:
vitter@linux:~/ > telnet localhost 8080
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
My name is: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

共4页: 上一页 1 [2] [3] [4] 下一页
 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·OPENVPN安装手册
·openssh记录sftp详细日志,并chr
·ssh-3.2记录sftp日志,并且chroo
·用linux构建仗剑江湖mud游戏服务
·Linux高可用(HA)集群笔记heartbe
·关于日志记录系统设计思想
·unix入侵及防御心得(一)(2)
·linux下的Informix安装配置
·Informix的数据库优化
·Linux下apache运行mysql,cgi,p
·Linux下安装Oracle817完美解决版
·改的一个非GBK的JSP的webshell
  相关文章
·unix入侵及防御心得(一)(2)
·使用rsync从linux到linux或到win
·在VMware 4.5.1下运行Fedora Cor
·Fedora 1升级2.6.5内核
·如何给solaris打补丁
·关于日志记录系统设计思想
·Linux + Win me 2000 xp 用OS Lo
·忘记linux密码怎么办
·用linux构建仗剑江湖mud游戏服务
·OPENVPN安装手册
·Linux高可用(HA)集群笔记heartbe
·lvs+heard负载均衡文档(DR)
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved