Full Code of CedArctic/digiQuack for AI

master 055146e616c4 cached
6 files
24.7 KB
6.9k tokens
4 symbols
1 requests
Download .txt
Repository: CedArctic/digiQuack
Branch: master
Commit: 055146e616c4
Files: 6
Total size: 24.7 KB

Directory structure:
gitextract_sv62pjtq/

├── LICENSE
├── README.md
├── css/
│   └── style.css
├── digiQuack.cpp
├── index.html
└── javascript/
    └── digiQuack.js

================================================
FILE CONTENTS
================================================

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2017 CedArctic

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
![digiQuack logo](/images/logo.png)

# digiQuack
digiQuack is an easy DuckyScript to DigiSpark payload converter based on C++. It contains various features including full DuckyScript language support, execution limiter, DigiSpark memory optimizations and more. Note though that currently support of foreign keyboard layouts (not english ones) is rather spotty, so try it out and see if it works out for yourself. The code is well documented with comments so feel free to take a look for yourself.


## Instructions - Online (Recommended) 🌐
You can use digiQuack by visiting the [converter website](https://cedarctic.github.io/digiQuack/).

## Instructions - Local 💻
![screenshot](/images/screenshot.png)

Just download one of the releases or download the source (digiQuack.cpp) and compile it yourself.

>Linux/Mac OS users: use ./digiQuack in the terminal to run and follow the prompt.

>Windows users: Run the digiQuack.exe. Drag and drop the txt file with the payload you want to convert and follow the prompt.

The converted file will be placed in the scripts' directory (or for macOS under the user directory) and will be named converted.txt. You can then follow seytonic's tutorial (in the credits) to install it on your digispark.

## Video Tutorial on using the tool locally:

[![Convert Ducky Scripts to Digispark](https://img.youtube.com/vi/YXWxEzLHXuw/0.jpg)](https://www.youtube.com/watch?v=YXWxEzLHXuw)

## Downloads

See the releases page to get the latest version: https://github.com/CedArctic/digiQuack/releases/ 

## Digispark Scripts

In case you want to play around with some of my Digispark scripts, you can find them here:
>https://github.com/CedArctic/DigiSpark-Scripts

## Convert to Python Scripts

Want to convert Ducky Scripts to Python applications? Check out ducky2python:
>https://github.com/CedArctic/ducky2python

## Credits/Resources
- Keyboard usage IDs: www.usb.org/developers/hidpage/Hut1_12v2.pdf
- Seytonic's tutorial: https://www.youtube.com/watch?v=fGmGBa-4cYQ
- Kevin Mitnik for pointing out the 'F' improvement: https://www.youtube.com/watch?v=IRSK_DNYL8Q
- hak5darren for the USB Rubber Ducky Documentation: https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Duckyscript
- Digistump for the DigiSpark and their documentation: https://github.com/digistump/DigisparkArduinoIntegration/blob/master/libraries/DigisparkKeyboard/DigiKeyboard.h
- AntyStewie for optimizations


================================================
FILE: css/style.css
================================================
body{
	font-family: Arial, Helvetica, sans-serif;
	background-color: #f4f4f4;
	color: #555;
	font-size: 16px;
	margin: 0;
	line-height: 1.6em;
	text-align: center;
}

a{
	text-decoration: none;
	color:inherit;
}

.navbar{
	background-color: black;
	margin: none;
	padding: 10px;
	width: 100%;
	height: auto;
	line-height: 0.5em;
	font-size: 18px;
}

.navbar h1{
	color: white;
	font-family: Arial, Helvetica, sans-serif;
}
.about{
	text-align: center;
}

.container{
	width: 75%;
	margin: auto;
	overflow: hidden;
}

textarea{
	width: 100%;
	font-size: 14px;
	height: auto;
}

button{
	font-size: 18px;
	padding: 5px;
	border-radius: 5px;
	margin: 10px;
	border-width: 0px;
	background-color: #c9ccd1;
}

img{
	height:auto;
	width: auto;
	max-width: 80px;
	max-height: 80px;
	margin: 10px;
}

================================================
FILE: digiQuack.cpp
================================================
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

//Function to count the lines of the script to be converted
int linecounter(string dir){

	int counter = 0;

    string line;

    //Create new file stream to file to be converted
    ifstream file(dir);

    while (getline(file, line)){
        counter++;}

    return counter;
}

//Accepts a string and returns the value of the key(s) in digispark language
//Some of the keys are encoded using their usage IDs. Refer to http://www.usb.org/developers/hidpage/Hut1_12v2.pdf  (Page 53-59)
string stringprocessor(string key){

    int asciinum;//Case for A and a

    if(key.size() == 1){
        asciinum = (int)key[0];         //If the string length is 1, use a switch statement to improve speed. In order to do that we need to extract the character number in ascii with this line of code.

        switch(asciinum){

            case 65:
            case 97:
                key = "KEY_A";
                return key;
            case 66:
            case 98:
                key = "KEY_B";
                return key;
            case 67:
            case 99:
                key = "KEY_C";
                return key;
            case 68:
            case 100:
                key = "KEY_D";
                return key;
            case 69:
            case 101:
                key = "KEY_E";
                return key;
            case 70:
            case 102:
                key = "KEY_F";
                return key;
            case 71:
            case 103:
                key = "KEY_G";
                return key;
            case 72:
            case 104:
                key = "KEY_H";
                return key;
            case 73:
            case 105:
                key = "KEY_I";
                return key;
            case 74:
            case 106:
                key = "KEY_J";
                return key;
            case 75:
            case 107:
                key = "KEY_K";
                return key;
            case 76:
            case 108:
                key = "KEY_L";
                return key;
            case 77:
            case 109:
                key = "KEY_M";
                return key;
            case 78:
            case 110:
                key = "KEY_N";
                return key;
            case 79:
            case 111:
                key = "KEY_O";
                return key;
            case 80:
            case 112:
                key = "KEY_P";
                return key;
            case 81:
            case 113:
                key = "KEY_Q";
                return key;
            case 82:
            case 114:
                key = "KEY_R";
                return key;
            case 83:
            case 115:
                key = "KEY_S";
                return key;
            case 84:
            case 116:
                key = "KEY_T";
                return key;
            case 85:
            case 117:
                key = "KEY_U";
                return key;
            case 86:
            case 118:
                key = "KEY_V";
                return key;
            case 87:
            case 119:
                key = "KEY_W";
                return key;
            case 88:
            case 120:
                key = "KEY_X";
                return key;
            case 89:
            case 121:
                key = "KEY_Y";
                return key;
            case 90:
            case 122:
                key = "KEY_Z";
                return key;
            case 48:
                key = "KEY_0";
                return key;
            case 49:
                key = "KEY_1";
                return key;
            case 50:
                key = "KEY_2";
                return key;
            case 51:
                key = "KEY_3";
                return key;
            case 52:
                key = "KEY_4";
                return key;
            case 53:
                key = "KEY_5";
                return key;
            case 54:
                key = "KEY_6";
                return key;
            case 55:
                key = "KEY_7";
                return key;
            case 56:
                key = "KEY_8";
                return key;
            case 57:
                key = "KEY_9";
                return key;
            default:
                cout << "There was a problem in converting the ascii character:" << key << endl;        //In case the character doesn't exist in the switch
        }
    }


    if(key=="ENTER"){
        key = "KEY_ENTER";
        return key;
    }

    else if(key=="F1"){
        key = "KEY_F1";
        return key;
    }

    else if(key=="F2"){
        key = "KEY_F2";
        return key;
    }

    else if(key=="F3"){
        key = "KEY_F3";
        return key;
    }

    else if(key=="F4"){
        key = "KEY_F4";
        return key;
    }

    else if(key=="F5"){
        key = "KEY_F5";
        return key;
    }

    else if(key=="F6"){
        key = "KEY_F6";
        return key;
    }

    else if(key=="F7"){
        key = "KEY_F7";
        return key;
    }

    else if(key=="F8"){
        key = "KEY_F8";
        return key;
    }

    else if(key=="F9"){
        key = "KEY_F9";
        return key;
    }

    else if(key=="F10"){
        key = "KEY_F10";
        return key;
    }

    else if(key=="F11"){
        key = "KEY_F11";
        return key;
    }

    else if(key=="F12"){
        key = "KEY_F12";
        return key;
    }

    else if((key=="GUI") || (key=="WINDOWS")){
        key = "0, MOD_GUI_LEFT"; //Doesn't work without the 0, for some reason
        return key;
    }

    else if((key=="APP") || (key=="MENU")){
        key = "101";
        return key;
    }

    else if(key=="SHIFT"){
        key = "MOD_SHIFT_LEFT";
        return key;
    }

    else if(key=="ALT"){
        key = "MOD_ALT_LEFT";
        return key;
    }

    else if((key=="CONTROL") || (key=="CTRL")){
        key = "MOD_CONTROL_LEFT";
        return key;
    }

    else if((key=="DOWNARROW") || (key=="DOWN")){
        key = "81";
        return key;
    }

    else if((key=="UPARROW") || (key=="UP")){
        key = "82";
        return key;
    }

    else if((key=="LEFTARROW") || (key=="LEFT")){
        key = "80";
        return key;
    }

    else if((key=="RIGHTARROW") || (key=="RIGHT")){
        key = "79";
        return key;
    }

    else if((key=="BREAK") || (key=="PAUSE")){
        key = "72";
        return key;
    }

    else if(key=="CAPSLOCK"){
        key = "57";
        return key;
    }

    else if((key=="ESC") || (key=="ESCAPE")){
        key = "41";
        return key;
    }

    else if(key=="DELETE"){
        key = "42";
        return key;
    }

    else if(key=="END"){
        key = "77";
        return key;
    }

    else if(key=="HOME"){
        key = "74";
        return key;
    }

    else if(key=="NUMLOCK"){
        key = "83";
        return key;
    }

    else if(key=="PAGEUP"){
        key = "75";
        return key;
    }

    else if(key=="PAGEDOWN"){
        key = "78";
        return key;
    }

    else if(key=="PRINTSCREEN"){
        key = "70";
        return key;
    }

    else if(key=="SCROLLLOCK"){
        key = "71";
        return key;
    }

    else if(key=="SPACE"){
        key = "44";
        return key;
    }

    else if(key=="TAB"){
        key = "43";
        return key;
    }
}

int main(){

    //Eye-candy
    cout<<"  _      _      _"<<endl;
    cout<<">(.)__ <(.)__ =(.)__"<<endl;
    cout<<" (___/  (___/  (___/"<<endl;
    cout<<endl;
    cout<<endl;
    cout<<"Welcome to digiQuack, the easy DuckyScript to Digispark payload converter!"<<endl;

    //Ask user to enter path to file to be converted
    string dir;
    cout<<"Enter the path of the file to be converted:"<<endl;
    cin>>dir;

    //Open input file stream
    ifstream filein(dir);

    //Check if file stream opened - if file exists and is a valid input
    if(!filein){
        cout<<"File not found or invalid input."<<endl;
        return -1;
    }

    //Check if the input file is empty
    if ( filein.peek() == std::ifstream::traits_type::eof() )
    {
        cout<<"File supplied is empty"<<endl;
        return -1;

    }

    //Create a counter as big as the number of lines in the input file
    int counter = linecounter(dir);

    //Open converted file fstream and create text file
    ofstream fileout;
    fileout.open ("converted.txt");

    //Create a string variable to store each individual ducky command/line to process in the for loop
    string command;

    //Create a trigger for the default delay command - if default delay command is encountered, inject converted script with delay lines
    int delay = 0;

    //Insert this line in the beginning of the converted script to make sure that (on older systems) the first keystroke after a delay isn't missed
    fileout << "DigiKeyboard.sendKeyStroke(0);\n";

    //Create temporary string variables to use for string manipulation in the following for-loop
    string tmpstring;
    string tmpstring2;
    string fincom; //Use this variable to keep track of the last converted command to use in the repeat function
    string key; //Variable to be used in the keystroke conversion if clause underneath
    int replays = 0; //Replays counter for the REPLAY feature if clause underneath

    //Open a for loop to process each line/command of the input script
    for(int i=0; i<counter; i++){

        //Set command string equal to current line
        getline(filein, command);

        //Check for DEFAULT_DELAY or DEFAULTDELAY, set the delay variable and re-examine for-loop (Note: writing the delay commands happens at the end of the for-loop).
        tmpstring = tmpstring.assign(command,0,13);
        if((tmpstring.compare("DEFAULTDELAY ")==0) || (tmpstring.compare("DEFAULT_DELAY")==0)){
            command.erase(0,13);
            delay = stoi(command);
            continue;
        }

        //Convert duckyscript comments to Arduino IDE comments: Extract 3 first characters, if == REM, replace them with //, write to output and re-examine for-loop - this helps avoid placing unnecessary delay commands
        tmpstring = tmpstring.assign(command,0,3);
        if(tmpstring.compare("REM") == 0){
            command.replace(0,4,"//");
            fileout << command << "\n";
            continue;
        }

        //Convert duckyscript STRING commands to digispark print commands (Note, used F to store large strings to flash since the digispark has few RAM)
        tmpstring = tmpstring.assign(command,0,6);
        if(tmpstring.compare("STRING") == 0){
            command.replace(0,7,"DigiKeyboard.print(F(\"");
            command += "\"));";
            fincom = command; //See use of fincom above
            fileout << command << "\n";
            command = ""; //Empty the string so it won't trigger the keystroke processor
        }

        //Convert DELAY command (Not DEFAULTDELAY)
        tmpstring = tmpstring.assign(command,0,5);
        if(tmpstring.compare("DELAY") == 0){
            command.erase(0,6);
            fincom = "DigiKeyboard.delay(" + command + ");";
            fileout << fincom << "\n";
            command = ""; //command variable is set to null to bypass keystroke processor but still access default delay
        }

        //REPLAY feature (Note: at the end, command variable is set to null to bypass keystroke processor but still access default delay)
        tmpstring = tmpstring.assign(command,0,5);
        if(tmpstring.compare("REPLAY") == 0){
            command.erase(0,6);
            replays = stoi(command);
            for(int j=0; j < replays; j++){
                fileout << fincom << "\n";
            }
            command = "";
        }

        //Convert keystroke commands by calling the string processor function
        if(!command.empty()){
            key = command.substr(0, command.find(' '));
            tmpstring = "DigiKeyboard.sendKeyStroke(" + stringprocessor(key);
            command.erase(0, command.find(' ')+1);
            if(!command.empty() && command != key){         //If command is equal to key it means that the command is a one word line e.g ENTER so command.erase until a ' ' would have no effect.
                tmpstring = tmpstring + ",";
                tmpstring = tmpstring + stringprocessor(command);
            }
            tmpstring = tmpstring + ");";
            fincom = tmpstring;
            fileout << fincom << "\n";
        }

        //If default delay trigger is activated, inject output file with a delay command
        if(delay!=0){
            fileout << "DigiKeyboard.delay(" << delay << ");\n";
        }
    }

    //Ask if user wants to execute the script just once - Use the counter variable instead of initialising a new one since counter won't be used anymore.
    cout << "Script has been converted successfully. Do you want the DigiSpark to execute the script once or loop infinitely? Select 0 for infinity and 1 for a single execution." << endl;
    cout << "[0/1]:";
    cin >> counter;

    if(counter){
        fileout << "for(;;){ /*empty*/ }";
    }

    //Close converted script txt fstream
    fileout.close();
    return 0;
}


================================================
FILE: index.html
================================================
<!DOCTYPE html>
<html>
<head>

	<title>digiQuack: Convert DuckyScript to Digispark Scripts</title>
	<meta charset="utf-8">
	<meta name = "description" content="Convert DuckyScript to Digispark Scripts">
	<meta name = "keywords" content="bad usb, rubber ducky, hak5, convert, script, digispark">
	<link rel = "stylesheet" type="text/css" href= "css/style.css">
	<script src="javascript/digiQuack.js"></script>

</head>

<body>

	<div class="navbar">
		<div class="container">
			<a href="https://github.com/CedArctic/digiQuack" target="_blank"><h1>digiQuack 🦆</h1></a>
			<a href="https://github.com/CedArctic" target="_blank"><p>by CedArctic</p></a>
		</div>

	</div>


	<div class = "container about">
		<p>Convert DuckyScript scripts (of the hak5 USB Rubber Ducky) to Digispark scripts that you can use with the 1$ bad USB.</p>

		<p>Why DuckyScript and why Digispark? It's easy! DuckyScript is simple and easy to learn and has become a standard in the BadUSB and pentesting community.
		Digispark is one of the cheapest and most easily accessible bad USBs available. Combine the two using digiQuack and you have a vast arsenal of ready to run
		scripts on a cheap and fun to use bad USB!</p>
		
		<p>Want to convert Duckyscript to Python programs? Check out <a href="https://github.com/CedArctic/ducky2python"><b>ducky2python!</b></b></a></p>
	</div>

	<div class = "container">
		<textarea rows = 15 id = "inputBox" placeholder="Enter DuckyScript to convert..."></textarea>
		<button onclick="if(document.getElementById('inputBox').value != ''){convert()}">Convert</button>
		<textarea rows = 15 id = "outputBox" placeholder="Converted Digispark script will appear here. Paste it into the Arduino IDE to load it onto your Digispark."></textarea>
	</div>

	<a href="https://github.com/CedArctic/ducky2python" target="_blank"><img src = "https://cdn0.iconfinder.com/data/icons/octicons/1024/mark-github-512.png" alt="Github Icon"></a>
</body>

</html>

================================================
FILE: javascript/digiQuack.js
================================================
/*	 

 duck2python converts DuckyScript scripts for the USB Rubber Ducky by hak5 to python scripts that function the same way
thus offering a convenient way of testing a script without requiring to load it on a Rubber Ducky each time.

*/

/*

# Print Ascii Art:
print("     _            _          ____              _   _                 ")
print("  __| |_   _  ___| | ___   _|___ \\ _ __  _   _| |_| |__   ___  _ __  ")
print(" / _` | | | |/ __| |/ / | | | __) | '_ \\| | | | __| '_ \\ / _ \\| '_ \\ ")
print("| (_| | |_| | (__|   <| |_| |/ __/| |_) | |_| | |_| | | | (_) | | | |")
print(" \\__,_|\\__,_|\\___|_|\\_\\\\__, |_____| .__/ \\__, |\\__|_| |_|\\___/|_| |_|")
print("                       |___/      |_|    |___/ \tby CedArctic                 ")
print("\n\n")

*/

function convert(){
	// Declare and load Ducky Script and Digispark output:
	var duckyScript = document.getElementById('inputBox').value;
	var digisparkScript = "";

	// Write module imports to output file:
	digisparkScript += "// Converted using digiQuack by CedArctic (https://github.com/CedArctic/digiQuack) \n\n";
	digisparkScript +="#include \"DigiKeyboard.h\"\n\n";
	digisparkScript += "void setup() {}\n\n";
	digisparkScript += "void loop() {\n";
	digisparkScript += "\tDigiKeyboard.sendKeyStroke(0);\n";

	// Convert the Ducky Script lines to a list and stip whitespaces:
	duckyScript = duckyScript.split(/\r\n|\r|\n/g);
	/* Ducky Statements fall into one of the following 6 categories:
	1. Default Delay	2.Comment	3.Delay 	4.String	5.Repeat	6.Command */

	// Check if there is a default delay:
	var defaultDelay = 0;
	if (duckyScript[0].slice(0,7) == "DEFAULT"){
		defaultDelay = parseInt(duckyScript[0].slice(7));
		duckyScript.shift();
	}

	// Variables:
	var previousStatement = "";	
	var keys = [];
		
	// Dictionary containing Duckyscript and their corresponding Digispark keys
	var ducky2digi = {"WINDOWS":"0, MOD_GUI_LEFT", "GUI":"0, MOD_GUI_LEFT", "APP":"101", "MENU":"101",
	"SHIFT":"MOD_SHIFT_LEFT", "ALT":"MOD_ALT_LEFT", "CONTROL":"MOD_CONTROL_LEFT", "CTRL":"MOD_CONTROL_LEFT",
	"DOWNARROW":"81", "DOWN":"81", "LEFTARROW":"80", "LEFT":"80", "RIGHTARROW":"79", "RIGHT":"79", "UPARROW":"82",
	"UP":"82", "BREAK":"72", "PAUSE":"72", "CAPSLOCK":"57", "DELETE":"42", "END":"42", "ESC":"41", "ESCAPE":"41",
	"HOME":"74", "NUMLOCK":"83", "PAGEUP":"75", "PAGEDOWN":"78", "PRINTSCREEN":"70", "SCROLLLOCK":"71", "SPACE":"44", 
	"TAB":"43", "ENTER":"KEY_ENTER", "F1":"KEY_F1", "F2":"KEY_F2", "F3":"KEY_F3", "F4":"KEY_F4", "F5":"KEY_F5",
	"F6":"KEY_F6", "F7":"KEY_F7", "F8":"KEY_F8", "F9":"KEY_F9", "F10":"KEY_F10", "F11":"KEY_F11", "F12":"KEY_F12",
	"a":"KEY_A", "b":"KEY_B", "c":"KEY_C", "d":"KEY_D", "e":"KEY_E", "f":"KEY_F", "g":"KEY_G", "h":"KEY_H",
	"i":"KEY_I", "j":"KEY_J", "k":"KEY_K", "l":"KEY_L", "m":"KEY_M", "n":"KEY_N", "o":"KEY_O", "p":"KEY_P",
	"q":"KEY_Q", "r":"KEY_R", "s":"KEY_S", "t":"KEY_T", "u":"KEY_U", "v":"KEY_V", "w":"KEY_W", "x":"KEY_X",
	"y":"KEY_Y", "z":"KEY_Z", "A":"KEY_A", "B":"KEY_B", "C":"KEY_C", "D":"KEY_D", "E":"KEY_E", "F":"KEY_F", 
	"G":"KEY_G", "H":"KEY_H", "I":"KEY_I", "J":"KEY_J", "K":"KEY_K", "L":"KEY_L", "M":"KEY_M", "N":"KEY_N",
	"O":"KEY_O", "P":"KEY_P", "Q":"KEY_Q", "R":"KEY_R", "S":"KEY_S", "T":"KEY_T", "U":"KEY_U", "V":"KEY_V",
	"W":"KEY_W", "X":"KEY_X", "Y":"KEY_Y", "Z":"KEY_Z", "1":"KEY_1", "2":"KEY_2", "3":"KEY_3", "4":"KEY_4", 
	"5":"KEY_5", "6":"KEY_6", "7":"KEY_7", "8":"KEY_8", "9":"KEY_9", "0":"KEY_0", "!":"30", "\"":"49", "#":"32", 
	"$":"33", "%":"34", "&":"36", "\'":"52", "(":"38", ")":"39", "*":"37", "+":"46", ",":"54", "-":"45", ".":"55",
	"/":"56", ":":"51", ";":"51", "<":"54", "=":"46", ">":"55", "?":"56", "@":"31", "[":"47", "]":"48", "^":"35",
	"_":"45", "`":"53", "{":"47", "|":"49", "}":"48", "~":"53"};

	// Process each line from the ducky script:
	for (line = 0; line < duckyScript.length; line++){

		// Check if the statement is a comment, delay, string, repeat or key combination
		if(duckyScript[line].slice(0,3) == "REM"){
			previousStatement = duckyScript[line].replace("REM","\t//");
		}else if (duckyScript[line].slice(0,5) == "DELAY"){
			previousStatement = "\tDigiKeyboard.delay(" + parseInt(duckyScript[line].slice(6)) + ");";
		}else if (duckyScript[line].slice(0,6) == "STRING") {
			previousStatement = "\tDigiKeyboard.print(\"" + duckyScript[line].slice(7).replaceAll("\\", "\\\\").replaceAll("\"", "\\\"") + "\");";
		}else if (duckyScript[line].slice(0,6) == "REPEAT"){
			var repetitions = parseInt(duckyScript[line].slice(7)) - 1;
			for (i = 0; i < repetitions; i++){
				digisparkScript += previousStatement;
				digisparkScript += "\n";

				// Write Default Delay between the commands if it exists:
				if (defaultDelay != 0){
					digisparkScript += "\tDigiKeyboard.delay(" + defaultDelay + ");\n";
				}
			}
		}else{
			// Write beginning of command:
			previousStatement = "\tDigiKeyboard.sendKeyStroke(";
			// Split statement into keys
			keys = duckyScript[line].split(" ");
			// Go through the keys matching them through the dictionary to Digispark keys
			for (j = 0; j < keys.length; j++){
				if (keys[j] in ducky2digi){
					previousStatement += ducky2digi[keys[j]] + ",";
				}else{
					// If it is not in the dictionary
					previousStatement += "UNDEFINED_KEY" + ",";
				}
			}
			// Remove last comma and add a parenthesis
			previousStatement = previousStatement.slice(0, previousStatement.length - 1) + ");";
		}

		// Write command to output file and add a new line \n :
		digisparkScript += previousStatement;
		digisparkScript += "\n";

		// Write Default Delay if it exists:
		if (defaultDelay != 0){
			digisparkScript += "\tDigiKeyboard.delay(" + defaultDelay + ");\n";
		}
	}
	digisparkScript += "}";
	// Write Output
	document.getElementById('outputBox').value = digisparkScript;
}
Download .txt
gitextract_sv62pjtq/

├── LICENSE
├── README.md
├── css/
│   └── style.css
├── digiQuack.cpp
├── index.html
└── javascript/
    └── digiQuack.js
Download .txt
SYMBOL INDEX (4 symbols across 2 files)

FILE: digiQuack.cpp
  function linecounter (line 8) | int linecounter(string dir){
  function string (line 25) | string stringprocessor(string key){
  function main (line 350) | int main(){

FILE: javascript/digiQuack.js
  function convert (line 21) | function convert(){
Condensed preview — 6 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (28K chars).
[
  {
    "path": "LICENSE",
    "chars": 1066,
    "preview": "MIT License\n\nCopyright (c) 2017 CedArctic\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\n"
  },
  {
    "path": "README.md",
    "chars": 2412,
    "preview": "![digiQuack logo](/images/logo.png)\n\n# digiQuack\ndigiQuack is an easy DuckyScript to DigiSpark payload converter based o"
  },
  {
    "path": "css/style.css",
    "chars": 791,
    "preview": "body{\n\tfont-family: Arial, Helvetica, sans-serif;\n\tbackground-color: #f4f4f4;\n\tcolor: #555;\n\tfont-size: 16px;\n\tmargin: 0"
  },
  {
    "path": "digiQuack.cpp",
    "chars": 13292,
    "preview": "#include <iostream>\n#include <fstream>\n#include <string>\n\nusing namespace std;\n\n//Function to count the lines of the scr"
  },
  {
    "path": "index.html",
    "chars": 1953,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n\n\t<title>digiQuack: Convert DuckyScript to Digispark Scripts</title>\n\t<meta charset=\"utf-8"
  },
  {
    "path": "javascript/digiQuack.js",
    "chars": 5804,
    "preview": "/*\t \n\n duck2python converts DuckyScript scripts for the USB Rubber Ducky by hak5 to python scripts that function the sam"
  }
]

About this extraction

This page contains the full source code of the CedArctic/digiQuack GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 6 files (24.7 KB), approximately 6.9k tokens, and a symbol index with 4 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!