juanchoc Posted August 17, 2013 Share Posted August 17, 2013 Hi everyone, I'm trying my ducky on a Macbook Pro, and my initial intention was to use it with the composite firmware (to execute the payload while im "looking for a pdf in my pendrive" basically), but i've found some issues along the way. If i set the VID/PID to the internal keyboard ones (using a non-composite firmware), it works as expected. If i put the VID/PID of another keyboard, the OS asks me to press a few keys in the new keyboad to confirm it's "allowed" to work. If i use the composite firmware (using one of the composite VID/PID) it detects the storage device correctly, and the keyboard correctly, but it shows me the same window requesting me to do a few specific keypresess to confirm the new keyboard is secure. One way to solve this would be to add to my ducky script the initial keypresses required by the OSX keyboard validation screen. But also while thinking about it, i came across another idea. Would it be possible to change the VID/PID while the ducky is connected (maybe forcing a disconect/reset so that the host detects the device again, but this time with another VID/PID set)? One possible use case would be to connect the ducky, it first acts as trusted host keyboard (ie. the internal macbook pro keyboard in my case), executes the payload, and afterwards, triggered by something (the ducky's button? or maybe the end of the script execution?), it swaps the vidpid.bin (ie. with another one that has the vid/pid of a storage device) and forces a reset on the usb device. Do you think doing something like that would be possible? Quote Link to comment Share on other sites More sharing options...
no42 Posted August 17, 2013 Share Posted August 17, 2013 You only need to complete the keyboard wizard once per machine, so I guess it depends where you are using the device? Have you tried the specifically the VID/PID of a Mac keyboard when in composite mode? I think it is possible to reset the Ducky. You would have to look at the C++-Code (Firmware), and code a reset procedure, that will reset the Ducky's USB stack, given a certain signal (eg the GPIO button). Quote Link to comment Share on other sites More sharing options...
juanchoc Posted August 17, 2013 Author Share Posted August 17, 2013 Hi midnitesnake! Thanks for the fast response! I've tried using the VID/PID of the internal mac keyboard (and also some of the external mac keyboards) in composite mode, but it didnt recognize the keyboard at all, just the storage drive. That was a bit odd, because i was expecting it to recognize only the keyboard (since that is the VID/PID i was using) and not the other way around. Anyway, thanks for the info, i'll look into the firmware code and post back my results! Quote Link to comment Share on other sites More sharing options...
overwraith Posted August 18, 2013 Share Posted August 18, 2013 There is a function in udc.c called usd_reset(), This may be what you are looking for. Am interested in this idea, so am poking around. /** * \brief Reset the current configuration of the USB device, * This routines can be called by UDD when a RESET on the USB line occurs. */ void udc_reset(void) The following code controls the push button, am not quite sure what debounce does yet. if( gpio_get_pin_value(GPIO_JOYSTICK_PUSH) == GPIO_JOYSTICK_PUSH_PRESSED ) { // debounce if( debounce == 0 ) { state = state_START_INJECT; debounce = 250; } } Quote Link to comment Share on other sites More sharing options...
no42 Posted August 19, 2013 Share Posted August 19, 2013 Then you use an electronic switch the signal maybe 111111111111, when you only pushed the button once not X-times, "debounce" eliminates the extra false positive signals, so the code is only execute once instead of many. Quote Link to comment Share on other sites More sharing options...
juanchoc Posted August 19, 2013 Author Share Posted August 19, 2013 (edited) Thanks overwraith! I've been looking into the different firmwares, and the avr drivers/framework. From what i've seen, it seems the udc_reset(void) method resets the configuration of all the device interfaces. To reset the usb stack, i think i would need to do something like this: if( gpio_get_pin_value(GPIO_JOYSTICK_PUSH) == GPIO_JOYSTICK_PUSH_PRESSED ) { udc_detach(); udc_stop(); // Maybe i need to do a udc_reset() here // Change VID/PID udc_start(); udc_attach(); // debounce if( debounce == 0 ) { state = state_START_INJECT; debounce = 250; } } Edited August 19, 2013 by juanchoc Quote Link to comment Share on other sites More sharing options...
juanchoc Posted August 19, 2013 Author Share Posted August 19, 2013 So far so good. Now what i'm trying to understand, is how you read from the vidpid.bin file to setup the vid/pid of the device. I've searched around but can't find any reference to that file. Any ideas? Quote Link to comment Share on other sites More sharing options...
overwraith Posted August 20, 2013 Share Posted August 20, 2013 (edited) The code needs to go inside the debounce if statement, like so: if( gpio_get_pin_value(GPIO_JOYSTICK_PUSH) == GPIO_JOYSTICK_PUSH_PRESSED ) { //debounce if( debounce == 0 ) { udc_detach(); udc_stop(); // Maybe i need to do a udc_reset() here // Change VID/PID udc_start(); udc_attach(); state = state_START_INJECT; debounce = 250; } } Also, I sent Midnight snake some mail concerning this, the vid/pid code is his, so he has to be the one to give it to you if he does. If the antivirus companies get the vid/pid code we may have to get creative. I plugged some of this into a composite duck variant, and now I have to figure out why the USB drive isn't mounting after the button is pressed. Edited August 20, 2013 by overwraith Quote Link to comment Share on other sites More sharing options...
overwraith Posted August 20, 2013 Share Posted August 20, 2013 I also put all this junk from the main of the script in the code, and that seems to have solved my USB drive not mounting issue. Don't even really know what this stuff does. Will have to investigate. if( gpio_get_pin_value(GPIO_JOYSTICK_PUSH) == GPIO_JOYSTICK_PUSH_PRESSED ) { // debounce if( debounce == 0 ) { //reset usb stack udc_detach(); udc_stop(); // Change VID/PID //Junk begin irq_initialize_vectors(); cpu_irq_enable(); // Initialize the sleep manager sleepmgr_init(); sysclk_init(); board_init(); ui_init(); ui_powerdown(); memories_initialization(FOSC0); //Junk end udc_reset(); udc_start(); udc_attach(); state = state_START_INJECT; a=0; debounce = 100; } } Also, I am doing a composite duck variant, so you're solution may be different from mine. Quote Link to comment Share on other sites More sharing options...
no42 Posted August 20, 2013 Share Posted August 20, 2013 (edited) Full source, on all modern developments, vidpid function, boot mode the lot: Ducky_HID_v2.1.zip Its all in the SVN on ducky-decode! Edited August 20, 2013 by midnitesnake Quote Link to comment Share on other sites More sharing options...
juanchoc Posted August 20, 2013 Author Share Posted August 20, 2013 overwraith: Awesome! I've reached the same conclusion you did (adding the "junk" in the debounce if). I refactored the junk part into another function and after executing udc_attach() i also run sleepmgr_enter_sleep(). midnitesnake: Super awesome midnitesnake! Just what i was looking for. I'll check the code later today and see what i come up with. Thank you both! Quote Link to comment Share on other sites More sharing options...
overwraith Posted August 20, 2013 Share Posted August 20, 2013 (edited) Ok, I was incorrect about the vid/pid code being secret, it is on the SVN. Here is what my code looks like. So far just making it switch to another vidpid file, but we could possibly make this code read from a space delimited binary file, and thereby choose a random vid/pid. If my other program I am writing pans out we will soon be able to generate this file from the text file I have on the ducky decode website. if( gpio_get_pin_value(GPIO_JOYSTICK_PUSH) == GPIO_JOYSTICK_PUSH_PRESSED ) { // debounce if( debounce == 0 ) { //reset usb stack udc_detach(); udc_stop(); // Change VID/PID nav_reset(); if( nav_setcwd( vidpidFile2, false, false ) ) { file_open(FOPEN_MODE_R); file_bof(); //vid and pid are uint16_t vid = file_getc() | (file_getc() << 8); pid = file_getc() | (file_getc() << 8); udc_device_desc.idVendor = (vid); udc_device_desc.idProduct = (pid); file_close(); } //Junk begin irq_initialize_vectors(); cpu_irq_enable(); // Initialize the sleep manager sleepmgr_init(); sysclk_init(); board_init(); ui_init(); ui_powerdown(); memories_initialization(FOSC0); //Junk end udc_reset(); udc_start(); udc_attach(); state = state_START_INJECT; a=0; debounce = 100; } } One more thing, wouldn't sleepmgr_enter_sleep() make the ducky go to sleep? Surely we don't want that? Edited August 20, 2013 by overwraith Quote Link to comment Share on other sites More sharing options...
juanchoc Posted August 21, 2013 Author Share Posted August 21, 2013 overwraith: One more thing, wouldn't sleepmgr_enter_sleep() make the ducky go to sleep? Surely we don't want that? From what i understand (http://asf.atmel.com/docs/3.0.1/xmegaa/html/group__sleepmgr__group.html) calling sleepmgr_enter_sleep() makes the ducky go to sleep at the deepest level of sleep allowed. But the key is where you call that function. I think that if you call it from the main loop, the device would go into sleep but still handle the interrupts (which is all we currently care about). Also, if you read/write you should call udi_msc_process_trans() to process the read/write operations, and if there's none (false returned) then put the device to sleep. Eg. (taken from the source of the composite duck firmware): while (true) { if (main_msc_enable) { if (!udi_msc_process_trans()) { sleepmgr_enter_sleep(); } }else{ sleepmgr_enter_sleep(); } } In the implementation im working on, instead of using the GPIO button to trigger the change in vid/pid, i'm doing it when the payload execution is complete, and i've been thinking that i could use the GPIO button to execute the payload again (change vid/pid -> execute payload -> change vid/pid again to mass storage). Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.