aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore (renamed from 3.11/.gitignore)0
-rw-r--r--3.2/.gitignore1
-rw-r--r--4.1/.gitignore1
-rwxr-xr-x4.1/charon.rb4
-rwxr-xr-x4.1/get_mail.rb58
-rwxr-xr-x4.1/kinit.rb2
-rwxr-xr-x4.1/mail.rb19
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