Advertisement
Guest User

Untitled

a guest
Dec 21st, 2018
288
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.15 KB | None | 0 0
  1.  
  2. enum AuthMethod : uint8_t {
  3.     NOAUTH = 0x00,
  4.     GSSAPI = 0x01,
  5.     PASSWORD = 0x02,
  6.     NO_ACCEPTABLE = 0xff,
  7. };
  8.  
  9. enum Version : uint8_t {
  10.     SOCKS5 = 0x05,
  11. };
  12.  
  13. enum Status : uint8_t {
  14.     SUCCESS = 0x00,
  15.     FORBIDDEN = 0x01,
  16. };
  17.  
  18. enum Command : uint8_t {
  19.     CONNECT = 0x01,
  20.     BIND = 0x02,
  21.     UDP_ASSOCIATE = 0x03,
  22. };
  23.  
  24. enum AddressType : uint8_t {
  25.     AT_IPV4 = 0x01,
  26.     AT_FQDN = 0x03,
  27.     AT_IPV6 = 0x04,
  28. };
  29.  
  30. enum Reply : uint8_t {
  31.     SUCCEEDED = 0x00,
  32.     FAILURE = 0x01,
  33.     NOT_ALLOWED = 0x02,
  34.     NETWORK_UNREACHABLE = 0x03,
  35.     HOST_UNREACHABLE = 0x04,
  36.     CONNECTION_REFUSED = 0x05,
  37.     TTL_EXPIRED = 0x06,
  38.     COMMAND_NOT_SUPPORTED = 0x07,
  39.     ADDRESS_NOT_SUPPORTED = 0x08,
  40. };
  41.  
  42. #pragma pack(push, 1)
  43.  
  44. struct socks5negotiation {
  45.     uint8_t         version;
  46.     uint8_t         nomethods;
  47.     AuthMethod      methods[1];
  48. };
  49.  
  50. struct socks5negotiationResponse {
  51.     uint8_t         version;
  52.     AuthMethod      method;
  53. };
  54.  
  55.  
  56. struct socks5_negotiation_header {
  57.     quint8 version;
  58. };
  59.  
  60. struct AuthResponse {
  61.     uint8_t authVersion = 0x01;
  62.     uint8_t authStatus;
  63. };
  64.  
  65.  
  66. struct IPv4 {
  67.     uint32_t ip;
  68.     uint16_t port;
  69. };
  70.  
  71. typedef uint8_t uint128_t[16];
  72.  
  73. struct IPv6 {
  74.     uint128_t   ip;
  75.     uint16_t    port;
  76. };
  77.  
  78. struct FQDN {
  79.     uint8_t bytes[4];
  80. };
  81.  
  82. union Destination {
  83.     IPv4 ipv4;
  84.     IPv6 ipv6;
  85.     FQDN fqdn;
  86. };
  87.  
  88. struct NegotiationRequest {
  89.     Version         version;
  90.     Command         command;
  91.     uint8_t         reserverd;
  92.     AddressType     addr_type;
  93.     Destination     dest;
  94. };
  95.  
  96. struct NegotiationResponse {
  97.     Version         version;
  98.     Reply           reply;
  99.     uint8_t         reserved;
  100.     AddressType     addr_type;
  101.     Destination     dest;
  102. };
  103.  
  104. #pragma pack(pop)
  105.  
  106.  
  107. AuthMethod getSupportedMethod(const AuthMethod *methods, uint8_t nomethods) {
  108.     for (uint8_t i = 0; i != nomethods; ++i) {
  109.         if (methods[i] == AuthMethod::PASSWORD) {
  110.             return AuthMethod::PASSWORD;
  111.         }
  112.     }
  113.  
  114.     return AuthMethod::NO_ACCEPTABLE;
  115. }
  116.  
  117. #include <winsock.h>
  118. #pragma comment(lib, "Ws2_32.lib")
  119.  
  120. void Worker::readyRead()
  121. {
  122.     QByteArray request = socket->read(1);
  123.     auto requestHeader = reinterpret_cast<socks5_negotiation_header*>(request.data());
  124.  
  125.     qDebug() << "HEADER" << requestHeader->version;
  126.     if(requestHeader->version == Version::SOCKS5 && !clientIsAuthenticated) {
  127.  
  128.         request.append(socket->readAll());
  129.         if(request.size() == 4) {
  130.  
  131.             auto header = reinterpret_cast<socks5negotiation*>(request.data());
  132.             auto method = getSupportedMethod(header->methods, header->nomethods);
  133.  
  134.             qDebug() << "[ Client sent SOCKS Version:" <<header->version << "]";
  135.  
  136.             if(header->version != 0x05) {
  137.                 socket->close();
  138.                 return;
  139.              }
  140.              else if(method != AuthMethod::PASSWORD) {
  141.                  qDebug() << "[ Close connection: Client sent authentication without password. ]";
  142.                  socket->close();
  143.                  return;
  144.              }
  145.  
  146.              auto res = reinterpret_cast<socks5negotiationResponse*>(request.data());
  147.              res->method = method;
  148.              res->version = Version::SOCKS5;
  149.              socket->write(request.data(), request.size());
  150.         }
  151.     }
  152.     else if(requestHeader->version == 0x01){
  153.  
  154.         qDebug() << "[ Reading Username / Password ]";
  155.  
  156.         uint8_t username_len = qFromLittleEndian<uint8_t>(socket->read(1));
  157.         QString username = socket->read(username_len);
  158.  
  159.         uint8_t password_len = qFromLittleEndian<uint8_t>(socket->read(1));
  160.         QString password = socket->read(password_len);
  161.  
  162.         qDebug() << "Username" << username;
  163.         qDebug() << "Password" << password;
  164.  
  165.         AuthResponse authReply;
  166.         if(username.compare("Kevin") || password.compare("MitNick")) {
  167.  
  168.             qDebug() << "[ Client sent wrong credentials ]";
  169.  
  170.             authReply.authStatus = Status::FORBIDDEN;
  171.             socket->write((char*)&authReply, sizeof(authReply));
  172.             socket->close();
  173.             return;
  174.         }
  175.  
  176.         qDebug() << "[ Client authentication success ]";
  177.         authReply.authStatus = Status::SUCCESS;
  178.         socket->write((char*)&authReply, sizeof(authReply));
  179.         clientIsAuthenticated = true;
  180.     }
  181.     else if(requestHeader->version == Version::SOCKS5 && clientIsAuthenticated) {
  182.  
  183.         qDebug() << "[ Client is sending negotiation request ]";
  184.         request.append(socket->readAll());
  185.         auto clientNegotiationRequest = reinterpret_cast<NegotiationRequest*>(request.data());
  186.         if(clientNegotiationRequest->command == Command::CONNECT) {
  187.  
  188.             qDebug() << "[ Client is requesting CONNECT ]";
  189.  
  190.             auto res = reinterpret_cast<NegotiationResponse *>(request.data());
  191.             res->version = Version::SOCKS5;
  192.             res->reply = Reply::SUCCEEDED;
  193.             res->reserved = 0;
  194.  
  195.             remoteEndpoint->connectToHost(QHostAddress(qFromBigEndian<quint32>(clientNegotiationRequest->dest.ipv4.ip)), qToBigEndian<quint16>(clientNegotiationRequest->dest.ipv4.port));
  196.             connect(remoteEndpoint, &QTcpSocket::connected, [=]() {qDebug() << "CONNECTED..........."; socket->write(request.data());  });
  197.                 connect(remoteEndpoint, &QTcpSocket::readyRead, [=]() { qDebug() << "WE HAVE DATA";
  198.                 QByteArray endpointData = remoteEndpoint->readAll();
  199.                 socket->write(endpointData);
  200.                 });
  201.  
  202.  
  203.  
  204.             qDebug() << "[ Sending negotiation request  ]";
  205.         }
  206.         else if(clientNegotiationRequest->command == Command::BIND) {
  207.  
  208.             qDebug() << "[ Client is requesting BIND ]";
  209.         }
  210.         else if(clientNegotiationRequest->command == Command::UDP_ASSOCIATE) {
  211.  
  212.              qDebug() << "[ Client is requesting UDP ASSOCIATE ]";
  213.         }
  214.     }
  215.     else if(clientIsAuthenticated) {
  216.         request.append(socket->readAll());
  217.  
  218.         qDebug() << "[ Server is sending us " << request.size() << "IP" << socket->peerAddress() << "]";
  219.         remoteEndpoint->write(request);
  220.  
  221.     }
  222.     else {
  223.         socket->close();
  224.     }
  225. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement