zsteg 0.0.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 (51) hide show
  1. data/Gemfile +15 -0
  2. data/Gemfile.lock +38 -0
  3. data/README.md +46 -0
  4. data/README.md.tpl +31 -0
  5. data/Rakefile +99 -0
  6. data/TODO +14 -0
  7. data/VERSION +1 -0
  8. data/bin/zsteg +7 -0
  9. data/cmp_bmp.rb +47 -0
  10. data/cmp_png.rb +42 -0
  11. data/lib/zsteg.rb +12 -0
  12. data/lib/zsteg/checker.rb +228 -0
  13. data/lib/zsteg/checker/wbstego.rb +98 -0
  14. data/lib/zsteg/cli.rb +132 -0
  15. data/lib/zsteg/extractor.rb +21 -0
  16. data/lib/zsteg/extractor/byte_extractor.rb +94 -0
  17. data/lib/zsteg/extractor/color_extractor.rb +95 -0
  18. data/lib/zsteg/file_cmd.rb +63 -0
  19. data/lib/zsteg/result.rb +90 -0
  20. data/pngsteg.gemspec +65 -0
  21. data/samples/06_enc.png +0 -0
  22. data/samples/Code.png +0 -0
  23. data/samples/README +4 -0
  24. data/samples/camouflage-password.png +0 -0
  25. data/samples/camouflage.png +0 -0
  26. data/samples/cats.png +0 -0
  27. data/samples/flower.png +0 -0
  28. data/samples/flower_rgb1.png +0 -0
  29. data/samples/flower_rgb2.png +0 -0
  30. data/samples/flower_rgb3.png +0 -0
  31. data/samples/flower_rgb4.png +0 -0
  32. data/samples/flower_rgb5.png +0 -0
  33. data/samples/flower_rgb6.png +0 -0
  34. data/samples/montenach-enc.png +0 -0
  35. data/samples/ndh2k12_sp113.bmp.7z +0 -0
  36. data/samples/openstego_q2.png +0 -0
  37. data/samples/openstego_send.png +0 -0
  38. data/samples/stg300.png +0 -0
  39. data/samples/wbsteg_noenc.bmp +0 -0
  40. data/samples/wbsteg_noenc_17.bmp +0 -0
  41. data/samples/wbsteg_noenc_even.bmp +0 -0
  42. data/samples/wbsteg_noenc_even_17.bmp +0 -0
  43. data/spec/camouflage_spec.rb +9 -0
  44. data/spec/cats_spec.rb +23 -0
  45. data/spec/flowers_spec.rb +11 -0
  46. data/spec/openstego_spec.rb +21 -0
  47. data/spec/simple_spec.rb +22 -0
  48. data/spec/spec_helper.rb +39 -0
  49. data/spec/wbstego_spec.rb +10 -0
  50. data/spec/zlib_spec.rb +6 -0
  51. metadata +198 -0
@@ -0,0 +1,90 @@
1
+ module ZSteg
2
+ module Result
3
+
4
+ class Struct < ::Struct
5
+ def to_s
6
+ inspect.sub('#<struct ZSteg::', '<')
7
+ end
8
+ end
9
+
10
+ class OpenStego < IOStruct.new "CVCCCC",
11
+ :version, :data_len, :channel_bits, :fname_len, :compress, :encrypt, :fname
12
+
13
+ def self.read io
14
+ super.tap do |r|
15
+ r.fname = io.read(r.fname_len) if r.fname_len
16
+ end
17
+ end
18
+
19
+ def to_s
20
+ super.sub(/^<Result::/,'').sub(/>$/,'').red
21
+ end
22
+ end
23
+
24
+ class Text < Struct.new(:text, :offset)
25
+ def to_s
26
+ "text: ".gray + (offset == 0 ? text.inspect.red : text.inspect)
27
+ end
28
+ end
29
+
30
+ # whole data is text
31
+ class WholeText < Text; end
32
+
33
+ # part of data is text
34
+ class PartialText < Text; end
35
+
36
+ class Zlib < Struct.new(:data, :offset)
37
+ def to_s
38
+ "zlib: data=#{data.inspect.red}, offset=#{offset}"
39
+ end
40
+ end
41
+
42
+ class OneChar < Struct.new(:char, :size)
43
+ def to_s
44
+ "[#{char.inspect} repeated #{size} times]".gray
45
+ end
46
+ end
47
+
48
+ class FileCmd < Struct.new(:title, :data)
49
+ COLORMAP = {
50
+ /bitmap|jpeg|pdf|zip|rar|7z/i => :red,
51
+ /DBase 3 data/i => :gray
52
+ }
53
+
54
+ def to_s
55
+ if title[/UTF-8 Unicode text/i]
56
+ begin
57
+ t = data.force_encoding("UTF-8").encode("UTF-32LE").encode("UTF-8")
58
+ rescue
59
+ t = data.force_encoding('binary')
60
+ end
61
+ return "utf8: " + t
62
+ end
63
+ COLORMAP.each do |re,color|
64
+ if title[re]
65
+ if color == :gray
66
+ return "file: #{title}".send(color)
67
+ else
68
+ return "file: " + title.send(color)
69
+ end
70
+ end
71
+ end
72
+ "file: " + title.yellow
73
+ end
74
+ end
75
+
76
+ class Camouflage < Struct.new(:hidden_data_len, :host_orig_len)
77
+ def initialize(data)
78
+ self.hidden_data_len = (data[0x1a,4] || '').unpack('V').first
79
+ if data.size > 300 && data[-4,4] == "\x20\x20\x20\x20"
80
+ # orignal length of host file
81
+ self.host_orig_len = data[-281,4].unpack('V').first
82
+ end
83
+ end
84
+
85
+ def to_s
86
+ super.red
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,65 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "pngsteg"
8
+ s.version = "0.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Andrey \"Zed\" Zaikin"]
12
+ s.date = "2013-01-06"
13
+ s.email = "zed.0xff@gmail.com"
14
+ s.executables = ["pngsteg"]
15
+ s.files = [
16
+ "Gemfile",
17
+ "Gemfile.lock",
18
+ "Rakefile",
19
+ "VERSION",
20
+ "bin/pngsteg",
21
+ "lib/pngsteg.rb",
22
+ "lib/pngsteg/checker.rb",
23
+ "lib/pngsteg/cli.rb",
24
+ "lib/pngsteg/extractor.rb",
25
+ "samples/flower.png",
26
+ "samples/flower_rgb1.png",
27
+ "samples/flower_rgb2.png",
28
+ "samples/flower_rgb3.png",
29
+ "samples/flower_rgb4.png",
30
+ "samples/flower_rgb5.png",
31
+ "samples/flower_rgb6.png",
32
+ "spec/samples_spec.rb",
33
+ "spec/spec_helper.rb"
34
+ ]
35
+ s.homepage = "http://github.com/zed-0xff/pngsteg"
36
+ s.licenses = ["MIT"]
37
+ s.require_paths = ["lib"]
38
+ s.rubygems_version = "1.8.24"
39
+ s.summary = "Detect stegano-hidden data in PNG files"
40
+
41
+ if s.respond_to? :specification_version then
42
+ s.specification_version = 3
43
+
44
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
+ s.add_runtime_dependency(%q<zpng>, [">= 0.2.1"])
46
+ s.add_development_dependency(%q<rspec>, [">= 2.8.0"])
47
+ s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
48
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
49
+ s.add_development_dependency(%q<awesome_print>, [">= 0"])
50
+ else
51
+ s.add_dependency(%q<zpng>, [">= 0.2.1"])
52
+ s.add_dependency(%q<rspec>, [">= 2.8.0"])
53
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
54
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
55
+ s.add_dependency(%q<awesome_print>, [">= 0"])
56
+ end
57
+ else
58
+ s.add_dependency(%q<zpng>, [">= 0.2.1"])
59
+ s.add_dependency(%q<rspec>, [">= 2.8.0"])
60
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
61
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
62
+ s.add_dependency(%q<awesome_print>, [">= 0"])
63
+ end
64
+ end
65
+
Binary file
Binary file
@@ -0,0 +1,4 @@
1
+ flower*.png - http://punkroy.drque.net/PNG_Steganography/Steganography3.php
2
+ cats.png - RuCTF2012 - steg400 - http://darkbyte.ru/2012/46/ructf-2012-quals-writeup-cats/
3
+ opensteg*.png - http://openstego.sourceforge.net/
4
+ Code.png - http://blog.secoverflow.org/gchq-can-you-crack-it-writeup/
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ each_sample("camouflage*.png") do |fname|
4
+ describe fname do
5
+ it "should detect Camouflage" do
6
+ cli(fname).should include("Camouflage")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe "cats.png" do
4
+ subject{ cli(sample("cats.png")) }
5
+
6
+ its(:size){ should < 4_000 }
7
+
8
+ it "should get 2nd cat" do
9
+ should include("Second cat is Marussia")
10
+ end
11
+
12
+ it "should get 3rd cat" do
13
+ should include("Hello, third kitten is Bessy")
14
+ end
15
+
16
+ it "should get 4th cat" do
17
+ should include("Fourth and last cat is Luke")
18
+ end
19
+
20
+ it "should get hint" do
21
+ should include("Good, but look a bit deeper...")
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ each_sample("flower_*.png") do |fname|
4
+ describe fname do
5
+ it "should reveal secret message" do
6
+ cli(
7
+ fname, "--limit", "64", "--bits", "1,2,3,4,5,6"
8
+ ).should include("SuperSecretMessage")
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ each_sample("openstego_*png") do |fname|
4
+ describe fname do
5
+ subject{ cli(fname) }
6
+
7
+ it { should include("OpenStego") }
8
+ end
9
+ end
10
+
11
+ # filenames of hidden files
12
+
13
+ describe "samples/openstego_q2.png" do
14
+ subject{ cli(sample("openstego_q2.png")) }
15
+ it { should include("flag.txt") }
16
+ end
17
+
18
+ describe "samples/openstego_send.png" do
19
+ subject{ cli(sample("openstego_send.png")) }
20
+ it { should include("secret.jpg") }
21
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe "samples/Code.png" do
4
+ subject{ cli(sample("Code.png")) }
5
+ it { should include("QkJCQjIAAACR2PFtcCA6q2eaC8SR+8dmD/zNzLQC+td3tFQ4qx8O447TDeuZw5P+0SsbEcYR\n78jKLw==".inspect) }
6
+ end
7
+
8
+ describe "samples/stg300.png" do
9
+ subject{ cli(sample("stg300.png")) }
10
+ it { should include("Congrats") }
11
+ it { should include("4E34B38257200616FB75CD869B8C3CF0") }
12
+ end
13
+
14
+ describe "samples/06_enc.png" do
15
+ subject{ cli(sample("06_enc.png")) }
16
+ it { should include("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod") }
17
+ end
18
+
19
+ describe "samples/montenach-enc.png" do
20
+ subject{ cli(sample("montenach-enc.png")) }
21
+ it { should include("48300:TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBp") }
22
+ end
@@ -0,0 +1,39 @@
1
+ $:.unshift(File.expand_path("../lib", File.dirname(__FILE__)))
2
+ require 'zsteg'
3
+ require 'zsteg/cli'
4
+
5
+ SAMPLES_DIR = File.expand_path("../samples", File.dirname(__FILE__))
6
+
7
+ def each_sample glob="*.png"
8
+ Dir[File.join(SAMPLES_DIR, glob)].each do |fname|
9
+ yield fname.sub(Dir.pwd+'/','')
10
+ end
11
+ end
12
+
13
+ def sample fname
14
+ File.join(SAMPLES_DIR, fname)
15
+ end
16
+
17
+ def cli *args
18
+ @@cli_cache ||= {}
19
+ @@cli_cache[args] ||=
20
+ begin
21
+ orig_stdout, out = $stdout, ""
22
+ begin
23
+ $stdout = StringIO.new(out)
24
+ ZSteg::CLI.new(args).run
25
+ ensure
26
+ $stdout = orig_stdout
27
+ end
28
+ out
29
+ end
30
+ end
31
+
32
+ RSpec.configure do |config|
33
+ config.before :suite do
34
+ Dir[File.join(SAMPLES_DIR, "*.7z")].each do |fname|
35
+ next if File.exist?(fname.sub(/\.7z$/,''))
36
+ system "7z", "x", fname, "-o#{SAMPLES_DIR}"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ each_sample("wbsteg*.bmp") do |fname|
4
+ describe fname do
5
+ subject{ cli(fname) }
6
+
7
+ it { should include("wbStego") }
8
+ it { should include("SuperSecretMessage") }
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe "samples/ndh2k12_sp113.bmp" do
4
+ subject{ cli(sample("ndh2k12_sp113.bmp"), "-o", "all") }
5
+ it { should include("%PDF-1.4") }
6
+ end
metadata ADDED
@@ -0,0 +1,198 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zsteg
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.0
6
+ platform: ruby
7
+ authors:
8
+ - Andrey "Zed" Zaikin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ prerelease: false
16
+ type: :runtime
17
+ name: zpng
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 0.2.1
23
+ none: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ! '>='
27
+ - !ruby/object:Gem::Version
28
+ version: 0.2.1
29
+ none: false
30
+ - !ruby/object:Gem::Dependency
31
+ prerelease: false
32
+ type: :runtime
33
+ name: awesome_print
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ none: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ none: false
46
+ - !ruby/object:Gem::Dependency
47
+ prerelease: false
48
+ type: :runtime
49
+ name: iostruct
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ none: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ none: false
62
+ - !ruby/object:Gem::Dependency
63
+ prerelease: false
64
+ type: :development
65
+ name: rspec
66
+ requirement: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: 2.8.0
71
+ none: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: 2.8.0
77
+ none: false
78
+ - !ruby/object:Gem::Dependency
79
+ prerelease: false
80
+ type: :development
81
+ name: bundler
82
+ requirement: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: 1.0.0
87
+ none: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: 1.0.0
93
+ none: false
94
+ - !ruby/object:Gem::Dependency
95
+ prerelease: false
96
+ type: :development
97
+ name: jeweler
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ~>
101
+ - !ruby/object:Gem::Version
102
+ version: 1.8.4
103
+ none: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ~>
107
+ - !ruby/object:Gem::Version
108
+ version: 1.8.4
109
+ none: false
110
+ description:
111
+ email: zed.0xff@gmail.com
112
+ executables:
113
+ - zsteg
114
+ extensions: []
115
+ extra_rdoc_files:
116
+ - README.md
117
+ - README.md.tpl
118
+ - TODO
119
+ files:
120
+ - Gemfile
121
+ - Gemfile.lock
122
+ - README.md
123
+ - README.md.tpl
124
+ - Rakefile
125
+ - TODO
126
+ - VERSION
127
+ - bin/zsteg
128
+ - cmp_bmp.rb
129
+ - cmp_png.rb
130
+ - lib/zsteg.rb
131
+ - lib/zsteg/checker.rb
132
+ - lib/zsteg/checker/wbstego.rb
133
+ - lib/zsteg/cli.rb
134
+ - lib/zsteg/extractor.rb
135
+ - lib/zsteg/extractor/byte_extractor.rb
136
+ - lib/zsteg/extractor/color_extractor.rb
137
+ - lib/zsteg/file_cmd.rb
138
+ - lib/zsteg/result.rb
139
+ - pngsteg.gemspec
140
+ - samples/06_enc.png
141
+ - samples/Code.png
142
+ - samples/README
143
+ - samples/camouflage-password.png
144
+ - samples/camouflage.png
145
+ - samples/cats.png
146
+ - samples/flower.png
147
+ - samples/flower_rgb1.png
148
+ - samples/flower_rgb2.png
149
+ - samples/flower_rgb3.png
150
+ - samples/flower_rgb4.png
151
+ - samples/flower_rgb5.png
152
+ - samples/flower_rgb6.png
153
+ - samples/montenach-enc.png
154
+ - samples/ndh2k12_sp113.bmp.7z
155
+ - samples/openstego_q2.png
156
+ - samples/openstego_send.png
157
+ - samples/stg300.png
158
+ - samples/wbsteg_noenc.bmp
159
+ - samples/wbsteg_noenc_17.bmp
160
+ - samples/wbsteg_noenc_even.bmp
161
+ - samples/wbsteg_noenc_even_17.bmp
162
+ - spec/camouflage_spec.rb
163
+ - spec/cats_spec.rb
164
+ - spec/flowers_spec.rb
165
+ - spec/openstego_spec.rb
166
+ - spec/simple_spec.rb
167
+ - spec/spec_helper.rb
168
+ - spec/wbstego_spec.rb
169
+ - spec/zlib_spec.rb
170
+ homepage: http://github.com/zed-0xff/zsteg
171
+ licenses:
172
+ - MIT
173
+ post_install_message:
174
+ rdoc_options: []
175
+ require_paths:
176
+ - lib
177
+ required_ruby_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ segments:
183
+ - 0
184
+ hash: 3565268342721586308
185
+ none: false
186
+ required_rubygems_version: !ruby/object:Gem::Requirement
187
+ requirements:
188
+ - - ! '>='
189
+ - !ruby/object:Gem::Version
190
+ version: '0'
191
+ none: false
192
+ requirements: []
193
+ rubyforge_project:
194
+ rubygems_version: 1.8.24
195
+ signing_key:
196
+ specification_version: 3
197
+ summary: Detect stegano-hidden data in PNG & BMP files.
198
+ test_files: []