zsteg 0.0.0 → 0.0.1
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.
- data/Gemfile +2 -7
- data/Gemfile.lock +2 -4
- data/README.md +72 -1
- data/README.md.tpl +23 -0
- data/Rakefile +5 -3
- data/TODO +5 -2
- data/VERSION +1 -1
- data/bin/zsteg-mask +7 -0
- data/lib/zsteg/checker/wbstego.rb +69 -14
- data/lib/zsteg/checker.rb +137 -34
- data/lib/zsteg/cli.rb +92 -35
- data/lib/zsteg/extractor/byte_extractor.rb +36 -21
- data/lib/zsteg/extractor/color_extractor.rb +68 -34
- data/lib/zsteg/extractor.rb +36 -1
- data/lib/zsteg/file_cmd.rb +64 -1
- data/lib/zsteg/mask_cli.rb +268 -0
- data/lib/zsteg/masker.rb +52 -0
- data/lib/zsteg/result.rb +27 -32
- data/lib/zsteg.rb +2 -0
- data/samples/hackquest/crypt.bmp +0 -0
- data/samples/hackquest/square.bmp +0 -0
- data/samples/wbstego/wbsteg_blowfish_pass_1.bmp +0 -0
- data/samples/wbstego/wbsteg_cast128_pass_1.bmp +0 -0
- data/samples/wbstego/wbsteg_enc_pass_pass.bmp +0 -0
- data/samples/wbstego/wbsteg_enc_pass_pass_even.bmp +0 -0
- data/samples/wbstego/wbsteg_mix_pass_1.bmp +0 -0
- data/samples/wbstego/wbsteg_mix_pass_1_even.bmp +0 -0
- data/samples/wbstego/wbsteg_mix_pass_foobar.bmp +0 -0
- data/samples/wbstego/wbsteg_mix_pass_pass.bmp +0 -0
- data/samples/wbstego/wbsteg_mixenc_pass_pass_even.bmp +0 -0
- data/samples/{wbsteg_noenc.bmp → wbstego/wbsteg_noenc.bmp} +0 -0
- data/samples/wbstego/wbsteg_noenc.png +0 -0
- data/samples/wbstego/wbsteg_noenc_.bmp +0 -0
- data/samples/{wbsteg_noenc_17.bmp → wbstego/wbsteg_noenc_17.bmp} +0 -0
- data/samples/wbstego/wbsteg_noenc__.bmp +0 -0
- data/samples/{wbsteg_noenc_even.bmp → wbstego/wbsteg_noenc_even.bmp} +0 -0
- data/samples/wbstego/wbsteg_noenc_even2.bmp +0 -0
- data/samples/{wbsteg_noenc_even_17.bmp → wbstego/wbsteg_noenc_even_17.bmp} +0 -0
- data/samples/wbstego/wbsteg_noenc_even_17_.bmp +0 -0
- data/samples/wbstego/wbsteg_noenc_ext_ABC.bmp +0 -0
- data/samples/wbstego/wbsteg_rijndael_pass_1.bmp +0 -0
- data/samples/wbstego/wbsteg_rijndael_pass_pass.bmp +0 -0
- data/samples/wbstego/wbsteg_rijndael_pass_pass_even.bmp +0 -0
- data/samples/wbstego/wbsteg_twofish_pass_1.bmp +0 -0
- data/samples/wechall/5ZMGcCLxpcpsru03.g00000010.png +0 -0
- data/samples/wechall/5ZMGcCLxpcpsru03.png +0 -0
- data/samples/wechall/stegano1.bmp +0 -0
- data/spec/checker_spec.rb +47 -0
- data/spec/easybmp_spec.rb +9 -0
- data/spec/hackquest_spec.rb +18 -0
- data/spec/mask_spec.rb +14 -0
- data/spec/polictf2012_spec.rb +48 -0
- data/spec/prime_spec.rb +9 -0
- data/spec/r3g2b3_spec.rb +9 -0
- data/spec/spec_helper.rb +21 -4
- data/spec/wbstego_spec.rb +21 -3
- data/spec/wechall_spec.rb +26 -0
- data/tmp/.keep +0 -0
- data/zsteg.gemspec +121 -0
- metadata +47 -43
- data/samples/06_enc.png +0 -0
- data/samples/Code.png +0 -0
- data/samples/README +0 -4
- data/samples/camouflage-password.png +0 -0
- data/samples/camouflage.png +0 -0
- data/samples/cats.png +0 -0
- data/samples/flower.png +0 -0
- data/samples/flower_rgb1.png +0 -0
- data/samples/flower_rgb2.png +0 -0
- data/samples/flower_rgb3.png +0 -0
- data/samples/flower_rgb4.png +0 -0
- data/samples/flower_rgb5.png +0 -0
- data/samples/flower_rgb6.png +0 -0
- data/samples/montenach-enc.png +0 -0
- data/samples/ndh2k12_sp113.bmp.7z +0 -0
- data/samples/openstego_q2.png +0 -0
- data/samples/openstego_send.png +0 -0
- data/samples/stg300.png +0 -0
data/lib/zsteg.rb
CHANGED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
File without changes
|
Binary file
|
Binary file
|
File without changes
|
Binary file
|
File without changes
|
Binary file
|
File without changes
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
include ZSteg
|
4
|
+
|
5
|
+
describe Checker do
|
6
|
+
each_sample do |fname|
|
7
|
+
describe fname do
|
8
|
+
describe "#check" do
|
9
|
+
before :all do
|
10
|
+
@checker = Checker.new(fname)
|
11
|
+
orig_stdout, @out = $stdout, ""
|
12
|
+
begin
|
13
|
+
$stdout = StringIO.new(@out)
|
14
|
+
@results = @checker.check
|
15
|
+
ensure
|
16
|
+
$stdout = orig_stdout
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should be quiet by default" do
|
21
|
+
@out.should == ""
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returned results should be equal to #results" do
|
25
|
+
@results.should == @checker.results
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return array of results" do
|
29
|
+
@results.should be_instance_of(Array)
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "results" do
|
33
|
+
it "should not have text results shorter than #{Checker::MIN_TEXT_LENGTH}" do
|
34
|
+
@results.each do |result|
|
35
|
+
case result
|
36
|
+
when Result::WholeText
|
37
|
+
result.text.size.should(be >= Checker::MIN_WHOLETEXT_LENGTH, result.inspect)
|
38
|
+
when Result::Text
|
39
|
+
result.text.size.should(be >= Checker::MIN_TEXT_LENGTH, result.inspect)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
sample("hackquest/square.bmp") do |fname|
|
4
|
+
describe fname do
|
5
|
+
subject{ cli(fname, "-b 10") }
|
6
|
+
|
7
|
+
it { should include "thesecretpasswordis:jedimaster" }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
sample("hackquest/crypt.bmp") do |fname|
|
12
|
+
describe fname do
|
13
|
+
subject{ cli(fname, "-b 10") }
|
14
|
+
|
15
|
+
it { should include "111Hello" }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
data/spec/mask_spec.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
sample("Steganography_original.png") do |fname|
|
4
|
+
describe fname do
|
5
|
+
it "extracts hidden image" do
|
6
|
+
tname = "tmp/mask.tmp.png"
|
7
|
+
File.unlink(tname) if File.exist?(tname)
|
8
|
+
cli(ZSteg::MaskCLI, fname, "-m 00000011 -O #{tname}")
|
9
|
+
img1 = ZPNG::Image.load tname
|
10
|
+
img2 = ZPNG::Image.load fname.sub(/\.png$/,".00000011.png")
|
11
|
+
img1.should == img2
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
sample('polictf2012_f200.bmp') do |fname|
|
4
|
+
describe fname do
|
5
|
+
it "should detect hidden BMP" do
|
6
|
+
cli(fname).should include("PC bitmap, Windows 3.x format, 500 x 277 x 24")
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "hidden BMP #1" do
|
10
|
+
subject(:data){ cli(fname, "--extract", "4b,lsb,bY") }
|
11
|
+
its(:size){ should == 416816 }
|
12
|
+
|
13
|
+
it "should have BMP header" do
|
14
|
+
data[0,2].should == "BM"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should have 7zip after BMP" do
|
18
|
+
data.index("7z").should == 2005
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "deeper" do
|
22
|
+
let(:tname){ File.join("tmp", File.basename(fname) + ".bmp") }
|
23
|
+
before(:all){ File.open(tname, "wb"){ |f| f<<data } }
|
24
|
+
|
25
|
+
it "should detect 7z & BMP" do
|
26
|
+
out = cli(tname)
|
27
|
+
out.should include('7-zip archive')
|
28
|
+
out.should include('PC bitmap, Windows 3.x format, 100 x 55 x 24')
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "hidden BMP #2" do
|
32
|
+
subject(:data2){ cli(tname, "--extract", "2b,lsb,bY") }
|
33
|
+
its(:size){ should == 103875 }
|
34
|
+
|
35
|
+
describe "deeper" do
|
36
|
+
let(:tname2){ File.join("tmp", File.basename(tname) + ".bmp") }
|
37
|
+
before(:all){ File.open(tname2, "wb"){ |f| f<<data2 } }
|
38
|
+
|
39
|
+
it "should detect text" do
|
40
|
+
out = cli(tname2)
|
41
|
+
out.should include('sticazziantanieancoraunavoltacomesefossestato')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/spec/prime_spec.rb
ADDED
data/spec/r3g2b3_spec.rb
ADDED
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
$:.unshift(File.expand_path("../lib", File.dirname(__FILE__)))
|
2
2
|
require 'zsteg'
|
3
3
|
require 'zsteg/cli'
|
4
|
+
require 'zsteg/mask_cli'
|
4
5
|
|
5
6
|
SAMPLES_DIR = File.expand_path("../samples", File.dirname(__FILE__))
|
6
7
|
|
@@ -11,21 +12,37 @@ def each_sample glob="*.png"
|
|
11
12
|
end
|
12
13
|
|
13
14
|
def sample fname
|
14
|
-
File.join(SAMPLES_DIR, fname)
|
15
|
+
fname = File.join(SAMPLES_DIR, fname)
|
16
|
+
if block_given?
|
17
|
+
yield fname.sub(Dir.pwd+'/','')
|
18
|
+
end
|
19
|
+
|
20
|
+
fname
|
15
21
|
end
|
16
22
|
|
17
23
|
def cli *args
|
18
24
|
@@cli_cache ||= {}
|
19
|
-
|
25
|
+
args.map! do |arg|
|
26
|
+
if arg.is_a?(String) && arg[' ']
|
27
|
+
# split strings with spaces into arrays
|
28
|
+
arg.split(' ')
|
29
|
+
else
|
30
|
+
arg
|
31
|
+
end
|
32
|
+
end
|
33
|
+
args.flatten!
|
34
|
+
@@cli_cache[args.inspect] ||=
|
20
35
|
begin
|
36
|
+
klass = args.first.is_a?(Class) ? args.shift : ZSteg::CLI
|
37
|
+
args << "--no-color" unless args.any?{|x| x['color']}
|
21
38
|
orig_stdout, out = $stdout, ""
|
22
39
|
begin
|
23
40
|
$stdout = StringIO.new(out)
|
24
|
-
|
41
|
+
klass.new(args).run
|
25
42
|
ensure
|
26
43
|
$stdout = orig_stdout
|
27
44
|
end
|
28
|
-
out
|
45
|
+
out.strip
|
29
46
|
end
|
30
47
|
end
|
31
48
|
|
data/spec/wbstego_spec.rb
CHANGED
@@ -1,10 +1,28 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
each_sample("
|
3
|
+
each_sample("wbstego/*") do |fname|
|
4
4
|
describe fname do
|
5
|
-
subject{
|
5
|
+
subject{
|
6
|
+
if fname['.png']
|
7
|
+
cli(fname, "1b,lsb", "-o", "all")
|
8
|
+
else
|
9
|
+
cli(fname, "1b,lsb")
|
10
|
+
end
|
11
|
+
}
|
6
12
|
|
7
13
|
it { should include("wbStego") }
|
8
|
-
it { should include("SuperSecretMessage") }
|
14
|
+
it { should include("SuperSecretMessage") } if fname['noenc']
|
15
|
+
if fname['even']
|
16
|
+
it { should include("even=true") }
|
17
|
+
else
|
18
|
+
it { should include("even=false") }
|
19
|
+
end
|
20
|
+
|
21
|
+
%w'blowfish twofish cast128 rijndael'.each do |enc|
|
22
|
+
it { should match(/#{enc}/i) } if fname[enc]
|
23
|
+
end
|
24
|
+
|
25
|
+
it { should include("mix=true") } if fname['mix']
|
26
|
+
it { should include("enc=\"wbSteg") } if fname['enc'] && !fname['noenc']
|
9
27
|
end
|
10
28
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
WECHALL = {
|
4
|
+
'stegano1.bmp' => "Look what the hex-edit revealed: passwd:steganoI"
|
5
|
+
}
|
6
|
+
|
7
|
+
each_sample("wechall/*.bmp") do |fname|
|
8
|
+
describe fname do
|
9
|
+
subject{ cli(fname) }
|
10
|
+
|
11
|
+
it { should include WECHALL[File.basename(fname)] }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
sample("wechall/5ZMGcCLxpcpsru03.png") do |fname|
|
16
|
+
describe fname do
|
17
|
+
it "extracts hidden image" do
|
18
|
+
tname = "tmp/wechall.tmp.png"
|
19
|
+
File.unlink(tname) if File.exist?(tname)
|
20
|
+
cli(ZSteg::MaskCLI, fname, "--green 00000010 -O #{tname}")
|
21
|
+
img1 = ZPNG::Image.load tname
|
22
|
+
img2 = ZPNG::Image.load fname.sub(/\.png$/,".g00000010.png")
|
23
|
+
img1.should == img2
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/tmp/.keep
ADDED
File without changes
|
data/zsteg.gemspec
ADDED
@@ -0,0 +1,121 @@
|
|
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 = "zsteg"
|
8
|
+
s.version = "0.0.1"
|
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-15"
|
13
|
+
s.email = "zed.0xff@gmail.com"
|
14
|
+
s.executables = ["zsteg", "zsteg-mask"]
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.md",
|
17
|
+
"README.md.tpl",
|
18
|
+
"TODO"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"README.md",
|
24
|
+
"README.md.tpl",
|
25
|
+
"Rakefile",
|
26
|
+
"TODO",
|
27
|
+
"VERSION",
|
28
|
+
"bin/zsteg",
|
29
|
+
"bin/zsteg-mask",
|
30
|
+
"cmp_bmp.rb",
|
31
|
+
"cmp_png.rb",
|
32
|
+
"lib/zsteg.rb",
|
33
|
+
"lib/zsteg/checker.rb",
|
34
|
+
"lib/zsteg/checker/wbstego.rb",
|
35
|
+
"lib/zsteg/cli.rb",
|
36
|
+
"lib/zsteg/extractor.rb",
|
37
|
+
"lib/zsteg/extractor/byte_extractor.rb",
|
38
|
+
"lib/zsteg/extractor/color_extractor.rb",
|
39
|
+
"lib/zsteg/file_cmd.rb",
|
40
|
+
"lib/zsteg/mask_cli.rb",
|
41
|
+
"lib/zsteg/masker.rb",
|
42
|
+
"lib/zsteg/result.rb",
|
43
|
+
"pngsteg.gemspec",
|
44
|
+
"samples/hackquest/crypt.bmp",
|
45
|
+
"samples/hackquest/square.bmp",
|
46
|
+
"samples/wbstego/wbsteg_blowfish_pass_1.bmp",
|
47
|
+
"samples/wbstego/wbsteg_cast128_pass_1.bmp",
|
48
|
+
"samples/wbstego/wbsteg_enc_pass_pass.bmp",
|
49
|
+
"samples/wbstego/wbsteg_enc_pass_pass_even.bmp",
|
50
|
+
"samples/wbstego/wbsteg_mix_pass_1.bmp",
|
51
|
+
"samples/wbstego/wbsteg_mix_pass_1_even.bmp",
|
52
|
+
"samples/wbstego/wbsteg_mix_pass_foobar.bmp",
|
53
|
+
"samples/wbstego/wbsteg_mix_pass_pass.bmp",
|
54
|
+
"samples/wbstego/wbsteg_mixenc_pass_pass_even.bmp",
|
55
|
+
"samples/wbstego/wbsteg_noenc.bmp",
|
56
|
+
"samples/wbstego/wbsteg_noenc.png",
|
57
|
+
"samples/wbstego/wbsteg_noenc_.bmp",
|
58
|
+
"samples/wbstego/wbsteg_noenc_17.bmp",
|
59
|
+
"samples/wbstego/wbsteg_noenc__.bmp",
|
60
|
+
"samples/wbstego/wbsteg_noenc_even.bmp",
|
61
|
+
"samples/wbstego/wbsteg_noenc_even2.bmp",
|
62
|
+
"samples/wbstego/wbsteg_noenc_even_17.bmp",
|
63
|
+
"samples/wbstego/wbsteg_noenc_even_17_.bmp",
|
64
|
+
"samples/wbstego/wbsteg_noenc_ext_ABC.bmp",
|
65
|
+
"samples/wbstego/wbsteg_rijndael_pass_1.bmp",
|
66
|
+
"samples/wbstego/wbsteg_rijndael_pass_pass.bmp",
|
67
|
+
"samples/wbstego/wbsteg_rijndael_pass_pass_even.bmp",
|
68
|
+
"samples/wbstego/wbsteg_twofish_pass_1.bmp",
|
69
|
+
"samples/wechall/5ZMGcCLxpcpsru03.g00000010.png",
|
70
|
+
"samples/wechall/5ZMGcCLxpcpsru03.png",
|
71
|
+
"samples/wechall/stegano1.bmp",
|
72
|
+
"spec/camouflage_spec.rb",
|
73
|
+
"spec/cats_spec.rb",
|
74
|
+
"spec/checker_spec.rb",
|
75
|
+
"spec/easybmp_spec.rb",
|
76
|
+
"spec/flowers_spec.rb",
|
77
|
+
"spec/hackquest_spec.rb",
|
78
|
+
"spec/mask_spec.rb",
|
79
|
+
"spec/openstego_spec.rb",
|
80
|
+
"spec/polictf2012_spec.rb",
|
81
|
+
"spec/prime_spec.rb",
|
82
|
+
"spec/r3g2b3_spec.rb",
|
83
|
+
"spec/simple_spec.rb",
|
84
|
+
"spec/spec_helper.rb",
|
85
|
+
"spec/wbstego_spec.rb",
|
86
|
+
"spec/wechall_spec.rb",
|
87
|
+
"spec/zlib_spec.rb",
|
88
|
+
"tmp/.keep",
|
89
|
+
"zsteg.gemspec"
|
90
|
+
]
|
91
|
+
s.homepage = "http://github.com/zed-0xff/zsteg"
|
92
|
+
s.licenses = ["MIT"]
|
93
|
+
s.require_paths = ["lib"]
|
94
|
+
s.rubygems_version = "1.8.24"
|
95
|
+
s.summary = "Detect stegano-hidden data in PNG & BMP files."
|
96
|
+
|
97
|
+
if s.respond_to? :specification_version then
|
98
|
+
s.specification_version = 3
|
99
|
+
|
100
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
101
|
+
s.add_runtime_dependency(%q<zpng>, [">= 0.2.2"])
|
102
|
+
s.add_runtime_dependency(%q<iostruct>, [">= 0"])
|
103
|
+
s.add_development_dependency(%q<rspec>, [">= 2.8.0"])
|
104
|
+
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
105
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
106
|
+
else
|
107
|
+
s.add_dependency(%q<zpng>, [">= 0.2.2"])
|
108
|
+
s.add_dependency(%q<iostruct>, [">= 0"])
|
109
|
+
s.add_dependency(%q<rspec>, [">= 2.8.0"])
|
110
|
+
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
111
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
112
|
+
end
|
113
|
+
else
|
114
|
+
s.add_dependency(%q<zpng>, [">= 0.2.2"])
|
115
|
+
s.add_dependency(%q<iostruct>, [">= 0"])
|
116
|
+
s.add_dependency(%q<rspec>, [">= 2.8.0"])
|
117
|
+
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
118
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|