Anyway to save files back to the Flipper using BadUSB?

I’m looking to create a script to gather system information and then save it to a file on the flipper. Is there anyway to do this?

Not at the moment, possibly in the future


While you can’t save directly to the flipper zero normal rubber duckies require twin duck firmware. If you want something that is a bit less personal than to your email. Look at using webhook to post information back to. The following URL has a wife password grabber from windows machines.

After it gets the password files it posts it back to a This allows you to retrieve the data from a webserver. This post is for educational purposes only. Don’t do anything illegal please.


Hello, will it be possible to add keystroke reflection, like this?


Yes, this should be possible to implement


Does anyone know whether this function has already been implemented on the Flipper by now? or is there a feasible way to make it work on your own?

first post on the forum

by the looks of things no it is still not here yet but hopefully soon…

hey if this is still not a feature… one can play around with having a spare usb drive with a unique name(something like . or _) and plug that into the target computer first before payload execution.
the script will then do its thing and at end move or directly export the data needing to be exfiltrated to the secondary usb drive :smiley:

this method was sugested by hak5 a long time ago and an example of it is somewhere on the youtubes.
not condoning anything here lol but it is something to keep in mind if data exfil like that is important for what you need it to do (this also can be usefull for offline attacks where larger programs like image files and the like are involved)

hope this is a usefull post (as i have seen webhooks here as well)

1 Like

I have a proof of concept for doing this in Windows using Powershell. It has a couple of limitations, but I’m able to have BadUSB run a script, allow it to finish, and then I hit the back button a couple times to get out of BadUSB and (after a programmed delay) it will write data to the Flipper’s storage. It needs more work on COM port handling (and even then, I don’t think it’ll be perfect). I’m going to continue to work on this and post it when I have something I’m happy with.

If anyone wants to make a version of the BadUSB app that will immediately exit itself after a command is run (and switch back to regular Flipper mode), this would improve deployment somewhat.

1 Like

Here we go: flipperzero/badusb/save_to_flipper_poc at main · emptythevoid/flipperzero · GitHub

I’m not an expert on Powershell, and also not an expert on the kind of obfuscation, optimization, etc. that one might find if this were used in a more “Hak5” sort of way. I just had a couple of ideas and was able to get them to work.

What I learned and what is demonstrated:
-How to use Powershell to enumerate COM ports based on Device ID. Basically it will try to determine which COM port the Flipper is connected to, based on Device ID. Obviously this only works if the Device ID is known and/or remains the same.
-How to use Powershell to talk to the Flipper CLI using serial. This was tricky because the CLI is interactive, but we need to interact with it non-interactively. Also tricky because you can’t talk to the CLI while the BadUSB application is running.

1 Like

Hi @emptythevoid,
good work, but there is space of improvement.
I am not a PowerShell expert, I don’t even own a Windows in private.
But the companies I am working for, are MS based and therefore I’ve given some PS scripting lessons.

Disclaimer: This is my personal style, not based on any sense or given sytleguide. Like it or not, it is just a suggestion.


$mydevs = (Get-PnPDevice | Where-Object{$_.PNPClass -in  "WPD","AndroidUsbDeviceClass","Modem","Ports" } | Where-Object{$_.Present -in "True"} | Where-Object{$_.Service -in "usbser"} | Select-Object Name,DeviceID | Sort-Object Name) | Select-String -Pattern 'COM'

You can easily connect different Where-Object' with an -and in one statement.
I don’t know if the Select-Object is needed, because this is in 97% a display format and not useful in automation. Because the result will be the same.
The same with Sort-Object Maybe 99,99% In this case, without a filter clause.

$mydevs = (Get-PnPDevice | Where-Object { $_.PNPClass -in  "WPD","AndroidUsbDeviceClass","Modem","Ports" -and $_.Present -in "True" -and $_.Service -in "usbser" } | Select-String -Pattern 'COM'


$splitcom = $mydevs -split ("COM")
$portnum = $splitcom[1][0]

I do understand why it is split, but for more compact code it could be combined. You are just selecting one element of a ‘create string from list’. Not hard to read:

$portnum = ($mydevs -split ("COM"))[1][0]

Harder, to read, when implemented in the next line:

$port = New-Object System.IO.Ports.SerialPort COM$(($mydevs -split ("COM"))[1][0]),115200,None,8,one

My Idea would be a loop at the beginning

If ($seeFlipperZeroHID){
} Else {
  do all above

But I can’t test, without a windows.

1 Like

Somehow I knew I’d see you. :grin:

Yes, I knew there was more that could be done. I’m the same way - I’m almost always a Linux person when I can. So my work on this was almost entirely pasting together different pieces that did what I needed. Honestly I was pleased it worked at all :sweat_smile:

I’m also pleased that a lot of what you suggest is style, so I’ll blame that on my inexperience with Powershell.

I hadn’t thought about looping though. That’s pretty clever. Once I get some energy back I’ll add these optimizations and see how it goes.

I don’t know if this is good or bad, but I’ll take it as a compliment :wink:

A little lunch break work:

REM Title: Save To Flipper PoC
REM Author: emptythevoid
REM Target: Windows 10 (not tested on Windows 11, yet)
REM Version: 1.0
REM Category: PoC

REM Open Powershell
STRING powershell

REM Flipper will inject the inline powershell and run it.
REM The powershell starts with a delay. This is to give you time to hit BACK twice on the Flipper to get it out of BadUSB mode. Otherwise it wont save data
REM After the delay, the script will try to determine which COM port the Flipper is plugged into and will write a string to the specified file path.

ALTSTRING 1..600|%{Try{$p=New-Object System.IO.Ports.SerialPort("COM$(((Get-PNPDevice -PresentOnly|Where{$_.InstanceID -match 'USB\\VID_0483\&PID_5740' -and $_.Class -eq "Ports"}) -split "COM")[1][0])",115200,'None',8,'one');$;$p.Write("storage write /ext/apps_data/exfil_data`r`n");$p.Write("Hello World!");$p.Write("$([char] 3)");$p.Close();break}Catch{If(Get-PNPDevice -PresentOnly|Where {$_.InstanceID -match 'HID\\VID_046D\&PID_C529'}){"BadUSB"}Else{"NoFZ";Start-Sleep 4};Start-Sleep 1}}

I was informed it works on Win10. I am not happy with 1000+ characters in one line. It is still POC - I’d like to share.


The PS part could be reduced by over 40 characters, but than the output in the loop is an error:

ALTSTRING 1..600|%{Try{$p=New-Object System.IO.Ports.SerialPort("COM$(((Get-PNPDevice -PresentOnly -Class 'Ports' -InstanceID 'USB\VID_0483&PID_5740*') -split "COM")[1][0])",115200,'None',8,'one');$;$p.Write("storage write /ext/apps_data/exfil_data`r`n");$p.Write("Hello World!");$p.Write("$([char] 3)");$p.Close();break}Catch{Sleep 1}}

Reading the documentation of Get-PnpDevice (PnpDevice) shows we don’t need the |Where.
The last part of my former line was just error handling. But in the end we only need to know ‘is storage present’? So it is reduced to ‘sleep’.


Complement intended! :slight_smile: It certainly wasn’t my intention to distract you from your work, though. Thanks for looking at this. If nothing else, it’s a learning experience for me. You’re very knowledgeable and a prolific poster on the forum, so I’m honored that this interested you.

I don’t like placing everything in a single line, either. I might fiddle with that. This is really cool - I know this question has come up a lot (saving data back to the Flipper). While this is kinda a hack to make it work, I’m really happy that it does work. I will find a time where I can give this some attention and try playing with it.

A first shot to do the same loop in bash/linux.

for i in {1..600}; do if (usb-devices |grep "Vendor=0483 ProdID=5740"); then echo "Storage"; break; elif (usb-devices | grep "Vendor=046d ProdID=c529"); then echo "BadUSB"; sleep 1; else echo "noFZ"; sleep4; fi; done

But I have no idea how to find the correct /dev/ at the moment.
If you have an approach, just replace echo "Storage"

Less chars with lsusb:

for i in {1..600}; do if (lsusb |grep "0483:5740"); then echo "Storage"; break; elif (lsusb | grep "046d:c529"); then echo "BadUSB"; sleep 1; else echo "noFZ"; sleep 4; fi; done
1 Like

This is brilliant! I haven’t been able to spend any time on this, but I definitely want to look at it in depth.

I don’t know whether you have a use for this but I wrote a script that uses PowerShell to exfil a folder structure to a USB you bring along. Just configure 3 variables, plug-in the USB drive and run the Ducky script. Have a look at it if you think this is useful: flipperzero/BadUSB/Ducky Scripts/Offensive/ExfilToUsb.txt at main · Zarcolio/flipperzero · GitHub

I do like the while (-not $f) part. It waits as long as it takes to place a USB stick.
On the downside you need an (prepared) USB drive with you. Even if you could reuse the same port, because of the while.
Create the file can be performed in time, if you know the filename.

At @emptythevoid’s script I intentionally used a loop with 600 cycles, with a delay of 1 sec. So it will run at least 5 minutes, enough time to act. Than just die …
Maybe a termination f the PS window at the end is useful (Note at TODO. Does the Flipper got a Todo list app?).

Today we found out, that some enterprise endpoint security solutions blocks USB Mass storage, but not direct serial write.

So +2 for the script from @emptythevoid

1 Like

While it’s true that mass storage devices are often blocked, I think both scripts have different use cases. Using an ordinary USB drive is less conspicuous than leaving a shiny Flipper Zero on someone’s desk. My script only needs the Flipper to execute the script and the Flipper can be unplugged. Also, if one needs to exfil large amounts of data, how well does that go over a serial connection in contrast to a copy to USB?

1 Like

Not as fast, for sure, but it’s something I’m going to be looking at soon

I tried out adding an exit at the end of the “short” version. I’ll double check to make sure that’s on the repo.

Edit: yes