Friday 21 December 2018

Using Curl lib to retrieve CSRF token from server response set-cookie, set CSRF header, retrieve logged in session from server response set-cookie

   // Init
            $ch = curl_init();
            $cookies = array(); 

            /* Fetch CSRFTOKEN from Server response header by visting login page */
            $request_headers = array(
                'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
                'Accept-Encoding: gzip, deflate, br',
                'Accept-Language: en-US,en;q=0.9',
                'Cache-Control: no-cache',
                'Connection: keep-alive',
                "Host:{$url}",
                'Pragma: no-cache',
                "Referer: https://{$url}/",
                'Upgrade-Insecure-Requests: 1',
                'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
            );

            curl_setopt($ch, CURLOPT_URL, "https://{$url}/login/");
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
            // Set request header
            curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
            // Get response header
            curl_setopt($ch, CURLOPT_HEADER, TRUE);
            $result = curl_exec($ch);
            if (curl_errno($ch)){
                throw new \Exception('Retreive CSRF token failed -> ' . curl_error($ch));
            }
            // Get cookie instruction from the server response
            preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $result, $matches);
            foreach ($matches[1] as $item) {
                parse_str($item, $cookie);
                $cookies = array_merge($cookies, $cookie);
            }       

            if (empty($cookies['csrftoken'])) {
                throw new \Exception('Unable to obtain CSRF token from server response.');           
            }

            /* Login */
            $request_headers = array(
                'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
                'Accept-Encoding: gzip, deflate, br',
                'Accept-Language: en-US,en;q=0.9',
                'Cache-Control: no-cache',
                'Connection: keep-alive',
                "Cookie: csrftoken={$cookies['csrftoken']}",
                'Content-Type: application/x-www-form-urlencoded',
                "Host: {$url}",
                "Origin: https://{$url}",
                'Pragma: no-cache',
                "Referer: https://{$url}/",
                'Upgrade-Insecure-Requests: 1',
                'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
            );

            $post_values = array(
                              'username'            => $username,
                              'password'            => $pwd,
                              'next'                => '/'
                            );

            curl_setopt($ch, CURLOPT_URL, "https://{$url}/login/" );
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_values));

            $result = curl_exec($ch);
            if (curl_errno($ch)){
                throw new \Exception('Login to FortiAuthenticator failed -> ' . curl_error($ch));
            }

            preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $result, $matches);
            foreach ($matches[1] as $item) {
                parse_str($item, $cookie);
                $cookies = array_merge($cookies, $cookie);
            }

            if ( ! empty($cookies['sessionid'])) {
                $is_logged_in = TRUE;
            }

No comments:

Post a Comment