Last active
April 2, 2024 14:00
-
-
Save caltuntas/657f89c7df80c3582659d63c63a5993d to your computer and use it in GitHub Desktop.
Extract and save images from guac packet capture
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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