diff options
author | Nat Lasseter <user@4574.co.uk> | 2025-02-19 22:59:46 +0000 |
---|---|---|
committer | Nat Lasseter <user@4574.co.uk> | 2025-02-19 22:59:46 +0000 |
commit | e532f817c53589de47ead76618677db1ddbb2e48 (patch) | |
tree | 5dfddef80feae4f9a77d0c79fd2b5c09f3c6a90f | |
parent | e160be0ebd55a130d37129714d340726882aac07 (diff) |
[4.1] Complete
-rw-r--r-- | .gitignore (renamed from 3.11/.gitignore) | 0 | ||||
-rw-r--r-- | 3.2/.gitignore | 1 | ||||
-rw-r--r-- | 4.1/.gitignore | 1 | ||||
-rwxr-xr-x | 4.1/charon.rb | 4 | ||||
-rwxr-xr-x | 4.1/get_mail.rb | 58 | ||||
-rwxr-xr-x | 4.1/kinit.rb | 2 | ||||
-rwxr-xr-x | 4.1/mail.rb | 19 |
7 files changed, 62 insertions, 23 deletions
diff --git a/3.11/.gitignore b/.gitignore index bfa3c3c..bfa3c3c 100644 --- a/3.11/.gitignore +++ b/.gitignore diff --git a/3.2/.gitignore b/3.2/.gitignore deleted file mode 100644 index bfa3c3c..0000000 --- a/3.2/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.keytab diff --git a/4.1/.gitignore b/4.1/.gitignore deleted file mode 100644 index bfa3c3c..0000000 --- a/4.1/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.keytab diff --git a/4.1/charon.rb b/4.1/charon.rb index ee2a514..a335d50 100755 --- a/4.1/charon.rb +++ b/4.1/charon.rb @@ -32,7 +32,7 @@ def ticket(username, ws_address, service) sk = SecureRandom.hex.upcase p = [sk, username, ws_address, service, 28800, ts].join(?\0) s = encrypt(p, Services[service]) - "#{sk}:28800:#{ts}:#{s}" + "#{sk},#{ws_address},28800,#{ts},#{s}" end def noleak(msg, ul, ws) @@ -65,7 +65,7 @@ post '/ticket' do next "Invalid ticket\n" unless Time.now.to_i >= ts next "Ticket expired\n" unless Time.now.to_i < (ts + ls) begin - aun, aws = decrypt(data["authenticator"], sk) + aun, aws = decrypt(data["authenticator"], sk).split(?,) rescue OpenSSL::Cipher::CipherError next "Invalid session key\n" end diff --git a/4.1/get_mail.rb b/4.1/get_mail.rb index 8cbbb1f..79a8bc7 100755 --- a/4.1/get_mail.rb +++ b/4.1/get_mail.rb @@ -4,13 +4,32 @@ require 'net/http' require 'uri' require 'json' -def get_ticket(un, tgt, sv) +def encrypt(obj, key) + cipher = OpenSSL::Cipher::AES.new(256, :CBC).encrypt + cipher.key = Digest::SHA2.digest(key) + s = cipher.update(obj) + cipher.final + s.unpack('H*')[0].upcase +end + +def decrypt(obj, key) + ticket = [obj].pack("H*").unpack("C*").pack("c*") + cipher = OpenSSL::Cipher::AES.new(256, :CBC).decrypt + cipher.key = Digest::SHA2.digest(key) + cipher.update(ticket) + cipher.final +end + +def gen_auth(un, ws, sk) + encrypt("#{un},#{ws}", sk) +end + +def get_ticket(un, wsa, tgt, sv, sk) uri = URI.parse("http://localhost:4567/ticket") header = {'Content-Type': 'text/json'} login = { "username": un, "ticket": tgt, + "authenticator": gen_auth(un, wsa, sk), "service": sv } @@ -31,7 +50,14 @@ end def update_keytab! File.open(".keytab", "w") do |f| - f.puts Tickets.map { |s, p| [s, *p.values].join(?:) } + f.puts Tickets.map { |s, p| [ + s, + p["sessionkey"], + p["ws_address"], + p["lifespan"], + p["timestamp"], + p["ticket"] + ].join(?,) } end end @@ -44,21 +70,28 @@ unless File.exist?(".keytab") end Tickets = File.readlines(".keytab").map { |l| - a = l.strip.split(?:) + a = l.strip.split(?,) [a[0], { - "lifespan" => a[1].to_i, - "timestamp" => a[2].to_i, - "ticket" => a[3] + "sessionkey" => a[1], + "ws_address" => a[2], + "lifespan" => a[3].to_i, + "timestamp" => a[4].to_i, + "ticket" => a[5] }] }.to_h unless Tickets.keys.include?(ms) && ticket_valid?(Tickets[ms]) if Tickets.keys.include?("_TGS") && ticket_valid?(Tickets["_TGS"]) - packet = get_ticket(un, Tickets["_TGS"]["ticket"], ms).split(?:) + packet = get_ticket(un, Tickets["_TGS"]["ws_address"], + Tickets["_TGS"]["ticket"], + ms, Tickets["_TGS"]["sessionkey"]) + packet = decrypt(packet, Tickets["_TGS"]["sessionkey"]).split(?,) Tickets[ms] = { - "lifespan" => packet[0].to_i, - "timestamp" => packet[1].to_i, - "ticket" => packet[2] + "sessionkey" => packet[0], + "ws_address" => packet[1], + "lifespan" => packet[2].to_i, + "timestamp" => packet[3].to_i, + "ticket" => packet[4] } update_keytab! else @@ -67,14 +100,13 @@ unless Tickets.keys.include?(ms) && ticket_valid?(Tickets[ms]) end end -ticket = Tickets[ms]["ticket"] - uri = URI.parse("http://localhost:4568/login") header = {'Content-Type': 'text/json'} login = { "username": un, - "ticket": ticket + "ticket": Tickets[ms]["ticket"], + "authenticator": gen_auth(un, Tickets[ms]["ws_address"], Tickets[ms]["sessionkey"]) } http = Net::HTTP.new(uri.host, uri.port) diff --git a/4.1/kinit.rb b/4.1/kinit.rb index 5174839..aca0fa2 100755 --- a/4.1/kinit.rb +++ b/4.1/kinit.rb @@ -29,7 +29,7 @@ cipher.key = Digest::SHA2.digest(pw) begin ticket = cipher.update(eticket) + cipher.final File.open(".keytab", ?w) do |f| - f.puts "_TGS:#{ticket}" + f.puts "_TGS,#{ticket}" end rescue OpenSSL::Cipher::CipherError puts "Invalid password?" diff --git a/4.1/mail.rb b/4.1/mail.rb index e8f9cdd..0f5e979 100755 --- a/4.1/mail.rb +++ b/4.1/mail.rb @@ -9,18 +9,18 @@ set :port, 4568 Service = "Mail" ServicePassword = "{FvM<kgG}VpHxKJO;6Zo" -def decrypt(ticket) - ticket = [ticket].pack("H*").unpack("C*").pack("c*") +def decrypt(obj, key) + ticket = [obj].pack("H*").unpack("C*").pack("c*") cipher = OpenSSL::Cipher::AES.new(256, :CBC).decrypt - cipher.key = Digest::SHA2.digest(ServicePassword) + cipher.key = Digest::SHA2.digest(key) cipher.update(ticket) + cipher.final end post '/login' do request.body.rewind data = JSON.parse(request.body.read) - next "Invalid request\n" unless data.keys.sort == %w(ticket username) - un, ws, sn, ls, ts = decrypt(data["ticket"]).split(?\0) + next "Invalid request\n" unless data.keys.sort == %w(authenticator ticket username) + sk, un, ws, sn, ls, ts = decrypt(data["ticket"], ServicePassword).split(?\0) ls = ls.to_i ts = ts.to_i next "Invalid ticket\n" unless sn == Service @@ -28,5 +28,14 @@ post '/login' do next "Invalid ticket\n" unless ws == request.ip next "Invalid ticket\n" unless Time.now.to_i >= ts next "Ticket expired\n" unless Time.now.to_i < (ts + ls) + + begin + aun, aws = decrypt(data["authenticator"], sk).split(?,) + rescue OpenSSL::Cipher::CipherError + next "Invalid session key\n" + end + next "Invalid authenticator\n" unless aun == un + next "Invalid authenticator\n" unless aws == ws + "Login okay! You have no mail.\n" end |