Aiur – ZelluX 的技术博客

Security, Kernel, Virtualization, Programming Languages

Archive for 2009

基于函数调用栈的rootkit

without comments

好久没更新这个博客了,最近忙实验室项目,作息时间有点颠倒,以至于现在这会儿睡不着把以前扫过一篇paper拿出来看了下。

这篇题目为Return-Oriented Rootkits: Bypassing Kernel Code Integrity Protection Mechanisms的论文发在了今年的Usenix Security上,现在在Usenix网站上还不能下到这篇paper的pdf,可以去作者的主页上下。

现在有不少用来防止栈溢出攻击的技术,比如操作系统保证任何一个页不能同时为可写且可读(WinXP SP2、Win 2003、Exec Shield for Linux等都采用了这个策略),这个方法实现起来比较简单,但只能防范部分形式的攻击,如果攻击者事先准备一张含有恶意代码的用户态的只读页,然后跳转到这个页,就能绕开这种保护措施了;另外也有人提出在操作系统的下面再加一层虚拟层,让它来保证上层系统没有因为各种buffer overflow而执行恶意代码(NICKLE)。

而这里提到的return-oriented的攻击方法不同于传统的攻击机制,它所采用的攻击代码都是内核自身的代码,因此能绕过前面提到的各种保护手段。

所谓return-oriented programming,简单的说就是把原来已经存在的代码块拼接起来,拼接的方式是通过一个预先准备好的特殊的返回栈,里面包含了各条指令结束后下一条指令的地址。

例如现在函数A里面有这么一段指令
instruction A
ret

函数B里面有另外一段:
instruction B
ret

它们在正常的运行情况下没有任何关系,但是我发现如果把A和B拼起来就能达到我想要的结果,于是我构造了一个包含有A和B的地址的栈,先通过ret指令返回到instruction A处,之后再执行ret指令时,由于栈是精心构造的,因此接下来会执行到instruction B,这样就得到我想要的结果了。只要这个ret前的指令库足够大,就能实现几乎所有的程序。

这种攻击方式并非这篇paper的首创,最早是由Shacham提出的(http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.140.9210,http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.78.7135)

这篇paper的一大贡献在于实现了一个自动从libc和驱动、内核等代码中找到可用的指令,并拼接成所需程序的系统,这里面包括一个扫描可利用代码、并把它们结合起来的Constructor,一套专用的语言,以及把这套语言编译成对应代码片段之和的编译器,最后还有一个计算实际代码地址的Loader。

这套攻击机制在WinXP SP2/Sp3, Vista SP1等系统上都获得了成功,尽管查找代码并生成这个过程的overhead很大,但对于一次成功的rootkit攻击来说影响并不大。

Written by zellux

August 12th, 2009 at 2:35 am

Posted in Computer System

Tagged with , ,

Xen警告Time went backwards的暴力解决方法

with 3 comments

前几天给测试Xen用的虚拟机挂了,只能用VMware的snapshot返回到之前的镜像,然后似乎因为时间问题启动Xen的时候总是会定时打印出类似

571 Timer ISR/0: Time went backwards: delta=-11072481 delta_cpu=298927519 shadow=196807680595 off=288495093 processed=197107247546 cpu_processed=196797247546
572  0: 196797247546
573  1: 197107247546

的信息,google了下发现是时间同步的问题,用ntp协议同步时间即可解决这个问题。另外这里再给出一个最暴力的解决方法:在linux-xen源码的arch/i386/kernel/time-xen.c文件中找到Time went backwards,把这行打印语句以及后面的循环打印删除,然后重新编译内核。x86_64体系结构也是修改这个文件。方法很暴力,也没真正解决问题,但是至少不影响我看/var/log/messages的输出了。

Written by zellux

July 7th, 2009 at 11:08 am

Posted in Computer System

Tagged with

防止Firefox在关闭最后一个Tab后退出

without comments

记得以前用Firefox 3.0.x时把Tools -> Options -> Tabs -> Always show the tab bar勾上就行了,升级到3.5以后就没用了,搜了下Knowledge Base,最后在

https://support.mozilla.com/tiki-view_forum_thread.php?locale=zh-CN&comments_parentId=184680&forumId=1

看到只要将about:config页中的browser.tabs.closeWindowWithLastTab项设为false即可

Written by zellux

July 1st, 2009 at 11:05 am

Posted in Tools

Tagged with

万恶的迅雷盗链

without comments

收到网站空间服务商的通知说这个月的流量已经达到3G+,超过上限2G了,而我两个博客加起来的访问量也才1000+,总不至于每次访问都能来个3M流量吧。然后查了下空间流量统计,发现之前在另外一个博客上传了一首Sentimental Kills,有人下载的时候用了迅雷,以至于这个月这个mp3一共被下了7000多次,直接把流量撑爆了,而那个博客是没有被任何搜索引擎收录的。

估计明天开始到月底,这个博客要暂时没法访问了。。。

Written by zellux

June 19th, 2009 at 8:11 pm

Posted in Meta-blogging

Tagged with

SVN更新短信通知脚本

without comments

主要功能:开发人员执行svn commit后自动将开发人id、修订版本号和日志内容通过短信的方式通知所有人。

首先修改svn服务器对应项目目录hook/post-commit文件

#!/bin/bash

export LANG=en_US.utf8
REPOS="$1"
REV="$2"

cd /home/svn/repositories/sebank/hooks
./sms.py commit $REPOS $REV

注意别忘了这里的export LANG,我一开始测试的时候发现中文一直有乱码,后来才意识到shell的环境变量里缺这个。
hook/sms.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys, urllib, os
from subprocess import *

user = 'your mobile number'
pword = 'fetion password'
phone = [
        '13764444444',
        '13813333333',
        ]

repo = sys.argv[2]
rev = sys.argv[3]
cmdlog = 'svnlook log -r %s %s'%(rev, repo)
cmdauthor = 'svnlook author -r %s %s'%(rev, repo)
log = Popen(cmdlog, stdout=PIPE, shell=True).stdout.read().strip()
author = Popen(cmdauthor, stdout=PIPE, shell=True).stdout.read().strip()

msg = 'sebank #%s %s: %s' % (rev, author, log)

for number in phone:
    url = 'http://sms.api.bz/fetion.php?username=%s&password=%s&sendto=%s&message=%s' % (user, pword, number, urllib.quote_plus(msg))
    cmd = 'curl "%s"' % url
    send = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
    send.wait()

这里user是发送者的手机号,且该用户的飞信好友需包含其他用户,pword为飞信密码,phone为用户手机号码列表。
最后设置下这两个文件的权限,保证http/svn用户能执行即可。另外由于sms.py中飞信密码是明文保存的,注意控制它的读权限。

Written by zellux

June 16th, 2009 at 6:57 pm

Posted in Programming

Tagged with , ,

云计算

with one comment

某门课程的Open Topic,我的话题是关于云计算的,读了一篇Above the Clouds: A Berkeley View of Cloud Computing

http://www.eecs.berkeley.edu/Pubs/TechRpts/2009/EECS-2009-28.html

这是UCB的RAD(Reliable Adaptive Distributed)实验室花了六个月时间brainstorm总结出来的paper,介绍了云计算的概念、现状及未来展望。以下内容主要来自于我上交的文档,做了一些修改,欢迎大家指正。

虽然现在对云计算这个概念的炒作大于实际研究,以至于很多人听到云计算这个名词就想到忽悠,但这里面还是很多东西需要好好考虑和设计的。云计 算和以前的cluster computing等概念虽有相同之处,区别也有不少,它涉及了经济学、虚拟化技术、安全等诸多领域的内容。

何谓云计算?

云计算包含两方面内容,一是通过Internet提供的作为服务的应用程序,这些服务以前也被称为SaaS(Software as a Service);二是提供这些服务的在数据中心的硬件和系统软件,这部分也就是我们通常所称呼为“云”的东西。

云计算平台的优势

云计算带来了三个新颖的观点:
1.    提供了看起来没有上限的可用计算资源,用户不需要提前考虑设备的需求量;
2.    免去了云计算用户的前期投入,使得公司可以从一个规模较小的硬件资源起家,并根据自己的需要增加资源;
3.    细粒度的计费手段,例如按每小时使用处理器数或者每天使用的存储空间计算,并在暂时不需要机器和存储空间时即时减免费用。

关于云计算资源拥有很好的弹性,以Amazon EC2为例,用户可以在几分钟内完成硬件资源的增加或者减少操作,而这在传统的应用程序部署中是很难做到的。文中提到了Facebook上的一个应用Animoto,这个应用的资源需求在三天内从50台服务器上升到了3500台服务器,这在传统的部署中很难估计并完成。另外还有一个问题,当资源需求下降时,传统方式部署的服务器资源就被闲置了,而通过云计算部署的资源甚至可以在晚上访问量下降时减少占用的硬件资源从而减少支出费用。

平台分类

现在的云计算平台提供了不同粒度的API。Amazon EC2是一个底层的极端,它提供了类似物理硬件的接口,用户可以几乎控制从内核开始的整个软件栈。通过虚拟技术提供的CPU、块设备、IP级别的连通技术使得开发人员几乎可以做任何事情。高度的灵活性带来的是可控性的损失,在自动伸缩性(automatic scalability)和容错转移(failover)方面,服务商就力不从心了。而Google AppEngine则提供了比较高层的API,主要面向传统的web应用,在牺牲灵活性之后能很好的实现自动伸缩和转移,并对用户完全透明。而微软的Azure则介于这两者之间,提供了CLR接口,用户可以通过.Net的一系列语言和类库实现自己的应用程序。

不同的平台有不同的适用范围,不可能有一方压倒性的胜过另一方,这个问题就像Ruby和C语言孰优孰劣一样。

当前问题及解决方案

1.    服务的有效性
即如何保证服务总是可以访问

文中提出的方法是不同的公司能提供独立的软件栈,以保证某一个服务无法使用后能及时切换到另一个。但这个实现似乎会有不少阻力,至少现在的云计算服务平台各自的API都还大相径庭,要在不同的平台间转移应用不怎么可行。

至于DDoS攻击,云计算的弹性可以很好的化解这个问题。文章算了一笔账,从黑市租借50万个攻击机器人攻击一个EC2的实例会使得受害者遭受额外的每小时460美刀的支出,但由于租借这些机器人需要1.5万美刀的资金,要使得受害者的损失大于攻击者的支出,这样的攻击需要持续32小时,对于攻击者来说很不可取。

2.    数据被锁定
数据被锁在服务提供商的数据平台中,客户无法很简单的把数据从一个站点转移到另一个。这也是Stallman反对云计算的一个重要原因,客户可能因为数据锁在云计算平台中而不得不接收服务提供商的价格提升等要求。

文中提到的一个解决方案就是统一平台的API,使得数据能在不同的服务提供商之间转移。我觉得这个方案也不现实,就像有了GAppEngine后,应该不会有另一家服务商提供类似的Python或者Java的API支持了吧?

不过也许可以有一个第三方的库把不同的服务商的API再做一层抽象,让应用程序来使用这些平台无关的API,就像是OpenCL/Streamware之于GPU。

3.    数据机密性
这个问题我想不算难点,可信计算已经是研究的热门之一了,而用户自己也可以将机密数据加密后再保存到云中。而虚拟机监控器层也能提供相应的保障,例如CHAOS和VMware的OverShadow可以保护在不可信的操作系统中应用程序运行的安全性,这样即使攻击者能利用操作系统层的漏洞,也无法对操作系统上面的受保护的应用程序进行攻击。

4.    数据传输瓶颈
用户的数据要传输到云里面,消耗的时间和带宽都很高,怎么办呢?

一个简单和实用的方案就是直接通过快递公司邮递硬盘,几TB的数据不到一天就能传到数据中心了。

另一个手段是尽可能地把数据保留在云中。我觉得广义的来说这也是一种locality的优化吧,但是这样就又要考虑到前面提到的数据锁定的问题了。

此外,降低网络传输的费用也是一个研究方向,据估计三分之二的网络带宽费用都是用在高端的路由器上,而另外的三分之一才是用在传输介质中。如何减少路由器的耗费是一个需要深入研究的问题,另外如何更有效的设计云里面的网络的拓扑结构也值得探讨。

5.    性能的不稳定
我觉得相对其他问题,这个问题应该算是很难解决的了。由于客户使用的虚拟机往往和其他虚拟机共享了云中的硬件资源,在共用I/O设备的时候表现性能会有较大的起伏。

提高性能稳定性的最直接的途径自然是提高体系结构和操作系统虚拟中断及I/O通道时的效率了。另外文中还考虑了使用闪存来降低I/O干扰的可能,不过我认为闪存随机写的性能很差,代替硬盘后的性能未必会好,尤其在多个虚拟机同时访问的情况下,稳定性就很难说了。

另外,在调度虚拟机的时候,还要采用Gang Schedule,即对于一些必须几个线程同时运行的程序,要保证这些虚拟机能被同时调度运行。

6.    文章还提到了另外5个障碍,包括存储设备的可伸缩性,如何快速伸缩、大规模分布式系统中的bug问题,这可以通过开发相应的可伸缩存储系统、算法以及分布式调试器解决。另外还有声誉共享(一个客户的恶意行为被其他网站记录,可能影响到同一台物理机上的另一个无辜的客户),软件协议等问题。这些应该都不是难点,而软件协议方面,微软也已经推出Windows Server和Windows SQL Server的到期支付(pay as you go)的协议。

Written by zellux

June 9th, 2009 at 5:24 pm

Posted in Computer System

Tagged with ,

Company-mode: Emacs自动补全

without comments

Company的全写是complete everything,它只是一个补全的前端,会自动调用semantic等后端插件。

新版的Company可以从它的官方主页(http://nschum.de/src/emacs/company-mode/)下载到,也可以从ELPA下载安装这个插件。

使用这个插件时只要在.emacs中加入

(add-to-list 'load-path "/path/to/company")
(autoload 'company-mode "company" nil t)

然后Emacs中使用M-x company-mode启动company模式即可。

具体的按键可以在company.el中看到

(defvar company-active-map
  (let ((keymap (make-sparse-keymap)))
    (define-key keymap "\e\e\e" 'company-abort)
    (define-key keymap "\C-g" 'company-abort)
    (define-key keymap (kbd "M-n") 'company-select-next)
    (define-key keymap (kbd "M-p") 'company-select-previous)
    (define-key keymap (kbd "") 'company-select-next)
    (define-key keymap (kbd "") 'company-select-previous)
    (define-key keymap [down-mouse-1] 'ignore)
    (define-key keymap [down-mouse-3] 'ignore)
    (define-key keymap [mouse-1] 'company-complete-mouse)
    (define-key keymap [mouse-3] 'company-select-mouse)
    (define-key keymap [up-mouse-1] 'ignore)
    (define-key keymap [up-mouse-3] 'ignore)
    (define-key keymap "\C-m" 'company-complete-selection)
    (define-key keymap "\t" 'company-complete-common)
    (define-key keymap (kbd "") 'company-show-doc-buffer)
    (define-key keymap "\C-w" 'company-show-location)
    (define-key keymap "\C-s" 'company-search-candidates)
    (define-key keymap "\C-\M-s" 'company-filter-candidates)
    (dotimes (i 10)
      (define-key keymap (vector (+ (aref (kbd "M-0") 0) i))
        `(lambda () (interactive) (company-complete-number ,i))))

    keymap)
  "Keymap that is enabled during an active completion.")

这里默认的补全按键是Tab,由于已经把它绑定到了yasnippet,我用了Shift-Tab替代(Ctrl-Tab似乎在terminal下没法用,不知道哪位能解决这个问题)

(define-key company-mode-map "\t" nil)
(define-key company-mode-map [(backtab)] 'company-complete-common)

如果按了Shift-Tab没有任何反应,请确认你的后端插件已经配置正确,可以参考这篇博文

另外这里还有个视频,不喜欢看文字的话看一下这个就知道company怎么用了。http://nschum.de/src/emacs/company-mode/screencast/

Written by zellux

June 2nd, 2009 at 10:27 pm

Posted in Tools

Tagged with

两个和函数构造相关的趣味面试题

without comments

http://stackoverflow.com/questions/731832/interview-question-ffn-n

http://stackoverflow.com/questions/732485/interview-question-ffx-1-x

问题描述很简单,第一个问题是实现一个函数f,参数为一个带符号的32位整型,使得f(f(x)) = -x,即调用两次后返回的结果为原来的相反数;另一个问题也是实现一个函数g,参数为一个32位浮点,最后使得g(g(x)) = 1/x。如果不能满足所有的情况,就满足尽可能多的情形。

第二个问题比第一个问题简单一点,目前支持数最高的两个答案如下:
Read the rest of this entry »

Written by zellux

June 1st, 2009 at 9:42 pm

Posted in Algorithm/Mathematics

Tagged with ,

利用VMware的虚拟串口调试Xen

with 2 comments

VMware支持虚拟串口设备,对于调试内核或者虚拟机的帮助很大,具体设置如下(VMware Server 2, Xen 3.3):

1. VMware中为虚拟机增加串口设备
Add Hardware->Serial Port,然后在设置中将Connection模式设为File,指定相应的文件路径(如[standard] debian-xen/serial-port.log)

2. 修改虚拟机的grub启动参数,以我的/boot/menu/lst为例

title           Xen 3.3.0 / Debian GNU/Linux, kernel 2.6.18.8-xen
root            (hd0,0)
kernel          /boot/xen-3.3.0.gz com1=115200,8n1 loglvl=all guest_loglvl=all console_to_ring console=com1,vga sync_console
module          /boot/vmlinuz-2.6.18.8-xen root=/dev/sda1 ro console=tty0
savedefault

3. 重启虚拟机,即可在之前指定的文件中(Host机上的/opt/vmware/Virtual Machines/debian-xen/serial-port.log)中看到虚拟机的输出信息了。

Written by zellux

May 27th, 2009 at 2:31 pm

Posted in Computer System

Tagged with , ,

ArchLinux下安装git, gitosis, gitweb服务

without comments

参考文章:

[1] http://hokietux.net/blog/?p=58
[2] http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way
[3] http://www.nkuttler.de/2009/04/06/git-clone-ssh-could-not-resolve-hostname/

1. git

很简单,直接用pacman安装即可
sudo pacman -S git

2. gitosis

gitosis是一个方便管理git仓库的工具,安装方法:

1) 从yaourt或者aur下载安装gitosis-git包 http://aur.archlinux.org/packages.php?ID=23419

2) 新建git用户
sudo useradd –system –shell /bin/sh –comment ‘git version control’–user-group –home-dir /home/git/ git

3) 将开发用户的rsa公钥导入gitosis,(没有公钥的话请先运行ssh-keygen -t rsa生成)
sudo -H -u git gitosis-init < ~/.ssh/id_rsa.pub

4) 如果以上步骤没有问题,那么运行
git clone ssh://git@hostname/gitosis-admin.git

后应该就能看到gitosis-admin.git这个目录了

5) 新建项目、添加用户等操作参见[2],这里不再赘述

3. gitweb

事实上ArchLinux中安装的git包自带了gitweb,可以用which gitweb搜到,一般默认在/usr/share/gitweb。下面假设我的http根目录为/home/httpd

1) 将/usr/share/gitweb下的文件复制到/home/httpd/cgi-bin(其实似乎只要gitweb.cgi就够了)
sudo cp -R /usr/share/gitweb /home/httpd/cgi-bin/

2) /usr/share/gitweb下的.css和.png复制到/home/httpd/html/git/

3) 修改或创建/etc/gitweb.conf,具体配置如下

# git命令的地址
$GIT = "/usr/bin/git";

# 项目仓库地址
$projectroot = "/home/git/repositories";

# 网页显示相关的文件,我把它们都放在了/home/httpd/html/git/下
$stylesheet = "/git/gitweb.css";
$logo = "/git/git-logo.png";
$favicon = "/git/git-favicon.png";

# 首页显示的站点名
$site_name = "ZelluX's Git Trees";

# 项目信息中显示的地址,
@git_base_url_list = ("ssh://git\@hostname");

# 网页中项目说明的显示长度
$projects_list_description_width = 50;

# 发布的项目的标记。例如/home/git/repositories/hello/git-daemon-export-ok存在,
# 那么hello这个项目就会显示在项目列表上。
# 但是似乎每次pull或者push操作都会导致git把这个它认为多余的文件删掉,不知道有没有其他的解决方案。
# 把这行注释掉就允许所有的项目显示在网页上。
$export_ok = "git-daemon-export-ok";

$feature{'pathinfo'}{'default'} = [1];

$feature{'blame'}{'default'} = [1];
$feature{'blame'}{'override'} = [1];

$feature{'pickaxe'}{'default'} = [1];
$feature{'pickaxe'}{'override'} = [1];

$feature{'snapshot'}{'default'} = [1];
$feature{'snapshot'}{'override'} = [1];

$feature{'search'}{'default'} = [1];

$feature{'grep'}{'default'} = [1];
$feature{'grep'}{'override'} = [1];

4) 在apache的配置中增加以下内容 /etc/httpd/conf/httpd.conf,这里我没有用VirtualHost机制,只加了行URL重写规则,VirtualHost的配置方法参见[1]

RewriteEngine on
RewriteRule ^/gitweb/(.*) /cgi-bin/gitweb.cgi/$1 [L,PT]

5) 重启apache后应该就能访问 http://hostname/gitweb/ 了,如果提示Project not found,请确认apache能访问git的仓库目录,并且相应的项目目录下有git-daemon-export-ok这个文件。

Written by zellux

May 26th, 2009 at 3:21 pm

Posted in Tools

Tagged with ,

FireStats icon Powered by FireStatsBetter Tag Cloud