Modules for snooze are written in lua. Maybe you want to write a module or just play with snooze but find it inconvinient to read the whole language reference.
Most of the programs comming with snooze are not (properly) documented (yet). This small howto will hopefully enlighten what some of the programs were written for.
So, let us imagine you want to write a module for snooze and you dont know the protocol. (I will illustrate these steps on a well known protocol so its maybe easier to understand why we are doing these steps).
First we need some sample data to analyze. We make a copy of the
dump_tcp.lua
file and change the first line to match our needs:
"-- :xxx_no_proto:1:tcp:" to "-- :xxx_no_proto:21:tcp:" |
We start snoozed:
# snoozed -i en0 -M modules/ -b -c t0 -D 10 THCsnoozed-0.0.6 by THC DEBUG: loading modules ... ... |
After we got one or two connections sniffed and stored we quit snooze. Now, we can use hxdmp to view the logs (well, you can use your favourite text editor to do that):
$ ./hxdmp -c t0/127.0.0.1_31231_127.0.0.1_21_0001.complete hxdmp - THCsnooze hexdump by THC 00000000 32 32 30 20 6c 6f 63 61 6c 68 6f 73 74 20 46 54 | 220 loca lhost FT 00000010 50 20 73 65 72 76 65 72 20 28 74 6e 66 74 70 64 | P server (tnftpd 00000020 20 32 30 30 35 30 31 30 31 29 20 72 65 61 64 79 | 2005010 1) ready 00000030 2e 0d 0a 55 53 45 52 20 67 75 65 73 74 31 0d 0a | ...USER guest1.. 00000040 33 33 31 20 50 61 73 73 77 6f 72 64 20 72 65 71 | 331 Pass word req 00000050 75 69 72 65 64 20 66 6f 72 20 67 75 65 73 74 31 | uired fo r guest1 00000060 2e 0d 0a 50 41 53 53 20 41 41 41 41 0d 0a 32 33 | ...PASS AAAA..23 00000070 30 2d 0d 0a 53 59 53 54 0d 0a 46 45 41 54 0d 0a | 0-..SYST ..FEAT.. 00000080 50 57 44 0d 0a 20 20 20 20 57 65 6c 63 6f 6d 65 | PWD.. Welcome 00000090 20 74 6f 20 42 6f 78 30 30 31 21 0d 0a 32 33 30 | to Box0 01!..230 000000a0 20 55 73 65 72 20 67 75 65 73 74 31 20 6c 6f 67 | User gu est1 log 000000b0 67 65 64 20 69 6e 2e 0d 0a 32 31 35 20 55 4e 49 | ged in.. .215 UNI 000000c0 58 20 54 79 70 65 3a 20 4c 38 20 56 65 72 73 69 | X Type: L8 Versi 000000d0 6f 6e 3a 20 74 6e 66 74 70 64 20 32 30 30 35 30 | on: tnft pd 20050 000000e0 31 30 31 0d 0a 32 31 31 2d 46 65 61 74 75 72 65 | 101..211 -Feature 000000f0 73 20 73 75 70 70 6f 72 74 65 64 0d 0a 20 4d 44 | s suppor ted.. MD 00000100 54 4d 0d 0a 20 4d 4c 53 54 20 54 79 70 65 2a 3b | TM.. MLS T Type*; 00000110 53 69 7a 65 2a 3b 4d 6f 64 69 66 79 2a 3b 50 65 | Size*;Mo dify*;Pe 00000120 72 6d 2a 3b 55 6e 69 71 75 65 2a 3b 0d 0a 20 52 | rm*;Uniq ue*;.. R 00000130 45 53 54 20 53 54 52 45 41 4d 0d 0a 20 53 49 5a | EST STRE AM.. SIZ 00000140 45 0d 0a 20 54 56 46 53 0d 0a 32 31 31 20 45 6e | E.. TVFS ..211 En 00000150 64 0d 0a 32 35 37 20 22 2f 68 6f 6d 65 2f 67 75 | d..257 " /home/gu 00000160 65 73 74 31 22 20 69 73 20 74 68 65 20 63 75 72 | est1" is the cur 00000170 72 65 6e 74 20 64 69 72 65 63 74 6f 72 79 2e 0d | rent dir ectory.. 00000180 0a | . |
The red data is send from server to client; the green from client to server. We can see here that user guest1 is logging in with password AAAA. It is time to write a module that can extract this information from the logfile.
It is often easier to write a module when you have a log of a session at hands. Furtunatly, we just grabbed one and so we already know what we have to go for.
Starting with a simple module, we can use the offline-snooze utility to check if it works, anytime. Our initial module code could be something like (you might consult the API Reference):
-- :ftp:21:tcp:
x = snooze.get_server ()
if x == nil then
return
end
t = string.sub (x, 1, 4)
if t == "USER" then
snooze.save (x)
end
|
We take the data send from client to server. If there is no data the module leaves. If there is data and it begins with the string "USER" we save the whole string. Using offline-snooze, we check what the module does with the saved log file:
$ ./offline-snooze -t 127.0.0.1_31231_127.0.0.1_21_0001.complete TEST.lua offline-snooze by THC Running ... snooze_save: +++++++++++++++++ USER guest1 ++++++++++++++++++++++++++++++ done. |
It works. Ok, we could add another test for the password. But it would be cool if we could check if the login was successful and wether the server accepted the username. Up to now we paid no attention to the data send from server to client.
The snooze library:
| Name | Description |
|---|---|
| src_port() | returns the source port of the connection (for tcp). Or the source port of the packet (for udp). |
| dst_port() | returns the destination port of the connection (for tcp). Or the destination port of the packet (for udp). |
| src_addr() | returns the source ip address in numbers-and-dot notation (as a string). |
| dst_addr() | returns the destination ip address in numbers-and-dot notation (as a string). |
| get() | returns the data previously exported with set. if no data was exported nil ist returned. |
| set(X) | saves the string X. Use this to carry data accross module calls. |
| get_udp() | Get the payload from an udp packet. If called for non-udp data, nil is returned. |
| get_client() | Get data send from server to client. If no data is aviable the empty string is returned. |
| get_server() | Get data send from client to server. |
| finished() | Notify snooze that the module has finished it's operation. |
| save(X) | save the string X to log file. |
The utils library:
| Name | Description |
|---|---|
| base64_encode(X) | returns the base64 encoded version of string X. |
| base64_decode(X) | decodes the base64 encoded string X and returns it. |
| bpack | |
| bunpack |