Curl Friendships/create, bad Authentication data

Asked

Viewed 303 times

4

Good with the help of the Inkeliz, made in this question, i got authentication with Twitter via form.

Filing cabinet login.php:

<?php

require_once '../modules/config.php';
require_once '../modules/class/Cookies.php';

$cookie = [];

$username = trim(filter_input(INPUT_POST, 'username'));
$password = trim(filter_input(INPUT_POST, 'password'));

$index_url = 'https://twitter.com';

$token = curl_init();
curl_setopt_array($token, [
      CURLOPT_URL             => $index_url,
      CURLOPT_CUSTOMREQUEST   => 'GET',
      CURLOPT_RETURNTRANSFER  => true,
      CURLOPT_SSL_VERIFYPEER  => false,
      CURLOPT_SSL_VERIFYHOST  => 2,
      CURLOPT_USERAGENT       => $_SERVER['HTTP_USER_AGENT'],
      //CURLOPT_COOKIEFILE      => __DIR__ . DIRECTORY_SEPARATOR . 'cookies' . DIRECTORY_SEPARATOR . $username . '.txt',
      CURLOPT_COOKIEJAR       => __DIR__ . SEPARATOR . 'cookies' . SEPARATOR . $username . '.txt',
      CURLOPT_COOKIESESSION   => true,
      CURLOPT_REFERER         => $index_url,
      CURLOPT_HEADER          => true,
      CURLOPT_HTTPHEADER      => ['Cookie:' . http_build_query($cookie, '', ';') . ';'],
      CURLOPT_HEADERFUNCTION => function ($curl, $header) use (&$cookie) {
        if (stripos($header, 'Set-Cookie:') === 0) {
          if (preg_match('/Set-Cookie:\s?(.*?)=(.*?);/i', $header, $matches)) {
            $cookie[$matches[1]] = urldecode($matches[2]);
          }
        }
        return strlen($header);
      }
    ]
);    
$access = curl_exec($token);

preg_match('/value="(.*?)" name="authenticity_token"/', $access, $matches);

$authenticity_token = $matches[1];

$session_post = "session[username_or_email]=$username&session[password]=$password&return_to_ssl=true&scribe_log=&redirect_after_login=%2F&authenticity_token=$authenticity_token";

$session_url = 'https://twitter.com/sessions';

curl_setopt_array($token, [
      CURLOPT_URL             => $session_url,
      CURLOPT_CUSTOMREQUEST   => 'POST',
      CURLOPT_POSTFIELDS      => $session_post,
      CURLOPT_RETURNTRANSFER  => true,
      CURLOPT_HTTPHEADER      => [
        "Content-type: application/x-www-form-urlencoded",
        'Cookie: '. http_build_query($cookie, '', ';').';',
      ],
      CURLOPT_USERAGENT       => $_SERVER['HTTP_USER_AGENT'],
      CURLOPT_HEADER          => true,
      CURLOPT_FOLLOWLOCATION  => true,
      CURLOPT_MAXREDIRS       => 2,
      CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
      CURLOPT_POSTREDIR       => 2,
      CURLOPT_AUTOREFERER     => 1
  ]

);
$auth = curl_exec($token);

if (isset($cookie['auth_token']))
{
  $twid = filter_var($cookie['twid'], FILTER_SANITIZE_NUMBER_INT);

  Cookies::set('login_token', $cookie['ct0']);
  Cookies::set('kdt', $cookie['kdt']);
  Cookies::set('user_id', $twid);
  Cookies::set('auth_token', $cookie['auth_token']);
  Cookies::set('username', $username);

  $_SESSION[SITE_TITLE . '_session'] = $username;

  echo json_encode(array(
    "status"      => "success",
    "message"     => "Autenticação bem sucedida, estamos te redirecionando.",
  ));
}
else
{
  echo json_encode(
    array(
      "status" => "error",
      'message'=> "Não foi possível autenticar com o Twitter.",
    ));
}

Note that saved two tokens in cookies: auth_token and login_token, being auth_token = $authenticity_token; and login_token = cookie[ct0], ct0 comes from Twitter.

Login is ok, then I have the cURL to obtain information from the logged-in user, who was also able to do so with the help of of my question and answered by Anderson Carlos Woss, is also ok, I recover, screen_name, name, foto, among others...

Now comes my question, I know that to use the API you need a token, and also know that this token is the cookie ct0, but I don’t know how to use it, see my code.

Filing cabinet, Friend.php

<?php

require_once '../modules/config.php';
require_once '../modules/class/Cookies.php';


$username = Cookies::get('username');

$friend_url = 'https://api.twitter.com/1.1/friendships/create.json';

$friend = curl_init();

curl_setopt_array($friend, [
        CURLOPT_URL             => $friend_url,
        CURLOPT_SSL_VERIFYPEER  => 1,
        CURLOPT_SSL_VERIFYHOST  => 2,
        CURLOPT_CAINFO          => ROOT . 'modules' . SEPARATOR . 'cacert' . SEPARATOR . 'cacert-2017-06-07.pem',
        CURLOPT_CUSTOMREQUEST   => 'POST',
        CURLOPT_POSTFIELDS      => 'screen_name=' . $username,
        CURLOPT_USERAGENT       => $_SERVER['HTTP_USER_AGENT'],
        CURLOPT_COOKIEJAR       => __DIR__ . SEPARATOR . 'cookies' . SEPARATOR . $username . '.txt',
        CURLOPT_COOKIESESSION   => true,
        CURLOPT_RETURNTRANSFER  => true,
        CURLOPT_HTTPHEADER      => [
            "Content-type: application/json; charset=utf-8",
      ],
        CURLOPT_HEADER          => 0,
    ]

);

$response  = curl_exec($friend);

var_dump($response);

When running the code in the browser returns the error 215 Bad Authentication data.

Good as I know it’s the cookie[ct0] what should I use? , Take a look at this question on ONLY ENGLISH, much (gambiarra) that I’m sure only with cURL, resolves.

EDIT 1

Class Cookie.php

<?php

class Cookies {
    private static $storage = array();

    public static function get($key) {

        if( isset($_COOKIE[$key])) {
            return $_COOKIE[$key];
        } else {
            if(isset(static::$storage[$key])) {
                return static::$storage[$key];
            }

        }
    }

    public static function set($key, $value) {
        static::$storage[$key] = $value;
        setcookie($key, $value, time() + (2 * 3600), '/');
    }

    public static function remove($key, $value) {
        setcookie($key, $value, time()-3600, '/');
    }
}

EDIT 2

In accordance with Inkeliz mentioned in the comments the token is in a JS file, and I was able to extract this token, but how should I use it now? anyone have any idea? See my code:

require_once './system/config.php';

$TwitterUser = null;

if (isset($_SESSION[SITE_TITLE . '_SESSION'])) {
    $TwitterUser = $_SESSION[SITE_TITLE . '_SESSION'];
}

$twitter_url_js = 'https://abs.twimg.com/k/pt/init.pt.8a8c7bc568e38012a94b.js';

$getToken = curl_init();
curl_setopt_array($getToken, [
        CURLOPT_URL                         => $twitter_url_js,
        CURLOPT_CUSTOMREQUEST   => 'GET',
        CURLOPT_RETURNTRANSFER  => true,
        CURLOPT_SSL_VERIFYPEER  => false,
        CURLOPT_SSL_VERIFYHOST  => 2,
        CURLOPT_USERAGENT               => $_SERVER['HTTP_USER_AGENT'],
        CURLOPT_HEADER                  => true,
    ]
);

$token = curl_exec($getToken);

preg_match('/\"([A-z0-9%]{114})\";/', $token, $matches);

$auth_token = $matches[1];

$friend_post = http_build_query([
        'screen_name' => $TwitterUser
    ]
);

$twitter_friend_url = 'https://api.twitter.com/1.1/friendships/create.json';

curl_setopt_array($getToken, [
        CURLOPT_URL                         => $twitter_friend_url,
        CURLOPT_CUSTOMREQUEST       => 'POST',
        CURLOPT_POSTFIELDS          => $friend_post,
        CURLOPT_RETURNTRANSFER  => true,
        CURLOPT_SSL_VERIFYPEER  => false,
        CURLOPT_SSL_VERIFYHOST  => 2,
        CURLOPT_USERAGENT               => $_SERVER['HTTP_USER_AGENT'],
        CURLOPT_HEADER                  => true,
    ]
);

$friend = curl_exec($getToken);

var_dump($friend);

Good with the var_dump($friend); I receive as an answer this:

'HTTP/1.1 400 Bad Request
content-length: 62
content-type: application/json; charset=utf-8
date: Sun, 16 Jul 2017 23:41:51 GMT
server: tsa_d
set-cookie: guest_id=v1%3A150024851187284588; Domain=.twitter.com; Path=/; Expires=Tue, 16-Jul-2019 23:41:51 UTC
strict-transport-security: max-age=631138519
x-connection-hash: 8c0410547b9456c4ac13f360b8c8dbc3
x-response-time: 132
x-tsa-request-body-time: 0

{"errors":[{"code":215,"message":"Bad Authentication data."}]}' (length=472)

EDIT 3

I exchanged some information on HTTP now call me back 200 OK:

$twitter_friend_url = 'https://api.twitter.com/1.1/friendships/create.json';

curl_setopt_array($getToken, [
        CURLOPT_URL                         => $twitter_friend_url,
        CURLOPT_CUSTOMREQUEST       => 'OPTIONS',
        CURLOPT_HTTPHEADER          => [
      'Access-Control-Request-Method: POST',
      'Access-Control-Request-Headers: authorization,x-csrf-token,x-twitter-active-user,x-twitter-auth-type',
      'DNT: 1',
      'Origin: https://twitter.com' 
        ], 
        CURLOPT_RETURNTRANSFER  => true,
        CURLOPT_SSL_VERIFYPEER  => false,
        CURLOPT_SSL_VERIFYHOST  => 2,
        CURLOPT_USERAGENT               => $_SERVER['HTTP_USER_AGENT'],
        CURLOPT_HEADER                  => true,
    ]
);

$friend = curl_exec($getToken);

var_dump($friend);
  • This token is not a cookie, this token is in the Twitter JS and this javascript needs the cookie. :)

  • Any idea how to do it? @Inkeliz

  • What would be the difficulty? The token is here (https://abs.twimg.com/k/pt/init.pt.8a8c7bc568e38012a94b.js), just search for "AAAAAAAAAAAA", I believe a /\"([A-z0-9%]{114})\";/ solve the case. Already CT0 is used for CSRF-Token, I believe. I don’t know if the name of this JS changes, so if you can’t access see the traffic (F12 > Network) and see the first JS that is usually obtained, with the prefix of init..

  • @Inkeliz, yes I tried, the difficulty is that I can’t use the token with Curl, if you have a basic answer to my question, I can put my code in the Mediafire tomorrow for you to take a closer look.

  • @Inkeliz edited my question, see that I extracted the token as you mentioned in the comments, but how to use Curl to do what I need? without those gambiarras used in the question in Sous, well, for more details I need an answer, I believe you have.

1 answer

0


If you monitored the information sent to Twitter then you should have noticed the presence of the headers of authorization, x-csrf-token, x-twitter-active-user and x-twitter-auth-type.

All of them are not present in your code.


You need to use something like:

CURLOPT_HTTPHEADER => [
  'origin: https://twitter.com',
  'cookie: ' . $todos_os_cookies_do_twitter,

  'authorization: Bearer ' . $auth_token,
  'x-csrf-token: ' . $ct0,

  'x-twitter-auth-type: OAuth2Session',
  'x-twitter-active-user: yes',

  'referer: https://twitter.com',
]

whereas the $ct0 is the value of the cookie with the name of ct0.

Already the $auth_token is the token that is "embedded" within the JS (could use the preg_match('/\"([A-Z0-9%]{114})\";/i', $token, $matches);, that what you’re using in the code).

The $todos_os_cookies_do_twitter is all the cookies you have from Twitter.

This authorization apparently always begins by AAAAAAAAAAAAAAAAAAAAA, what makes it easy to find it on JS.

Besides of course must make the request as POST and not OPTIONS. The OPTIONS is used as prefight. Then you must use CURLOPT_CUSTOMREQUEST => 'POST' or CURLOPT_POST => 1.

Then you need to define the CURLOPT_POSTFIELDS with the data, something that tests different in your code. In case use exactly as Twitter uses, it is:

    CURLOPT_POSTFIELDS => http_build_query(
        ['challenges_passed' => false,
        'handles_challenges' => 1,
        'include_blocked_by' => true,
        'include_blocking' => true,
        'include_can_dm' => true,
        'include_followed_by' => true,
        'include_mute_edge' => true,
        'skip_status' => true,
        'user_id' => $id_twitter_quem_quer_seguir
    ], '', '&', PHP_QUERY_RFC3986),

I don’t know what the variables indicate, except the last user_id which is who you want to follow, for example I used 83430421, finally the $id_twitter_quem_quer_seguir must be the user ID that will receive the follower.


Also make sure that the $auth_token that is correct.

  • All right, but I still get paid {"errors":[{"code":32,"message":"Could not authenticate you."}]}' (length=485), but 200 ok in friendships/create and in the token of JS, knows the solution to this?

  • I tested here, there is no error. I will edit to include all headers instead of the //....

  • is not going is returning HTTP/1.1 401 Authorization Required&#xA;

  • This is because the access token is incorrect. The other ("could not authenticate you") is when cookies are not sent. Apparently.

  • Vixe, I have everything, I’m going to put my Pastebin code. It was supposed to work.

  • see : https://pastebin.com/s82ndBKa

  • Cookies are clearly wrong. Cookies should be in format nome=valor; outro_nome=outro_valor;, so it’s used ['Cookie:' . http_build_query($cookie, '', ';') . ';'] in its own code, which was an answer I gave some time ago. This is done precisely to make nome_do_cookie=valor;. The separator is ; instead of &.

  • see: print1: http://prntscr.com/fy7u59, print2: http://prntscr.com/fy7ufa. I’m almost sure right?

  • Read the documentation would avoid most errors, seriously, since the Curl already tells how you expect cookies. The http_build_query expects an array, ie http_build_query($_COOKIE, '', ';') . ';' ; already does everything, excluding the applicable security problems.

  • Forgive me, I read the documentation and fixed and did not warn you, I did the way you put there solved, however HTTP/1.1 403 Forbidden&#xA;; is returned now. MDS one problem after another.

  • What is the text? If it is You can't follow yourself. is because you are trying to follow yourself, due to what you defined in $user_id = Cookies::get('twid');. The $id_twitter_quem_quer_seguir is the ID of want you want to follow and not the ID of who is connected.

  • I tidied up, grateful @Inkeliz, now I will leave for logic tokens saved in DB follow connected users.

Show 7 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.