0

I found a script and modified it, hoping to returrn the contents of a login page. However, it seems that the page won't let me log in.

using var_dump($_POST); and print_r($_POST); gives me a blank array:

array(0) {
}

Array
(
)

So I don't know how to do it. The website is https://create.kahoot.it/login

This is the code I am running:

<?php
$username = 'USERNAME';
$password = 'PASSWORD';
$loginUrl = 'https://create.kahoot.it/login';


//init curl
$ch = curl_init();

//Set URL 
curl_setopt($ch, CURLOPT_URL, $loginUrl);
//HTTPS
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
// ENABLE HTTP POST
curl_setopt($ch, CURLOPT_POST, 1); 
//try to echo post variables
var_dump($_POST); 
print_r($_POST);
//Set the post parameters
curl_setopt($ch, CURLOPT_POSTFIELDS, 'user='.$username.'&pass='.$password);

//Handle cookies
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');

//Setting CURLOPT_RETURNTRANSFER variable to 1 will force cURL
// to return the results as a string return value
//from curl_exec() instead of the usual true/false.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

//login
$store = curl_exec($ch);
//put page details in file
file_put_contents("test.txt",$store);

?>

--EDIT--

  • response headers + authentication page stuff enter image description here

  • by changing the postman from POST to GET it returns {"error":"Authentication failed","exception":"Authentication failed","error_description":"Authentication token of type [class no.mobitroll.core.security.shiro.tokens.SessionToken] could not be authenticated by any configured realms. Please ensure that at least one realm can authenticate these tokens.","timestamp":1499789957919,"duration":0,"errorCode":0}

user7903682
  • 199
  • 1
  • 1
  • 18
  • 1
    well, if you actually watched what that form is doing (via your network tab), when you submit the form it sends the POST request to https://create.kahoot.it/rest/authenticate, not the URL you've got above - that's only the landing page containing the form. Forms don't have to post back to themselves! 405 means method not allowed, and given that the URL there is just a form, it's understandable that they don't allow POSTs to it. Of course there's no guarantee changing the URL will work, they might have anti-spoofing measures in place, but you can only try. – ADyson Jul 11 '17 at 14:12
  • I get a `301 Moved Permanently`, but we are moving in the right direction! All my details were empty still, though – user7903682 Jul 11 '17 at 14:18
  • normally a 301 response will contain a link to the location the resource was moved to. e.g. `HTTP/1.1 301 Moved Permanently Location: http://www.example.org/index.asp`. A browser would respond to this automatically and request that new URL immediately, but cURL does not do that. You need to extract that location (either programatically each time, or by hand and then change your script to hard-code the new URL) and POST to that instead. – ADyson Jul 11 '17 at 14:27
  • Well, It doesn't tell me a URL unless `openresty/1.11.2.2` is it. – user7903682 Jul 11 '17 at 14:31
  • The full html returned is: ` 301 Moved Permanently

    301 Moved Permanently


    openresty/1.11.2.2
    `
    – user7903682 Jul 11 '17 at 14:31
  • it's usually in a "Location" header, not in the response body. Do it manually on the website, like a normal user, with your browser's network tab open, or using an intermediary tool like Fiddler might be easier. Watch what happens, you can see the sequence of requests and responses that happen, and then you know what you need to emulate. – ADyson Jul 11 '17 at 14:31
  • I'm sorry, I don't understand what a `location header` is. Can we output that from PHP? – user7903682 Jul 11 '17 at 14:33
  • read about HTTP headers then, if you don't know what that is. Every HTTP request and HTTP response contains both headers and body sections. Look at the requests in your browser or in Fiddler as I just suggested and you can start to see the structure. The PHP/cURL documentation will explain how to extract the headers from a response using PHP. – ADyson Jul 11 '17 at 14:33
  • 1
    See https://stackoverflow.com/questions/9183178/can-php-curl-retrieve-response-headers-and-body-in-a-single-request for ways to get the headers from cURL – ADyson Jul 11 '17 at 14:49
  • Wow! That worked. What sections do we need? At the end it says `Curl_http_done: called premature == 0`. Is that a problem? – user7903682 Jul 11 '17 at 14:57
  • I don't really know cURL that well if I'm honest, you might be able to google that error, but as I said earlier you ought to be looking inside the header info for a header called "location". – ADyson Jul 11 '17 at 14:58
  • There is no such header. Do you want the full text? – user7903682 Jul 11 '17 at 15:02
  • Hm if so that means their API is not really observing the convention properly. Strange that a login process would have a 301 in it at all, but there you go. Anyway yes show me the whole text in case you've missed something. – ADyson Jul 11 '17 at 15:05
  • `* Trying 23.22.203.63... * TCP_NODELAY set * Connected to create.kahoot.it (23.22.203.63) port 443 (#0) * TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 * Server certificate: *.kahoot.it * Server certificate: COMODO RSA Domain Validation Secure Server CA * Server certificate: COMODO RSA Certification Authority > POST /rest/authenticate HTTP/1.1 Host: create.kahoot.it Accept: */* Content-Length: 45 ` – user7903682 Jul 11 '17 at 15:09
  • `Content-Type: application/x-www-form-urlencoded * upload completely sent off: 45 out of 45 bytes < HTTP/1.1 415 Unsupported Media Type < Server: openresty/1.11.2.2 < Date: Tue, 11 Jul 2017 15:08:35 GMT < Content-Type: application/json < Content-Length: 124 < Connection: keep-alive < * Curl_http_done: called premature == 0 * Connection #0 to host create.kahoot.it left intact` – user7903682 Jul 11 '17 at 15:09
  • What's interesting is by changing `curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);` to `curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);`, it changes the IP to `54.211.216.59` – user7903682 Jul 11 '17 at 15:10
  • that's the output of the cURL command line, not the response headers from the resulting HTTP response. – ADyson Jul 11 '17 at 15:13
  • It might be easier to use a tool like PostMan to create the request and get the response initially, it will give you a clearer view of the response than cURL. Once you know what to expect back from the server it'll be easier to write your PHP code. https://www.getpostman.com/ – ADyson Jul 11 '17 at 15:15
  • i got them. I will add it to my originial post – user7903682 Jul 11 '17 at 16:02
  • @ADyson you still there? – user7903682 Jul 11 '17 at 19:56
  • 401 means you can't authenticate. Possibly this is some anti-spoofing stuff. However I'd be surprised if it accepts a GET instead of a post. Can you show the response for when you send a POST please? – ADyson Jul 11 '17 at 20:44
  • 1
    I got it to work. I needed to post in the form of `application/json` and I needed a third field. – user7903682 Jul 11 '17 at 20:46
  • `$loginheader = array(); $loginheader[] = 'content-type: application/json'; $loginpost = new stdClass(); $loginpost->username = $username; $loginpost->password = $password; $loginpost->grant_type = "password"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $loginUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($loginpost)); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_HTTPHEADER,$loginheader); $store = curl_exec($ch); ` – user7903682 Jul 11 '17 at 20:46
  • ah well done, well spotted! That would make sense, since it expects the form to be submitted via ajax normally, and that technique would quite often use JSON to send data. – ADyson Jul 11 '17 at 20:53
  • In fact, I'm having the problem again, if you want to help. https://stackoverflow.com/questions/45044027/405-error-php-get-request – user7903682 Jul 11 '17 at 21:01

1 Answers1

0

first use this code and debug your issue.

$info = curl_getinfo($ch);
print_r( $info );

if you are requesting HTTPS check

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);

405 error probably for un-permitted methods. e.g. Making a GET call, when only POST is permitted, or vice versa.

Sunil Rajput
  • 960
  • 9
  • 19
  • does it matter where – user7903682 Jul 11 '17 at 14:11
  • It returns nothing. Here we go: – user7903682 Jul 11 '17 at 14:12
  • print before your curl_close($ch); – Sunil Rajput Jul 11 '17 at 14:12
  • `( [url] => https://create.kahoot.it/login [content_type] => [http_code] => 0 [header_size] => 0 [request_size] => 0 [filetime] => 0 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0 [namelookup_time] => 0 [connect_time] => 0 [pretransfer_time] => 0 [size_upload] => 0 ` – user7903682 Jul 11 '17 at 14:12
  • `[size_download] => 0 [speed_download] => 0 [speed_upload] => 0 [download_content_length] => -1 [upload_content_length] => -1 [starttransfer_time] => 0 [redirect_time] => 0 [redirect_url] => [primary_ip] => [certinfo] => Array ( ) [primary_port] => 0 [local_ip] => [local_port] => 0 )` – user7903682 Jul 11 '17 at 14:13
  • See my comment above, you've missed the real reason this doesn't work – ADyson Jul 11 '17 at 14:15
  • So it could not be a post request? How can I tell? `https://create.kahoot.it/rest/authenticate` – user7903682 Jul 11 '17 at 14:19
  • and also check curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); Hope it works . – Sunil Rajput Jul 11 '17 at 14:22