How to get information for a form from Twitter?

1

Yesterday I did this question here in SoPT , I'm now following what the Inkeliz said:

  

Cookies will only be obtained if you apply using login / password. To do this, just go to the Twitter page and see what URL is called (ie F12 & Network) and make the request using cURL, it is able to send the information to the browser. The official API of Twitter does not use cookies, even because you get other people's login / password is not safe, so there is OAuth, officially made available by Twitter.

The question is how can I do this? Would you do it using TwitterOAuth?

Someone would give an example of how to make this request, using f12 > Tetwork ?

My authentication code is this:

<?php

class Auth {

    public function signedIn() {

        if (isset($_SESSION['twitter_access_token'])) {
            $access_token = $_SESSION['twitter_access_token'];

            $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']);

            $user = $connection->get('account/verify_credentials');

            return $user;
        }

        return false;
    }

    public function getAuthUrl() {

        $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET);

        $request_token = $connection->getRequestToken(OAUTH_CALLBACK);

        if($request_token){
            $token = $request_token['oauth_token'];

            $_SESSION['oauth_token'] = $token ;
            $_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret'];

            $auth_url = $connection->getAuthorizeURL($token);
        }

        return $auth_url;
    }

    public function getAccessToken() {

        $request_token = [];
        $request_token['oauth_token']           = $_SESSION['oauth_token'];
        $request_token['oauth_token_secret']    = $_SESSION['oauth_token_secret'];

        if (isset($_GET['oauth_token']) && $request_token['oauth_token'] !== $_GET['oauth_token']) {
            die('Error: Something went wrong...');
        }

        $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $request_token['oauth_token'], $request_token['oauth_token_secret']);

        $access_token = $connection->getAccessToken($_REQUEST['oauth_verifier']);

        if (empty($access_token)) {
            die('Error: Invalid access token...');
        }

        return $access_token;
    }

    public function logout() {
        session_destroy();
        header('Location:' . URL_BASE);
    }

}

The question now is how to get the data, comparing user = oauth_token and password = oauth_token_secret and confirm on the form?

<form method="post">
  <div class="form-group">
    <input type="text" name="ttrUsername" placeholder="Usuário do Twitter" class="form-control">
  </div>
  <div class="form-group">
    <input type="password" name="ttrPassword" placeholder="Senha do Twitter" class="form-control">
  </div>

  <button type="submit" name="ttrSignin" class="btn btn-primary btn-block">
    <i class="fa fa-twitter"></i> Entrar agora
  </button>
</form>

This is my form:

IgotthefollowingcURL

curl"https://twitter.com/"
-H "accept-encoding: gzip, deflate, br"

-H "accept-language: pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4"

-H "upgrade-insecure-requests: 1"

-H "user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.109 Safari/537.36"

-H "accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"

-H "cache-control: max-age=0"

-H "authority: twitter.com"

-H "cookie: guest_id=v1^%^3A149848156157534036; privacy_2017=1; lang=pt; eu_cn=1; ct0=3dae64dcfd1d4e31e6b9f749eaff5f1c; _gat=1; ads_prefs=^\^"HBERAAA=^\^"; kdt=6F5z2H1dYzkK2dxVkhDommOOBWmYJiXTdCCbRZGE; remember_checked_on=1; twid=^\^"u=866687457990979584^\^"; auth_token=115ba1614d21781e601769c512a48bccc7bda89b; _ga=GA1.2.1124081759.1498481564; _gid=GA1.2.126286429.1498481564; _twitter_sess=BAh7CiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo^%^250ASGFzaHsABjoKQHVzZWR7ADoPY3JlYXRlZF9hdGwrCOgPduRcAToMY3NyZl9p^%^250AZCIlZWM4NWI1ZTZiMDk5Yzg4MDZmM2NhNGE4MTA5MGZmODY6B2lkIiVlM2I4^%^250AMTRmNDA4NTZlYTkyYzI1Y2Y3NDE1NTE2ZjYwYjoJdXNlcmwrCQCw1rCmFwcM--b7e62a94a232a36015e8959d2391af44b9b2b753"

-H "referer: https://twitter.com/login/error?redirect_after_login=^%^2F" --compressed

I've made the following scheme, and it's returning the twitter login page:

<?php

# First call gets hidden form field authenticity_token
# and session cookie
$ch = curl_init();
$sTarget = "https://twitter.com/";
curl_setopt($ch, CURLOPT_URL, $sTarget);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_COOKIEFILE, "/tmp/cookie.txt");
curl_setopt($ch, CURLOPT_REFERER, "https://twitter.com/");
$html = curl_exec($ch);

# parse authenticity_token out of html response
preg_match('/<input type="hidden" value="([a-zA-Z0-9]*)" name="authenticity_token"\/>/', $html, $match);
$authenticity_token = $match[1];



$username = "[email protected]";
$password = "password";

# set post data
$sPost = "session[username_or_email]=$username&session[password]=$password&return_to_ssl=true&scribe_log=&redirect_after_login=%2F&authenticity_token=$authenticity_token";

# second call is a post and performs login
$sTarget = "https://twitter.com/sessions";
curl_setopt($ch, CURLOPT_URL, $sTarget);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $sPost);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: application/x-www-form-urlencoded"));

# display server response
curl_exec($ch);
curl_close($ch);
?>
    
asked by anonymous 26.06.2017 / 23:29

1 answer

2
  

This response is before editing, based on comment .

If you want an example, then suppose you have website X, which uses this code:

<?php
/**
 * NÃO UTILIZE ESTE CÓDIGO EM PRODUÇÃO!
 */

session_start();

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    if (isset($_POST['nome'], $_POST['senha'], $_POST['csrf'], $_SESSION['csrf'])
        && hash_equals($_POST['csrf'], $_SESSION['csrf'])
    ) {

        if (hash_equals($_POST['senha'], '123456789')) {
            $_SESSION['nome'] = $_POST['nome'];
        }

    }

}


if ($_SERVER['REQUEST_METHOD'] === 'GET') {

    $_SESSION['csrf'] = $_SESSION['csrf'] ?? base64_encode(random_bytes(64));

    if (isset($_SESSION['nome'])) {

        echo 'Você está logado usando o nome de ', $_SESSION['nome'];

    } else {


        echo '<form method="post">';

        echo '<input name="nome" type="text" placeholder="Nome">';
        echo '<br>';
        echo '<input name="senha" type="password" placeholder="Senha">';
        echo '<br>';
        echo '<input name="csrf" type="hidden" value="' . $_SESSION['CSRF'] . '">';
        echo '<input name="enviar" type="submit">';

        echo '</form>';

    }

}

So he has three things:

  • If POST and correct login: set the session.
  • If it's GET:

  • You are logged in (there is a session containing Nome ): show your name.
  • Disconnected: Displays the form.
  • Assuming you know the basics of how HTTP works and you understand cURL minimizer, then:

    curl -X GET http://127.0.0.1/login.php -v
    

    Will return the same result as when we accessed via browser, the most important in this case are two things:

    < Set-Cookie: PHPSESSID=3qsmtd817pof4ucngd3f9tjf1e; path=/
    

    This is cookie sent by the server to the client, then we have input containing csrf-token , in:

    <input name="csrf" type="hidden" value="6kYwBSjY8lfKcXefUau3r6apgcY3fsjEbEhiPjlt1lxZwXuwDzJeYh6F1WyW4q/kycj4/YczxHxXC0t0YtUmhg==">
    

    But, we still need to see where the data is sent, ignoring the html form , in the console under "Network" clicking on "Send" shows which page is called and which method and which headers.

    Then we do the same in CURL:

    curl ^
    -X POST ^
    -d "nome=Inkeliz&senha=123456789&csrf=6kYwBSjY8lfKcXefUau3r6apgcY3fsjEbEhiPjlt1lxZwXuwDzJeYh6F1WyW4q/kycj4/YczxHxXC0t0YtUmhg==" ^
    -H "Cookie: PHPSESSID=3qsmtd817pof4ucngd3f9tjf1e" ^
    http://127.0.0.1/login.php -v
    
      

    Meanings:

    • -X defines the method (it's redundant in this case!).
    • -d defines the "body" of the request, in this case it is x-www-form-urlencoded .
    • -H sets the header, in the case of the previously obtained cookie.
    • -v displays the entire send and reply header and other information, such as handshake in the case of HTTPS.

    Now that we've used the same cookie:

    curl ^
    -X GET ^
    -H "Cookie: PHPSESSID=3qsmtd817pof4ucngd3f9tjf1e" ^
    http://127.0.0.1/login.php
    

    We'll get:

    Você está logado usando o nome de Inkeliz
    

    How to do this in PHP there are two steps.

    First we need to get the CSRF-Token (and the cookie, which is directly related to the CSRF-Token):

    $cookie = '';
    $csrf = '';
    
    $PegarCSRFToken = curl_init('http://127.0.0.1/login.php');
    
    curl_setopt_array($PegarCSRFToken, [
            CURLOPT_CUSTOMREQUEST => 'GET',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HEADERFUNCTION => function($curl, $cabeçalho) use (&$cookie){
    
                if(stripos($cabeçalho, 'Set-Cookie:') === 0){
                    if(preg_match('/Set-Cookie:\s?(.*?);/i', $cabeçalho, $matches)) {
                        $cookie .= $matches[1] . '; ';
                    }
                }
    
                return strlen($cabeçalho);
            }
        ]
    );
    
    $PegarCSRFToken = curl_exec($PegarCSRFToken);
    
    if(preg_match('/name="csrf".*?value="(.*?)"/', $PegarCSRFToken, $matches)){
    
        $csrf = $matches[1];
    
    }
    

    I think it's easy to understand, obviously it can be improved, but the point is:

  • It fetches the cookie and stores it in $cookie using CURLOPT_HEADERFUNCTION , extracting using preg_match on Set-Cookie: sent by the server.

  • It gets CSRF-Token using preg_match in the result of the page, in the HTML itself.

  • Now, with both contents in hand we can login:

    $EnviarLoginSenha = curl_init('http://127.0.0.1/login.php');
    
    curl_setopt_array($EnviarLoginSenha, [
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POSTFIELDS => [
                'nome' => 'inkeliz',
                'senha' => '123456789',
                'csrf' => $csrf,
            ],
            CURLOPT_HTTPHEADER => [
                'Cookie: '.$cookie
            ]
    ]);
    
    curl_exec($EnviarLoginSenha);
    

    The CURLOPT_HTTPHEADER is equivalent to -H and CURLOPT_POSTFIELDS when entered an array is equivalent to -d . So we can do any action as if it were logged in, based on cookies, soon:

    $AcessarLogado = curl_init('http://127.0.0.1/login.php');
    
    curl_setopt_array($AcessarLogado, [
        CURLOPT_CUSTOMREQUEST => 'GET',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            'Cookie: '.$cookie
        ]
    ]);
    
    echo curl_exec($AcessarLogado);
    

    Will return:

    Você está logado usando o nome de inkeliz
    

    The basic concept is this, it can be applied in any case. It is obvious that other validations can be made, such as having to inform a valid UA and the like.

        
    27.06.2017 / 03:09