Попытка подключиться к серверу SOCKS 5 с использованием boost :: asio, но мой запрос на подключение оказывается некорректным - PullRequest
0 голосов
/ 31 января 2019

Я пытаюсь установить соединение SOCKS 5 (с прокси-сервером tor) в моем коде, но по какой-то причине мой запрос на соединение (после выбора метода приветствия и аутентификации) полностью искажен.

Я пытался использоватьGDB смотреть на значения в памяти, но это выглядит хорошо.также попытался распечатать информацию на консоль, которая мне тоже ничего не дала.

(адрес сайта с луком - просто пример)

main.cpp https://pastebin.com/zjHb7vg3

socks5.hpp https://pastebin.com/pksnqmfa Или просто создайте пакет с помощью функции

std::vector<boost::asio::const_buffer> conn(unsigned char cmd, unsigned char type, std::string hostname, int port) {
            int cmd_ = 0x04;
            int type_ = 0x03;
            std::vector<boost::asio::const_buffer> buffers = {
                //{
                    boost::asio::buffer(&version, 1),
                    boost::asio::buffer(&cmd_, 1),
                    boost::asio::buffer(&null_byte, 1),
                    boost::asio::buffer(&type_, 1)
                //}
            };

            std::cout << "Conn:" << cmd << std::endl << "type:" << type << std::endl;

            if (type_ == IPv4) {
                int byte1=0x5d, byte2=0xb8, byte3=0xd8, byte4=0x22;
                char dot;
                std::istringstream s(hostname);  // input stream that now contains the ip address string

                //s >> byte1 >> dot >> byte2 >> dot >> byte3 >> dot >> byte4 >> dot;
                // buffers.push_back(boost::asio::buffer({
                //     (unsigned char)byte1,
                //     (unsigned char)byte2,
                //     (unsigned char)byte3,
                //     (unsigned char)byte4
                // }));
                buffers.push_back(boost::asio::buffer(&byte1, 1));    
                buffers.push_back(boost::asio::buffer(&byte2, 1));            
                buffers.push_back(boost::asio::buffer(&byte3, 1));            
                buffers.push_back(boost::asio::buffer(&byte4, 1));            

            } else if (type_ == IPv6) {
                int byte1,
                    byte2,
                    byte3,
                    byte4,
                    byte5,
                    byte6,
                    byte7,
                    byte8,
                    byte9,
                    byte10,
                    byte11,
                    byte12,
                    byte13,
                    byte14,
                    byte15,
                    byte16;
                char sep;
                std::istringstream s(hostname);  // input stream that now contains the ip address string

                s >> 
                    byte1 >> sep >>
                    byte2 >> sep >>
                    byte3 >> sep >>
                    byte4 >> sep >>
                    byte5 >> sep >>
                    byte6 >> sep >>
                    byte7 >> sep >>
                    byte8 >> sep >>
                    byte9 >> sep >>
                    byte10 >> sep >>
                    byte11 >> sep >>
                    byte12 >> sep >>
                    byte13 >> sep >>
                    byte14 >> sep >>
                    byte15 >> sep >>
                    byte16;

                buffers.push_back(boost::asio::buffer({
                    (unsigned char)byte1,
                    (unsigned char)byte2,
                    (unsigned char)byte3,
                    (unsigned char)byte4,
                    (unsigned char)byte5,
                    (unsigned char)byte6,
                    (unsigned char)byte7,
                    (unsigned char)byte8,
                    (unsigned char)byte9,
                    (unsigned char)byte10,
                    (unsigned char)byte11,
                    (unsigned char)byte12,
                    (unsigned char)byte13,
                    (unsigned char)byte14,
                    (unsigned char)byte15,
                    (unsigned char)byte16
                }));
            } else if (type_ == Domain) {
                int hostnameLen = hostname.length();
                buffers.push_back(boost::asio::buffer(&hostnameLen, 1));
                buffers.push_back(boost::asio::buffer(hostname, 255));

                std::cout << hostnameLen << std::endl << hostname << std::endl;
            }

            unsigned char port_high_byte_ = (port >> 8) & 0xff;
            unsigned char port_low_byte_ = port & 0xff;

            buffers.push_back(boost::asio::buffer(&port_high_byte_, 1));
            buffers.push_back(boost::asio::buffer(&port_low_byte_, 1));

            std::cout << buffers[0].data();
            return buffers;
        }            

};

class reply {

    private:
        int hostnameLen;
        int hostname;
        int port_nbo;

        enum state {
            AUTH_CHOICE = 0,
            PASSWORD = 1,
            CONNECT = 2
        };

        state state;

    public:

        unsigned char ver;
        unsigned char auth;
        unsigned char auth_ver;
        unsigned char status_;
        addr_type type;

        bool success() {
            return ver == version &&
                (state == AUTH_CHOICE ? state == NO_AUTH || state == PASSWORD : true) &&
                (state == PASSWORD ? status_ == 0x00 : true) &&
                (state == CONNECT ? status_ == 0x00 : true);
        }

        std::string status() const {
            if (state == AUTH_CHOICE) {
                if (auth == 0xFF) {
                    return "No acceptable auth methods";
                }
            } else if (state == PASSWORD) {
                return status_ == 0x00 ? "Auth success" : "Auth error: "+std::to_string(status_);
            } else if (state == CONNECT) {
                return status_ == 0x00 ? "Connect success" : "Connect error: "+std::to_string(status_);
            }
            return "";
        }

        std::array<boost::asio::mutable_buffer, 5> auth_choice() {
            state = AUTH_CHOICE;
            return {
                {
                    boost::asio::buffer(&ver, 1),
                    boost::asio::buffer(&auth, 1)
                }
            };
        }

        std::array<boost::asio::mutable_buffer, 5> password_verif() {
            state = PASSWORD;
            return {
                {
                    boost::asio::buffer(&auth_ver, 1),
                    boost::asio::buffer(&status_, 1)
                }
            };
        }

        std::vector<boost::asio::mutable_buffer> connect_reply() {
            state = CONNECT;
            std::vector<boost::asio::mutable_buffer> buffers = {
                {
                    boost::asio::buffer(&ver, 1),
                    boost::asio::buffer(&status_, 1),
                    boost::asio::buffer(&null_byte, 1),
                    boost::asio::buffer(&type, 1)
                }
            };

            if (type == IPv4) {
                buffers.push_back(boost::asio::buffer(&hostname, 4));
            } else if (type == IPv6) {
                buffers.push_back(boost::asio::buffer(&hostname, 16));
            } else if (type == Domain) {
                buffers.push_back(boost::asio::buffer(&hostnameLen, 1));
                buffers.push_back(boost::asio::buffer(&hostname, 255));
            }

            buffers.push_back(boost::asio::buffer(&port_nbo, 2));

            return buffers;
        }         

захват Wireshark: (используйте фильтр просмотра "socks") https://quickfileshare.org/1Kjr/socks-capture.pcapng

1 Ответ

0 голосов
/ 31 января 2019

boost::asio::write(socket, socks_request.conn(socks5::request::connect, socks5::addr_type::Domain, hostname, port));

мы можем разделить этот код на:

[1] get buffers
std::vector<boost::asio::const_buffer> buffs = 
socks_request.conn(socks5::request::connect, socks5::addr_type::Domain, hostname, port);
[2] send data
boost::asio::write(socket, buffs);

в conn у нас есть много локальных переменных, которые передаются в boost::asio::buffer.Что делает buffer?Он возвращает упаковщик для данных , подробности здесь , который состоит из pointer to data и длины данных. Данные не копируются .Таким образом, когда conn заканчивается, у вас есть вектор буферов, которые ссылаются на данные, которые были уничтожены - неопределенное поведение.

Вам необходимо найти новый подход для отправки данных или предоставить действительные данные, когда boost::asio::write используетбуфер к ним.

...