Skip to content

Instantly share code, notes, and snippets.

@caltuntas
Last active April 2, 2024 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caltuntas/657f89c7df80c3582659d63c63a5993d to your computer and use it in GitHub Desktop.
Save caltuntas/657f89c7df80c3582659d63c63a5993d to your computer and use it in GitHub Desktop.
Extract and save images from guac packet capture
guacp_packets = 0
packet_no = 0
local OPCODE_IMG = "332E696D672C"
local OPCODE_BLOB = "342E626C6F622C"
local OPCODE_END = "332E656E642C"
tap_guacp = Listener.new(nil,"guacp")
local guacp_instructions_f = Field.new("guacp.instructions")
local guacp_instruction_f = Field.new("guacp.instruction")
local guacp_opcode_f = Field.new("guacp.opcode")
local guacp_opcode_len_f = Field.new("guacp.opcode.len")
local guacp_opcode_value_f = Field.new("guacp.opcode.value")
local guacp_args_f = Field.new("guacp.args")
local guacp_arg_f = Field.new("guacp.arg")
local guacp_arg_len_f = Field.new("guacp.arg.len")
local guacp_arg_value_f = Field.new("guacp.arg.value")
function tap_guacp.draw()
print("guacp packets:" .. guacp_packets)
end
function tap_guacp.packet(pinfo,tvb,ip)
local instructions = { }
print("----------packet--------", packet_no)
packet_no = packet_no + 1
local instruction_list = { guacp_instruction_f() }
local opcodes = { guacp_opcode_f() }
local opcodelens = { guacp_opcode_len_f() }
local opcodevals = { guacp_opcode_value_f() }
local argvals = { guacp_arg_value_f() }
local instruction = { }
for ii, ins in pairs(instruction_list) do
for io, opcode in pairs(opcodes) do
local val = tostring(opcode.value)
if (val == OPCODE_IMG or val == OPCODE_BLOB or val == OPCODE_END) and
ins.offset == opcode.offset then
instruction = get_instruction(ins,opcode,opcodelens,opcodevals,argvals)
table.insert(instructions,instruction)
end
end
end
guacp_packets = guacp_packets + 1
if next(instructions) ~= nil then
write_to_file(instructions, guacp_packets)
end
end
function get_img_ext(instruction)
for i,val in pairs(instruction.arguments) do
if string.match(val,"image/") then
return string.gsub(val,"image/","")
end
end
end
function write_to_file(instructions,no)
local image_found = false
local image_saved = false
local blob =""
local ext = ""
for i, instruction in pairs(instructions) do
print("hex value:",instruction.opcode.hex_value)
local code = tostring(instruction.opcode.hex_value)
if code == OPCODE_IMG then
image_found = true
ext = get_img_ext(instruction)
print("opcode value string:", instruction.opcode.value)
end
if image_found == true and code == OPCODE_BLOB then
print("blob found:", instruction.arguments[2])
blob = blob .. instruction.arguments[2]
end
if image_found == true and code == OPCODE_END then
local raw_data = ByteArray.new(blob, true):base64_decode():raw()
print("entire blob:", blob)
local file,err = io.open("blob" .. no .. "." .. ext,'w')
if file then
file:write(raw_data)
file:close()
image_saved = false
image_found = false
else
print("error:", err)
end
end
end
end
function get_instruction(ins,opcode,opcodelens,opcodevals,argvals)
local instruction = { offset = ins.offset, length = ins.len }
local t_opcode = { hex_value = opcode.value, total_length = opcode.len }
print("instruction offset:", ins.offset)
print("ins.len:", tostring(ins.len))
print("opcode.value", opcode.range:string());
print("offset:", tostring(opcode.offset))
print("len:", tostring(opcode.len))
for il, opcodelen in pairs(opcodelens) do
if opcodelen.offset == opcode.offset then
print("opcode.len:", opcodelen.value)
for iv, opcodeval in pairs(opcodevals) do
if opcodeval.offset >= opcode.offset+2 and opcodeval.offset <= opcode.offset+2+opcodelen.value then
print("opcodeval.val:", opcodeval.value)
t_opcode["value"] = opcodeval.value
end
end
end
end
instruction["opcode"] = t_opcode
instruction["arguments"] = { }
for ia, argval in pairs(argvals) do
if argval.offset >= opcode.offset+opcode.len and argval.offset < ins.offset + ins.len then
print("arg.val:", argval.value)
table.insert(instruction.arguments,argval.value)
end
end
return instruction
end
function tap_guacp.reset()
guacp_packets = 0
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment