This file is indexed.

/usr/share/ettercap/lua/core/ettercap.lua is in ettercap-common 1:0.8.1-3+deb8u1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
---
-- Basic ettercap functionality!
--
--    Copyright (C) Ryan Linn and Mike Ryan
--
--    This program is free software; you can redistribute it and/or modify
--    it under the terms of the GNU General Public License as published by
--    the Free Software Foundation; either version 2 of the License, or
--    (at your option) any later version.
--
--    This program is distributed in the hope that it will be useful,
--    but WITHOUT ANY WARRANTY; without even the implied warranty of
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--    GNU General Public License for more details.
--

--    You should have received a copy of the GNU General Public License along
--    with this program; if not, write to the Free Software Foundation, Inc.,
--    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

-- 


-- All of our core stuff will reside in the "ettercap" namespace.
ettercap = {}

local ffi = require("ettercap_ffi")
require('packet_meta')
local ettercap_c = require("ettercap_c")
local eclib = require("eclib")
local op = require('io')
ettercap.reg = require("ettercap_reg")

--- Log's a message using ettercap's ui_msg function.
-- @see string.format
-- @param fmt The format string
-- @param ... Variable arguments to pass in
log = function(fmt, ...) 
  -- We don't want any format string "accidents" on the C side of things.. 
  -- so, we will let lua handle it.
  ettercap_c.log(string.format(fmt, ...))
end

file_exists = function(filename)
  local msg = nil
  local fio, errmsg, errno = io.open(filename, "r")
  if fio then
    fio:close()
    return true
  end

  assert(errno == 2, "Could not open '" .. filename .. "': " .. errmsg)

  return false
end

require('dumper')

--- Dumps data structure(s) to log
-- @param ... The data to dump!
dump = function (...)
  log(DataDumper(...), "\n---")
end

-- Script interface
--
-- All Ettercap LUA scripts are initialized using a common interface. We've 
-- modeled this interface very closely after that of NMAP's NSE script 
-- interface. Our hope is that the community's familiarity with NSE will 
-- lower the barrier for entry for those looking to write Ettercap LUA 
-- scripts.
--
--
--  Data structures:
--    packet_object - Access to the Ettercap "packet_object" (originally 
--                    defined in include/ec_packet.h) is provided via a 
--                    light luajit FFI wrapper. Details on interacting with 
--                    data-types via luajit FFI can be found here:
--                    http://luajit.org/ext_ffi_semantics.html. 
--
--                    Generally, script implementations should avoid direct
--                    modifications to packet_object, or any FFI wrapped 
--                    structure, instead favoring modification through 
--                    defined ettercap.* interfaces.
--
--                    NOTE: Careful consideration must be taken to when 
--                    interacting with FFI-wrapped data-structures! Data 
--                    originating from outside of the LUA VM must have their
--                    memory managed *manually*! See the section of luajit's
--                    FFI Semantics on "Garbage Collection of cdata Objects"
--                    for details. 
--                    
--
--  Script requirements:
--
--    description - (string) Like that of NSE, each script must have a 
--                  description of the its functionality.
--
--    action      - (function (packet_object)) The action of a script operates
--                  on a FFI-wrapped packet_object. 
--
--  Optional:
--
--    packetrule  - (function (packet_object)) If implemented, then this 
--                  function must return true for a given packet_object 
--                  before that packet_object is passed to the script's action.
--

local Script = {}

do
  local coroutine = require "coroutine";
  local debug = require "debug";
  local traceback = debug.traceback;

  local ETTERCAP_SCRIPT_RULES = {
    packetrule = "packetrule",
  };

  -- These are the components of a script that are required. 
  local REQUIRED_FIELDS = {
    description = "string",
    action = "function",
--    categories = "table",
--    dependencies = "table",
  };

  function Script.new (filename, arguments)
    local script_params = arguments or {};  
    local script_path = filename 
    local full_path = ETTERCAP_LUA_SCRIPT_PATH .. "/" .. filename;

    local file_closure = nil

    if file_exists(filename) == true then
      file_closure = assert(loadfile(filename))
      script_path = filename
    elseif file_exists(full_path) == true then
      file_closure = assert(loadfile(full_path))
      script_path = full_path
    else
      log("ERROR: Could not find script '%s'\n", filename)
      return nil
    end

    local env = {
      SCRIPT_PATH = script_path,
      dependencies = {},
    };

    -- No idea what this does.
    setmetatable(env, {__index = _G});
    setfenv(file_closure, env);

    local co = coroutine.create(file_closure); -- Create a garbage thread
    local status, e = coroutine.resume(co); -- Get the globals it loads in env

    if not status then
      log("Failed to load %s:\n%s", filename, traceback(co, e));
      --error("could not load script");
      return nil
    end

    for required_field_name in pairs(REQUIRED_FIELDS) do
      local required_type = REQUIRED_FIELDS[required_field_name];
      local raw_field = rawget(env, required_field_name)
      local actual_type = type(raw_field);
      assert(actual_type == required_type, 
             "Incorrect of missing field: '" .. required_field_name .. "'." ..
             " Must be of type: '" .. required_type .. "'" ..
             " got type: '" .. actual_type .. "'." ..
             " Script: '" .. env["SCRIPT_PATH"] .. "'"

      );
    end

    -- Check our rules....
    local rules = {};
    for rule in pairs(ETTERCAP_SCRIPT_RULES) do
      local rulef = rawget(env, rule);
      assert(type(rulef) == "function" or rulef == nil,
          rule.." must be a function!");
      rules[rule] = rulef;
    end
    local action = env["action"];

    -- Make sure we have a hook_point!
    local hook_point = rawget(env, "hook_point")
    assert(type(hook_point) == "number", "hook_point must be a number!")
 
    local script = {
      filename = filename,
      action = action,
      rules = rules,
      hook_point = hook_point,
      env = env,
      file_closure = file_closure,
      script_params = script_params
    };
    
    return setmetatable(script, {__index = Script, __metatable = Script});
  end
end

-- Stores hook mappings.
--- Called during ettercap's shutdown
local ettercap_cleanup = function() 
end

local packet_object_ctype = ffi.typeof("struct packet_object *")
local ffi_cast = ffi.cast

local create_hook = function(script)
  local packetrule = script.rules["packetrule"]
  local hook_func = function(packet_object_ptr) 
    local packet_object = ffi_cast(packet_object_ctype, packet_object_ptr);
    if (not(packetrule == nil)) then
      if not(packetrule(packet_object) == true) then
        return false
      end
    end
    script.action(packet_object)
  end
  return(hook_func)
end

-- Adds a hook
local hook_add = function (hook_point, func)
  ettercap_c.hook_add(hook_point, func)
end

-- Processes all the --lua-script arguments into a single list of script
-- names. 
--
-- @param scripts An array of script cli arguments
-- @return A table containing all the split arguments
local cli_split_scripts = function (scripts)
  -- This keeps track of what script names have already been encountered. 
  -- This prevents us from loading the same script more than once.
  local loaded_scripts = {}

  local ret = {}
  for v = 1, #scripts do
    local s = scripts[v]
    local script_list = eclib.split(s, ",")
    for i = 1, #script_list do 
      if (loaded_scripts[script_list[i]] == nil) then
        -- We haven't loaded this script, yet, so add it it our list.
        table.insert(ret, script_list[i])
        loaded_scripts[script_list[i]] = 1
      end
    end 
  end

  return ret
end

-- Processes all the --lua-args arguments into a single list of args
-- names. 
--
-- @param args An array of args cli arguments
-- @return A table containing all the split arguments
local cli_split_args = function (args)
  local ret = {}
  for v = 1, #args do
    local s = args[v]
    local arglist = eclib.split(s, ",")
    for i = 1, #arglist do 
      -- We haven't loaded this args, yet, so add it it our list.
      local temp = eclib.split(arglist[i],"=")
      ret[temp[1]] = temp[2]
    end 
  end

  return ret
end

-- Loads a script.
--
-- @param name (string) The name of the script we want to load.
-- @param args (table) A table of key,value tuples
local ettercap_load_script = function (name, args)
  local script = assert(Script.new(name, args), "Failed to load: " .. name)
  hook_add(script.hook_point, create_hook(script))
end

-- Primary entry point for ettercap lua environment
-- @param lua_scripts Array of CLI script strings
-- @param lua_args Array of CLI argument strings
local ettercap_main = function (lua_scripts, lua_args)
  local scripts = cli_split_scripts(lua_scripts)
  local args = cli_split_args(lua_args)
  for i = 1, #scripts do
    ettercap_load_script(scripts[i], args)
  end
end

-- C -> LUA api functions. These should never be called from scripts!
ettercap.main = ettercap_main
ettercap.cleanup = ettercap_cleanup

-- Global functions

ettercap.log = log
ettercap.dump = dump

-- Is this even nescessary? Nobody should be requiring this except for 
-- init.lua... However, I'll act like this is required.
return ettercap