Jump to content

Archived

This topic is now archived and is closed to further replies.

timmattison

New Ducky encoder implementation

Recommended Posts

Hey everyone, I recently implemented a Ducky encoder from scratch and wanted to share the results here. My motivation was originally just to have a project to play around with but after many, many commits I think that it is something that other people can probably use as well. Honestly, I didn't look to see if someone had already done something similar before I started since I wanted to do a completely clean implementation. After perusing the forums a bit I see someone else is maintaining and updating the original code in a new repo with some very interesting features that I haven't implemented yet.

What did I do? First, I made a version of my code that was completely compatible with the original encoder. I did this by extracting the scripts from the Wiki and adding tests to the Java code that would run the original encoder, capture the output, run my encoder, and then make sure they matched byte-for-byte.

Then I saw there were a few bugs in the original implementation so I fixed those:
- Incorporated Peter Janes' "GUI SPACE" fix
- Fixed issue where DEFAULT_DELAY values larger than 127 get thrown away
- Fixed a crash when lines are less than two characters long
- Added a REPEAT implementation
- CTRL and ALT characters don't seem to work properly on Macs (still working on this)

Then to add a bit more flexibility for the new encoder I touched up the scripts in the wiki that caused problems. Most of this was changing things like "CONTROL Z" to "CONTROL z". My code would generate a control code with an upper-case Z with the first string but the original code always treated control characters as lowercase. These changes wouldn't affect older encoder versions so that shouldn't be a problem. With the new version you can do "CONTROL Z" and "CONTROL z" and it'll generate CTRL-SHIFT-Z and CTRL-Z respectively.

I cleaned up some minor Wiki code formatting junk too but that's not that exciting.

The real benefit to the new code is that it is more modular than the original code so adding new functionality and commands should be easy. For example I have included the following new features:
- REPEAT instruction (although this is in the original version now as well)
- The ability to create strings like "CTRL ALT SHIFT x" to generate more complex keypresses. You can even do "LEFTALT RIGHTCTRL GUI F11" if you want. The code makes sure you don't do two keypresses that collide too. I need to test this more but so far it appears to work well.
- Improved REPEAT instruction that lets you do something like "REPEAT 5 4" which will make 5 copies of the last 4 instructions
- Added support for pre-processors that can convert legacy or new syntax into other commands. For example, one translates DEFAULTDELAY to DEFAULT_DELAY. Another one translates “CTRL-SHIFT” to “CONTROL SHIFT". This helps keep the processing code focused on just implementing the key press instructions and moves some stuff that can end up cluttering the code out to where it isn’t distracting.
- Maven support for building and testing

If anyone is interested the code is on github. I'd really like feedback and feature requests. Feel free to use this thread and the issue tracker there to contribute.

Thoughts?

Share this post


Link to post
Share on other sites

Hi,

Can you post the URL here? I don't know your github details and you haven't provided a link.

Cheers,

MB60893

Share this post


Link to post
Share on other sites

Hi,

Sorry it took me so long to reply. I love what you have done with this, and you have obviously given it a lot of thought. I have just written a simple script and I find that it has worked quite well. I will have to look into the things you've added, like the REPEAT function.

Great Job!

MB60893.

Share this post


Link to post
Share on other sites

Hi,

Sorry it took me so long to reply. I love what you have done with this, and you have obviously given it a lot of thought. I have just written a simple script and I find that it has worked quite well. I will have to look into the things you've added, like the REPEAT function.

Great Job!

MB60893.

Thank you so much! If you have feature requests or bug reports please let me know on Github!

Share this post


Link to post
Share on other sites

I really liked the concept of that repeat feature and could use it for some of my payloads I am working on. My current request though is for some basic instructions. I have cloned via git into a dir and get the general concept but have no idea how to use your encoder. Right now with the current encoder which is just a .jar it is very easy to run. If you could make it that easy or give some instructions for us n00b's that would be great.

Share this post


Link to post
Share on other sites

Thanks for the feedback. I've updated the README to indicate what you need to do to get started but here's the gist.

First, run "mvn clean package" to create the JAR file.

Then, run "java -jar target/Encoder-1.0-SNAPSHOT-jar-with-dependencies.jar" and it will tell you what the command-line options are. After that you can just append those options to this command.

Let me know if that works for you and if you find any bugs!

I really liked the concept of that repeat feature and could use it for some my payloads I am working on. My current request though is for some basic instructions. I have cloned via git into a dir and get the general concept but have no idea how to use your encoder. Right now with the current encoder which is just a .jar it is very easy to run. If you could make it that easy or give some instructions for us n00b's that would be great.

Share this post


Link to post
Share on other sites

Hey Thanks for the quick response! I am impressed. I needed to install maven to get this going but that was pretty easy.

The enhanced repeat option you have is the most important thing to me. I am probably one of the few people who is actually experimenting with the use of the usb ducky in a Android QA environment. I see automated testing opportunities with little overhead. This is why the ability to repeat is valuable to me.

Thanks again!

Share this post


Link to post
Share on other sites

Yup this is working great. This next request would be much more difficult in my opinion but... how about a way to repeat commands based on line number or some sort of reference... I know we must have some limit in this as eventually we are getting into creating functions and referencing variables which I know Ducky Script was never meant to do. But I am interested in your thoughts on the idea of expanding REPEAT to the next level for larger payloads.

Thnx dude and have a Merry Christmas!

Share this post


Link to post
Share on other sites

If you're interested there is a branch called "multi-statement-repeat" on the repo. It implements multiple statement repeat but I'm having some trouble getting one of the tests to pass. Would you try it out?

The syntax to repeat multiple statements should be:

REPEAT 2 4

Where "2" means repeat twice and "4" means repeat the last four statements. So you would expect something like this:

STRING Hello, world
DELAY 500
STRING Time to repeat
DELAY 500
REPEAT 2 4

To print out:

Hello, world
Time to repeat
Hello, world
Time to repeat
Hello, world
Time to repeat

The first copy of "Hello, world, Time to Repeat" is from the original commands. The next two are the repeat.

My Ducky is at home and I can't test it right now.

Share this post


Link to post
Share on other sites

If I have the REPEAT 3 3 option enabled or utilize the new REPEAT style it appears to bomb during encoding....

java -jar target/Encoder-1.0-SNAPSHOT-jar-with-dependencies.jar -input test -output inject.bin
Exception in thread "main" com.timmattison.hacking.usbrubberducky.exceptions.NoParserFoundForStringException
at com.timmattison.hacking.usbrubberducky.StandardRubberDuckyEncoder.encode(StandardRubberDuckyEncoder.java:56)
at com.timmattison.hacking.usbrubberducky.RubberDuckyEncoderApplication.main(RubberDuckyEncoderApplication.java:47)

Share this post


Link to post
Share on other sites

I tried this script:

STRING Hi
STRING 1,2,3
STRING OMG
REPEAT 3 3

With mine and it did generate a binary file. Did you do a "mvn clean package" after you pulled the latest code?

Share this post


Link to post
Share on other sites

Interesting.... I did. I can get it to work fine without the second number. Now I am not using STRING's... is this specific to strings? This is for a droid so here is my test payload.

REM Test repeat
DELAY 500
ESC
DELAY 500
CONTROL ESCAPE
DELAY 500
ESC
DELAY 500
DELAY 1000
STRING ~
DELAY 1000
DOWN
DOWN
LEFT
ENTER
DELAY 1000
STRING vz test
DELAY 500
DOWN
ENTER
STRING Starting SMS/MMS Test.
ENTER
STRING Char Count 141 
ENTER
DELAY 1000
STRING GixUp0N6mBZj7Q7uWN1G0Vec6XpJl@L2Y0AxQ7150ks9U3Uo3vz5lMdIL7M3R5gEuY7lT79@x5m7OR33Yy8xi4Vr2C190om6icZSSOsH5s2lfV9cAKFH35C0g3i8t21ag6t4AdFuxH61
ENTER
DELAY 1000
REPEAT 3 3
ESC
REPEAT 3

Share this post


Link to post
Share on other sites

Found something else strange. I can't encode a payload that contains BACKSPACE. Is this known? DELETE appears to work but of course it deletes in the way the DEL key deletes.

Made a payload with just BACKSPACE in it and tried to encode....

java -jar target/Encoder-1.0-SNAPSHOT-jar-with-dependencies.jar -input backspace -output inject.bin
Exception in thread "main" com.timmattison.hacking.usbrubberducky.exceptions.NoParserFoundForStringException
at com.timmattison.hacking.usbrubberducky.StandardRubberDuckyEncoder.encode(StandardRubberDuckyEncoder.java:56)
at com.timmattison.hacking.usbrubberducky.RubberDuckyEncoderApplication.main(RubberDuckyEncoderApplication.java:47)
Out of curiosity I made a payload with STRING blah and then REPEAT 1 1. So just two lines. Got the same error.
java -jar target/Encoder-1.0-SNAPSHOT-jar-with-dependencies.jar -input blah -output inject.bin
Exception in thread "main" com.timmattison.hacking.usbrubberducky.exceptions.NoParserFoundForStringException
at com.timmattison.hacking.usbrubberducky.StandardRubberDuckyEncoder.encode(StandardRubberDuckyEncoder.java:56)
at com.timmattison.hacking.usbrubberducky.RubberDuckyEncoderApplication.main(RubberDuckyEncoderApplication.java:47)

Share this post


Link to post
Share on other sites

OK, so here's what has happened so far today...

I checked and the "BACKSPACE" command is not implemented. It appears to not be implemented in the original encoder either. Does it work for you in any of the old versions or any of the forks? If there is a fork where it works let me know and I'll see if I can implement that quickly too. I've created a ticket for it so I won't forget https://github.com/timmattison/USB-Rubber-Ducky/issues/20

It seems strange that you're getting a NoParserFoundForStringException. This could be because you're on the wrong branch or using an old JAR. I've updated the master branch and my multi-statement-repeat branch to have two specific features to make this easier to debug. First, the application now prints out the githash that it was built from. So you'll see something like this:

Rubber Ducky Encoder Application - githash: 9f79d891760ad92bdb389159869f75d11790ff8f

Each time you run the application. If you run into a string that doesn't parse you should see something like this:

Rubber Ducky Encoder Application - githash: 9f79d891760ad92bdb389159869f75d11790ff8f
This line could not be parsed: BACKSPACE

com.timmattison.hacking.usbrubberducky.exceptions.NoParserFoundForStringException
	at com.timmattison.hacking.usbrubberducky.StandardRubberDuckyEncoder.encode(StandardRubberDuckyEncoder.java:56)
	at com.timmattison.hacking.usbrubberducky.RubberDuckyEncoderApplication.main(RubberDuckyEncoderApplication.java:51)

Whenever you are reporting an issue be sure to include this information. I then took your input from above and manually converted it to this:

REM Test repeat
DELAY 500
ESC
DELAY 500
CONTROL ESCAPE
DELAY 500
ESC
DELAY 500
DELAY 1000
STRING ~
DELAY 1000
DOWN
DOWN
LEFT
ENTER
DELAY 1000
STRING vz test
DELAY 500
DOWN
ENTER
STRING Starting SMS/MMS Test.
ENTER
STRING Char Count 141 
ENTER
DELAY 1000
STRING GixUp0N6mBZj7Q7uWN1G0Vec6XpJl@L2Y0AxQ7150ks9U3Uo3vz5lMdIL7M3R5gEuY7lT79@x5m7OR33Yy8xi4Vr2C190om6icZSSOsH5s2lfV9cAKFH35C0g3i8t21ag6t4AdFuxH61
ENTER
DELAY 1000
STRING GixUp0N6mBZj7Q7uWN1G0Vec6XpJl@L2Y0AxQ7150ks9U3Uo3vz5lMdIL7M3R5gEuY7lT79@x5m7OR33Yy8xi4Vr2C190om6icZSSOsH5s2lfV9cAKFH35C0g3i8t21ag6t4AdFuxH61
ENTER
DELAY 1000
STRING GixUp0N6mBZj7Q7uWN1G0Vec6XpJl@L2Y0AxQ7150ks9U3Uo3vz5lMdIL7M3R5gEuY7lT79@x5m7OR33Yy8xi4Vr2C190om6icZSSOsH5s2lfV9cAKFH35C0g3i8t21ag6t4AdFuxH61
ENTER
DELAY 1000
STRING GixUp0N6mBZj7Q7uWN1G0Vec6XpJl@L2Y0AxQ7150ks9U3Uo3vz5lMdIL7M3R5gEuY7lT79@x5m7OR33Yy8xi4Vr2C190om6icZSSOsH5s2lfV9cAKFH35C0g3i8t21ag6t4AdFuxH61
ENTER
DELAY 1000
ESC
ESC
ESC
ESC

And then I compared the output against what the encoder produces for your input vs mine and they came out as identical bit strings on the multi-statement-repeat repeat branch.

I would suggest pulling the latest multi-statement-repeat branch, rebuilding, and trying to run it again. If it doesn't work then post the new results with the additional information generated in the thread.

Again, thanks for testing!

Share this post


Link to post
Share on other sites

Thanks for the reply. As for BACKSPACE I actually saw it in someone else's payload here on the forum's and assumed it was allowed in the original encoder.

https://forums.hak5.org/index.php?/topic/28636-payload-sharing-some-payloads/

---

As for the repeat... I have no idea what I am missing.

I did an git pull then re-ran mvn clean package

--

I now see the new feature you added so it clearly states REPEAT 3 3 is failing.

Rubber Ducky Encoder Application - githash: 8d576591b62ff7a1713be01f43dda180477d9425
This line could not be parsed: REPEAT 3 3
com.timmattison.hacking.usbrubberducky.exceptions.NoParserFoundForStringException
at com.timmattison.hacking.usbrubberducky.StandardRubberDuckyEncoder.encode(StandardRubberDuckyEncoder.java:56)
at com.timmattison.hacking.usbrubberducky.RubberDuckyEncoderApplication.main(RubberDuckyEncoderApplication.java:51)
---
So in frustration i completely deleted the directory and re-downloaded it
still failed
--
java -jar target/Encoder-1.0-SNAPSHOT-jar-with-dependencies.jar -input test -output inject.bin <--- this is the command I am using. Is this wrong in some way? I run this from the USB-Rubber-Ducky dir.
Thnx dude

Share this post


Link to post
Share on other sites

Nope, your command is right. From the output I can see that you were on the master branch and not the multi-statement-repeat branch. I've merged multi-statement-repeat into master. Try pulling again and try it again. Everything else looks right.

Share this post


Link to post
Share on other sites

That was it. Awesome. I will now incorporate this into some of my payloads I am using and let you know how that goes.

Share this post


Link to post
Share on other sites

Dude that is not a big deal... it aint like your getting paid. :) I am just happy to work with someone interested in expanding the usefulness of the ducky. I see lots of potential.

Share this post


Link to post
Share on other sites

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...