330 lines
8.6 KiB
Lua
330 lines
8.6 KiB
Lua
local commands = {}
|
|
local function registerCommand(cmd, handler)
|
|
if not isstring(cmd) or not isfunction(handler) then return end
|
|
commands[string.lower(cmd)] = handler
|
|
end
|
|
|
|
--============= UTILITY FUNCTIONS =============--
|
|
local function stop(ply)
|
|
netstream.Start(ply, 'dbg-hack.cancel')
|
|
if ply.hacking and IsValid(ply.hacking.target) then
|
|
hook.Run('onKeypadHack', ply, false, ply.hacking.target)
|
|
end
|
|
if ply.hacking and isfunction(ply.hacking.cancel) then ply.hacking.cancel() end
|
|
timer.Remove('dbg-hack.load' .. ply:SteamID())
|
|
ply.hacking = nil
|
|
end
|
|
|
|
local function lock(ply, locked)
|
|
ply.hacking.blocked = (locked == true)
|
|
netstream.Start(ply, 'dbg-hack.updateLockStatus', locked == true)
|
|
end
|
|
|
|
local function invalidEnt(ply)
|
|
local tgt = ply.hacking.target
|
|
return not IsValid(tgt) or ply:GetShootPos():DistToSqr(tgt:GetPos()) > 2500
|
|
end
|
|
|
|
local function invalid(ply)
|
|
if not IsValid(ply) or not ply.hacking then return true end
|
|
if invalidEnt(ply) then return true, stop(ply) end
|
|
return false
|
|
end
|
|
|
|
local function requestInput(ply, cback)
|
|
if invalid(ply) then return end
|
|
ply.hacking.pendingInput = cback
|
|
netstream.Start(ply, 'dbg-hack.requestInput')
|
|
lock(ply)
|
|
end
|
|
|
|
local function beep(ply)
|
|
ply:EmitSound('buttons/button15.wav')
|
|
end
|
|
|
|
local function print(ply, text, append)
|
|
if not IsValid(ply) or not ply.hacking then return false end
|
|
beep(ply)
|
|
netstream.Start(ply, 'dbg-hack.print', text, append == true)
|
|
return true
|
|
end
|
|
|
|
local function input(ply, data)
|
|
local cmd = string.lower(data[1])
|
|
if isfunction(commands[cmd]) then
|
|
table.remove(data, 1)
|
|
commands[cmd](ply, data)
|
|
else
|
|
print(ply, cmd .. ': command not found')
|
|
lock(ply)
|
|
end
|
|
end
|
|
|
|
-- Player types something in terminal and presses the Enter key
|
|
netstream.Hook('dbg-hack.input', function(ply, data)
|
|
|
|
if not isstring(data) or invalid(ply) then return end
|
|
if ply.hacking.blocked then return lock(ply, true) end
|
|
lock(ply, true)
|
|
|
|
local h = ply.hacking
|
|
if h.pendingInput then
|
|
h.pendingInput(data)
|
|
h.pendingInput = nil
|
|
return
|
|
end
|
|
input(ply, string.Split(data, ' '))
|
|
|
|
end)
|
|
|
|
-- Player closes the terminal window (need to stop hacking process)
|
|
netstream.Hook('dbg-hack.cancel', function(ply)
|
|
if not ply.hacking then return end
|
|
if isfunction(ply.hacking.cancel) then ply.hacking.cancel() end
|
|
timer.Remove('dbg-hack.load' .. ply:SteamID())
|
|
ply.hacking = nil
|
|
end)
|
|
hook.Add('PlayerDisconnected', 'dbg-hack.cancel', function(ply)
|
|
if ply.hacking and isfunction(ply.hacking.cancel) then ply.hacking.cancel() end
|
|
timer.Remove('dbg-hack.load' .. ply:SteamID())
|
|
end)
|
|
|
|
--================= COMMANDS =================--
|
|
registerCommand('pwdserver', function(ply)
|
|
hook.Run('dbg-hack.1stCommand', ply, ply.hacking.target)
|
|
print(ply, ply.hacking.target.pwdserver)
|
|
lock(ply)
|
|
end)
|
|
|
|
registerCommand('traceroute', function(ply, data)
|
|
if not data[1] then
|
|
print(ply, 'Usage: traceroute target_ip')
|
|
return lock(ply)
|
|
end
|
|
if data[1] ~= ply.hacking.target.pwdserver then
|
|
print(ply, 'Could not connect to ' .. data[1] .. ': connection was closed unexpectedly.')
|
|
return lock(ply)
|
|
end
|
|
print(ply, 'traceroute to ' .. data[1] .. ', 30 hops max, 38 byte packets')
|
|
|
|
local tm, i = 0, 0
|
|
local function printNext()
|
|
|
|
if invalid(ply) then return end
|
|
i = i + 1
|
|
if not ply.hacking.target.traceroute[i] then return lock(ply) end
|
|
|
|
print(ply, string.format('%2d', i))
|
|
|
|
local time = math.Rand(0.1, 0.4)
|
|
local ip = ply.hacking.target.traceroute[i]
|
|
timer.Simple(time, function()
|
|
if not invalid(ply) then
|
|
print(ply, ' ' .. ip, true)
|
|
end
|
|
end)
|
|
|
|
time = time + math.Rand(0.5, 0.7)
|
|
timer.Simple(time, function()
|
|
if invalid(ply) then return end
|
|
print(ply, string.rep(' ', 15 - #ip + 1), true)
|
|
local timeStr = ''
|
|
for j = 1, 3 do
|
|
tm = tm + math.Rand(0.001, 0.5)
|
|
timeStr = timeStr .. string.format('%.3f ms ', tm)
|
|
end
|
|
print(ply, timeStr, true)
|
|
printNext()
|
|
end)
|
|
|
|
end
|
|
printNext()
|
|
|
|
end)
|
|
|
|
registerCommand('./inject.sh', function(ply, data)
|
|
local ip = data[1]
|
|
if not isstring(ip) then
|
|
print(ply, 'Usage: ./inject.sh target_ip')
|
|
return lock(ply)
|
|
end
|
|
local attNum = 0
|
|
for i,v in ipairs(ply.hacking.target.traceroute) do
|
|
if v == ip then
|
|
attNum = i
|
|
break
|
|
end
|
|
end
|
|
if attNum == 0 then
|
|
print(ply, 'Could not inject interceptor into ' .. ip .. ': connection was closed unexpectedly.')
|
|
return lock(ply)
|
|
end
|
|
ply.hacking.interceptor = attNum
|
|
print(ply, 'successfully injected interceptor on ' .. ip)
|
|
lock(ply)
|
|
end)
|
|
|
|
local alphabet = '123456789'
|
|
local function randomPass()
|
|
local str = ''
|
|
for i = 1, 4 do
|
|
str = str .. alphabet[math.random(#alphabet)]
|
|
end
|
|
return str
|
|
end
|
|
|
|
registerCommand('./unhash.sh', function(ply, data)
|
|
if not isstring(data[1]) then
|
|
print(ply, 'Usage: ./unhash.sh target_hash')
|
|
return lock(ply)
|
|
end
|
|
local ans = {}
|
|
if data[1] ~= ply.hacking.target.problem then
|
|
local seed = tonumber(tostring(data[1]), 16)
|
|
if not seed then
|
|
print(ply, 'Incorrect hash')
|
|
return lock(ply)
|
|
end
|
|
math.randomseed(tonumber(tostring(data[1]), 16))
|
|
for i = 1, 5 do
|
|
ans[#ans + 1] = randomPass()
|
|
end
|
|
math.randomseed(CurTime())
|
|
else ans = ply.hacking.target.passs end
|
|
|
|
local i = 0
|
|
local function printNext()
|
|
if invalid(ply) then return end
|
|
i = i + 1
|
|
if not ans[i] then return lock(ply) end
|
|
print(ply, string.format('%2d. %s', i, ans[i]))
|
|
timer.Simple(math.Rand(0.1, 3), printNext)
|
|
end
|
|
print(ply, 'Possible combinations:')
|
|
timer.Simple(math.Rand(0.1, 3), printNext)
|
|
|
|
end)
|
|
|
|
registerCommand('sudo', function(ply, data)
|
|
|
|
if not isstring(data[1]) then
|
|
print(ply, 'Usage: sudo command command_args')
|
|
return lock(ply)
|
|
end
|
|
local cmd = string.lower(data[1])
|
|
if cmd ~= 'unlock' then
|
|
return input(ply, data)
|
|
end
|
|
|
|
local hashPart
|
|
if ply.hacking.interceptor then
|
|
local h, ind = ply.hacking.target.problem, ply.hacking.target.hashpts[ply.hacking.interceptor]
|
|
hashPart = ''
|
|
for i = 1, ind-1 do
|
|
hashPart = hashPart .. '**'
|
|
end
|
|
hashPart = hashPart .. h[ind * 2 - 1] .. h[ind * 2]
|
|
for i = ind + 1, 4 do
|
|
hashPart = hashPart .. '**'
|
|
end
|
|
hashPart = hashPart
|
|
end
|
|
|
|
print(ply, '[sudo] password for kpad: ')
|
|
requestInput(ply, function(pwd)
|
|
if hashPart then
|
|
print(ply, 'Received pwd hash part: ' .. hashPart)
|
|
end
|
|
if pwd == ply.hacking.target:GetPassword() then
|
|
print(ply, 'Unlocked.')
|
|
ply.hacking.target:Process(true)
|
|
hook.Run('onKeypadHack', ply, true, ply.hacking.target)
|
|
if isfunction(ply.hacking.succeed) then ply.hacking.succeed() end
|
|
else
|
|
print(ply, 'Sorry, try again.')
|
|
ply.hacking.target:Process(false)
|
|
if isfunction(ply.hacking.fail) then ply.hacking.fail() end
|
|
end
|
|
lock(ply)
|
|
end)
|
|
|
|
end)
|
|
|
|
--================ EASTER EGGS ================--
|
|
local files = {
|
|
{'-rwxrwx--x', '1176', 'Feb', '16', '00:19', 'inject.sh'},
|
|
{'-rwxrwxr--', '484', 'Mar', '29', '22:18', 'README.TXT'},
|
|
{'-rwxrwx--x', '9008', 'May', '10', '22:54', 'unhash.sh'},
|
|
}
|
|
|
|
registerCommand('ls', function(ply)
|
|
print(ply, 'total ' .. #files)
|
|
for _,v in ipairs(files) do
|
|
print(ply, string.format('%10s 1 crackr crackr %4s %3s %2s %5s %s', unpack(v)))
|
|
end
|
|
lock(ply)
|
|
end)
|
|
|
|
registerCommand('cat', function(ply, args)
|
|
if not isstring(args[1]) then
|
|
print(ply, 'Usage: cat file_name')
|
|
return lock(ply)
|
|
end
|
|
if string.lower(args[1]) ~= 'readme.txt' then
|
|
print(ply, '[cat] file ' .. args[1] .. ' not found or permission denied for user kpad')
|
|
return lock(ply)
|
|
end
|
|
|
|
print(ply, [[ HOW TO USE THIS PIECE OF SHIT:
|
|
1. Detect keypad's current upsource IP using "pwdserver" command:
|
|
> pwdserver
|
|
37.212.16.22
|
|
2. Check it's packet path using "traceroute" command:
|
|
> traceroute 37.212.16.22
|
|
traceroute to 37.212.16.22, 30 hops max, 38 byte packets
|
|
...
|
|
3. Set interceptors on one of IPs from traceroute:
|
|
> ./inject.sh 37.212.16.22
|
|
Successfully injected interceptor on 37.212.16.22
|
|
4. Try to unlock keypad:
|
|
> sudo unlock
|
|
[sudo] password for kpad: 1111
|
|
Received pwd hash part: ******2f**
|
|
Sorry, try again.
|
|
5. Collect all hash parts and run unhash.sh:
|
|
> ./unhash.sh 16bd7c2fd0
|
|
Possible combinations:
|
|
1. 1234
|
|
2. 8888
|
|
3. 1984
|
|
6. Try to unlock keypad with all passwords prompted:
|
|
> sudo unlock
|
|
[sudo] password for kpad: 1234
|
|
Sorry, try again.
|
|
> sudo unlock
|
|
[sudo] password for kpad: 8888
|
|
Unlocked.
|
|
Feel free contact me if you have any questions: giwamam817@jmail7.com
|
|
]])
|
|
lock(ply)
|
|
end)
|
|
|
|
local pmeta = FindMetaTable('Player')
|
|
function pmeta:Hack(ent, succ, fail, cancel)
|
|
if self:GetShootPos():DistToSqr(ent:GetPos()) > 2500 then
|
|
return self:addExploitAttempt()
|
|
end
|
|
ent:GenerateProblem()
|
|
self.hacking = {
|
|
target = ent,
|
|
succeed = succ,
|
|
fail = fail,
|
|
cancel = cancel,
|
|
blocked = true,
|
|
}
|
|
netstream.Start(self, 'dbg-hack.start')
|
|
timer.Create('dbg-hack.load' .. self:SteamID(), 6, 1, function()
|
|
netstream.Start(self, 'dbg-hack.loaded')
|
|
lock(self)
|
|
end)
|
|
end
|