Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- enum AuthMethod : uint8_t {
- NOAUTH = 0x00,
- GSSAPI = 0x01,
- PASSWORD = 0x02,
- NO_ACCEPTABLE = 0xff,
- };
- enum Version : uint8_t {
- SOCKS5 = 0x05,
- };
- enum Status : uint8_t {
- SUCCESS = 0x00,
- FORBIDDEN = 0x01,
- };
- enum Command : uint8_t {
- CONNECT = 0x01,
- BIND = 0x02,
- UDP_ASSOCIATE = 0x03,
- };
- enum AddressType : uint8_t {
- AT_IPV4 = 0x01,
- AT_FQDN = 0x03,
- AT_IPV6 = 0x04,
- };
- enum Reply : uint8_t {
- SUCCEEDED = 0x00,
- FAILURE = 0x01,
- NOT_ALLOWED = 0x02,
- NETWORK_UNREACHABLE = 0x03,
- HOST_UNREACHABLE = 0x04,
- CONNECTION_REFUSED = 0x05,
- TTL_EXPIRED = 0x06,
- COMMAND_NOT_SUPPORTED = 0x07,
- ADDRESS_NOT_SUPPORTED = 0x08,
- };
- #pragma pack(push, 1)
- struct socks5negotiation {
- uint8_t version;
- uint8_t nomethods;
- AuthMethod methods[1];
- };
- struct socks5negotiationResponse {
- uint8_t version;
- AuthMethod method;
- };
- struct socks5_negotiation_header {
- quint8 version;
- };
- struct AuthResponse {
- uint8_t authVersion = 0x01;
- uint8_t authStatus;
- };
- struct IPv4 {
- uint32_t ip;
- uint16_t port;
- };
- typedef uint8_t uint128_t[16];
- struct IPv6 {
- uint128_t ip;
- uint16_t port;
- };
- struct FQDN {
- uint8_t bytes[4];
- };
- union Destination {
- IPv4 ipv4;
- IPv6 ipv6;
- FQDN fqdn;
- };
- struct NegotiationRequest {
- Version version;
- Command command;
- uint8_t reserverd;
- AddressType addr_type;
- Destination dest;
- };
- struct NegotiationResponse {
- Version version;
- Reply reply;
- uint8_t reserved;
- AddressType addr_type;
- Destination dest;
- };
- #pragma pack(pop)
- AuthMethod getSupportedMethod(const AuthMethod *methods, uint8_t nomethods) {
- for (uint8_t i = 0; i != nomethods; ++i) {
- if (methods[i] == AuthMethod::PASSWORD) {
- return AuthMethod::PASSWORD;
- }
- }
- return AuthMethod::NO_ACCEPTABLE;
- }
- #include <winsock.h>
- #pragma comment(lib, "Ws2_32.lib")
- void Worker::readyRead()
- {
- QByteArray request = socket->read(1);
- auto requestHeader = reinterpret_cast<socks5_negotiation_header*>(request.data());
- qDebug() << "HEADER" << requestHeader->version;
- if(requestHeader->version == Version::SOCKS5 && !clientIsAuthenticated) {
- request.append(socket->readAll());
- if(request.size() == 4) {
- auto header = reinterpret_cast<socks5negotiation*>(request.data());
- auto method = getSupportedMethod(header->methods, header->nomethods);
- qDebug() << "[ Client sent SOCKS Version:" <<header->version << "]";
- if(header->version != 0x05) {
- socket->close();
- return;
- }
- else if(method != AuthMethod::PASSWORD) {
- qDebug() << "[ Close connection: Client sent authentication without password. ]";
- socket->close();
- return;
- }
- auto res = reinterpret_cast<socks5negotiationResponse*>(request.data());
- res->method = method;
- res->version = Version::SOCKS5;
- socket->write(request.data(), request.size());
- }
- }
- else if(requestHeader->version == 0x01){
- qDebug() << "[ Reading Username / Password ]";
- uint8_t username_len = qFromLittleEndian<uint8_t>(socket->read(1));
- QString username = socket->read(username_len);
- uint8_t password_len = qFromLittleEndian<uint8_t>(socket->read(1));
- QString password = socket->read(password_len);
- qDebug() << "Username" << username;
- qDebug() << "Password" << password;
- AuthResponse authReply;
- if(username.compare("Kevin") || password.compare("MitNick")) {
- qDebug() << "[ Client sent wrong credentials ]";
- authReply.authStatus = Status::FORBIDDEN;
- socket->write((char*)&authReply, sizeof(authReply));
- socket->close();
- return;
- }
- qDebug() << "[ Client authentication success ]";
- authReply.authStatus = Status::SUCCESS;
- socket->write((char*)&authReply, sizeof(authReply));
- clientIsAuthenticated = true;
- }
- else if(requestHeader->version == Version::SOCKS5 && clientIsAuthenticated) {
- qDebug() << "[ Client is sending negotiation request ]";
- request.append(socket->readAll());
- auto clientNegotiationRequest = reinterpret_cast<NegotiationRequest*>(request.data());
- if(clientNegotiationRequest->command == Command::CONNECT) {
- qDebug() << "[ Client is requesting CONNECT ]";
- auto res = reinterpret_cast<NegotiationResponse *>(request.data());
- res->version = Version::SOCKS5;
- res->reply = Reply::SUCCEEDED;
- res->reserved = 0;
- remoteEndpoint->connectToHost(QHostAddress(qFromBigEndian<quint32>(clientNegotiationRequest->dest.ipv4.ip)), qToBigEndian<quint16>(clientNegotiationRequest->dest.ipv4.port));
- connect(remoteEndpoint, &QTcpSocket::connected, [=]() {qDebug() << "CONNECTED..........."; socket->write(request.data()); });
- connect(remoteEndpoint, &QTcpSocket::readyRead, [=]() { qDebug() << "WE HAVE DATA";
- QByteArray endpointData = remoteEndpoint->readAll();
- socket->write(endpointData);
- });
- qDebug() << "[ Sending negotiation request ]";
- }
- else if(clientNegotiationRequest->command == Command::BIND) {
- qDebug() << "[ Client is requesting BIND ]";
- }
- else if(clientNegotiationRequest->command == Command::UDP_ASSOCIATE) {
- qDebug() << "[ Client is requesting UDP ASSOCIATE ]";
- }
- }
- else if(clientIsAuthenticated) {
- request.append(socket->readAll());
- qDebug() << "[ Server is sending us " << request.size() << "IP" << socket->peerAddress() << "]";
- remoteEndpoint->write(request);
- }
- else {
- socket->close();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement