Current section

Files

Jump to
paraxial lib paraxial exploit_guard.ex
Raw

lib/paraxial/exploit_guard.ex

defmodule Paraxial.ExploitGuard do
@moduledoc false
use GenServer
require Logger
import IEx.Helpers, only: [pid: 1]
alias Paraxial.Helpers
def start_link(state \\ %{}) do
GenServer.start_link(__MODULE__, state, name: __MODULE__)
end
# Functions to be called externally, none
# This GenServer receives trace messages and prints
# a warning if it detects someone exploiting :erlang.binary_to_term/1 or /2
def init(_) do
# Start the tracing, max 10 calls per 1 second
ms = [{:"$1", [{:==, {:binary_part, {:hd, :"$1"}, 0, 2}, <<131, 112>>}], [{:return_trace}]}]
:recon_trace.calls({:erlang, :binary_to_term, ms}, {10, 1000}, [{:io_server, self()}])
{:ok, %{}}
end
def handle_info({:io_request, p_id, tag, request}, _state) do
Logger.alert("[Paraxial] Exploit behavior detected, binary_to_term created function")
{_, _, _, _, i} = request
exploit_term = IO.iodata_to_binary(i)
Logger.alert("[Paraxial] Exploit info: " <> exploit_term)
if :persistent_term.get(:exploit_guard) == :block do
exploit_pid = get_exploit_pid(exploit_term)
Process.exit(exploit_pid, :kill)
Logger.alert("[Paraxial] Block mode active, exploit process killed")
backend_then_reply(exploit_term, p_id, tag)
else
Logger.alert("[Paraxial] Monitor mode active, no action taken")
backend_then_reply(exploit_term, p_id, tag)
end
end
def get_exploit_pid(exploit_term) do
exploit_term
|> String.split(" ")
|> Enum.at(1)
|> String.split([".", "<", ">"], trim: true)
|> Enum.join(".")
|> pid()
end
def backend_then_reply(exploit_term, p_id, tag) do
Task.start(fn ->
send_to_backend(exploit_term)
end)
send(p_id, {:io_reply, tag, :ok})
{:noreply, %{}}
end
def send_to_backend(message) do
mode = :persistent_term.get(:exploit_guard)
url = Helpers.get_exploit_ingest_url()
api_key = Helpers.get_api_key()
j_map = %{
mode: mode,
message: message,
api_key: api_key
}
json = Jason.encode!(j_map)
HTTPoison.post(url, json, [{"Content-Type", "application/json"}])
end
end