Very Lost: Flack and NYU Osiris Challenges - python

I am going through some CTF challenges at https://recruit.osiris.cyber.nyu.edu/challenges.
I got to one for Template Programming where the task is to "Read /flag.txt from the server. http://recruit.osiris.cyber.nyu.edu:2000"
I am not asking for a solution, but I would like some better understanding of what is going on below:
What is this code doing?
Should I be worried about running out of Debugging mode and/or using host="0.0.0.0"?
What are some resources that could help me understand this? I tried reading through the Flask documentation and the tutorialspoint page, but I am unclear as to how this doesn't just set up a local server for testing as opposed to accessing a remote server...
If I ctrl+C do I need to worry about leaving a server still running on an open port when I am not in Debugging mode?
#!/usr/bin/env python3
from flask import Flask, request, abort, render_template_string
import os.path
app = Flask(__name__)
#app.route('/', methods=['GET'])
def index():
name = request.args.get('name')
if name is not None:
return render_template_string(open('templates/hello.html').read().format(name=name))
return render_template_string(open('templates/index.html').read())
if __name__ == "__main__":
app.run(host="0.0.0.0")

I think I can answer most of these.
As you probably already figured out, Flask is a fairly basic web framework. By the look of things, what you have there is a copy of the code running at the CTF site. It displays just two pages; one that contains the initial web form (templates/index.html) and another that uses a query string variable to greet the user (templates/hello.html) when a name has been provided.
You don't really have to run this code yourself. The 0.0.0.0 host address is catch-all that matches all IPv4 addresses on the local machine, which would include local addresses like 192.168.0.1 and 127.0.0.1 as well as the IP address used for incoming connections to the server.
Like I said, this is the code running on the remote server.
I think what you need to do is find some way of crafting a request to this web service in such a way that it reveals the contents of /flag.txt instead of (or perhaps in addition to) just saying hello. A quick search for something like "flask include file vulnerability" should give you some idea of how to attack this problem.

Related

steps I need to take to make my flask webpage visible by others

I have a webpage with some simple algorithm, which returns the output based on user input & local data file. I checked it's working with my local machine, but found that it doesn't work from my cell phone / other laptops.
I tried several things from web - such as 'python app.py --host=0.0.0.0' on my terminal, or app.run(host='0.0.0.0', port=5000) but didn't work.
I'm trying again from the beginning. below is my code (I named the file app.py), where I put it back to default before any edit.
from flask import Flask,render_template,url_for,request
app = Flask(__name__)
#app.route('/')
def home():
return render_template('home.html')
#app.route('/predict',methods=['POST'])`
def predict():
#some algorithm stuffs
return render_template('result.html', tables=[result.to_html(classes='data',escape=False)], titles=result.columns.values)
if __name__ == '__main__':
app.run(debug=True)
what should I add on this py file?
Also, is there anything beside coding I should do? (firewall, port, etc) I'm currently starting with local machine and planning to work it with virtual machine later (EC2)
If you want to deploy your application in your own local network and make it accessible to your phone or to other computers in the network for testing reasons, then the following steps is enough:
Make sure your computer is connected to your access point and receives an ip address, then launch your application with the command: flask run --host=0.0.0.0 which tells your operating system to listen on all public IPs.
Check the ip address of your machine and the port number on which flask is running (eg: 192.168.43.114:5000). Type it in the browser on your phone or another computer on the network and you will have access to your application.
If you want a larger deployment, for example having computers in other networks access your application, then you need to consider other strategies. Here are a few examples, all of which relate to a specific use case:
Flask-ngrok
Pythonanywhere
Excellent tutorial about deployement on heroku
If you want to make it visible by anyone you have to open at least one port of your box (depending on your box model you can find some explanations on how to do it), this can be unsafe. You'll then have to map your box port with your PC's port.
You should go straight with a cloud virtual machine as it's much easier (just allow connexion to the VM port 80)
A good alternative would be to use Docker and deploy your app on Heroku or Azure (it's free!)
If you want to make it visible on your own network (just the people on the same WIFI) then it's easier but I don't think that's your point

Trouble accessing webservice from EC2 instance

I have a small bottle webservice running on EC2 virtual windows server i launched. I am able to access it on localhost or by using the IPV4 specified in the main method as below but I am not able to access it over internet from other computers.
Please suggest me how to deal with this. I saw one similar question like this but the suggestions didnt work so am posting again. Apologies for that.
Trying:http://172.31.30.244:8080/
#route('/')
def index():
""" Display welcome & instruction messages """
return "<p>Welcome to bottle powered server !</p> \
<p>There are many ways to invoke the web service :\
<ul><li>http://localhost:8080/in?s=type_your_string_here</li>\
</ul>"
some code here for calculations
IN my Main method
if __name__ == '__main__':
bottle.debug(True)
run(host='172.31.30.244', port=8080,debug=True)
Ran bottle server on EC2 instance, opened a port 8083 and accessed using the fully_qualified_machine_name:8083 thank you for your suggestion on using the public DNS name. I was not opening the port properly which i later did using custom TCP under 'Add rule' for inbounds of EC2 instance

How to detect which of the two virtual hosts is being used in python and flask

I have a website developed in flask running on an apache2 server that responds on port 80 to two URLs
Url-1 http://www.example.com
Url-2 http://oer.example.com
I want to detect which of the two urls the user is coming in from and adjust what the server does and store the variable in a config variable
app.config['SITE'] = 'OER'
or
app.config['SITE'] = 'WWW'
Looking around on the internet I can find lots of examples using urllib2 the issue is that you need to pass it the url you want to slice and I cant find a way to pull that out as it may change between the two with each request.
I could fork the code and put up two different versions but that's as ugly as a box of frogs.
Thoughts welcome.
Use the Flask request object (from flask import request) and one of the following in your request handler:
hostname = request.environ.get('HTTP_HOST', '')
url = urlparse(request.url)
hostname = url.netloc
This will get e.g. oer.example.com or www.example.com. If there is a port number that will be included too. Keep in mind that this ultimately comes from the client request so "bad" requests might have it set wrong, although hopefully apache wouldn't route those to your app.

How to use CherrPy as Web server and Bottle as Application to support multiple virtual hosts?

I have a website (which running in Amazon EC2 Instance) running Python Bottle application with CherryPy as its front end web server.
Now I need to add another website with a different domain name already registered. To reduce the cost, I want to utilize the existing website host to do that.
Obviously, virtual host is the solution.
I know Apache mod_wsgi could play the trick. But I don't want to replace CherryPy.
I've googled a a lot, there are some articles showing how to make virtual hosts on CherryPy, but they all assume Cherrypy as Web Sever + Web application, Not CherrPy as Web server and Bottle as Application.
How to use CherrPy as Web server and Bottle as Application to support multiple virtual hosts?
As you mentioned, use VirtualHost. In the example cherrypy.Application instances are used, but any WSGI callable (e. g. Bottle app) will do.
perhaps you can simply put nginx as reverse proxy and configure it to send the traffic to the two domains to the right upstream (the cherryPy webserver).
Another idea would be to use Nginx (http://wiki.nginx.org/Main) with uWsgi(http://projects.unbit.it/uwsgi/) & (uWsgi-python) plug-in
uWsgi has a module named emperor that you can link vhosts(vassals) in, sort of.
i'm a newbie at this myself, so not necessarily an answer but rather a suggestion to check it out.
just a heads up, uWsgi and Nginx can be a hassle to get it to work, depending on your linux distro. Does work nicely with bottle, tested it myself.
hope it helps
jwalker's answer is pretty clear. In case any CherryPy newbie need whole script for reference, I post one below.
import cherrypy
from bottle import Bottle
import os
app1 = Bottle()
app2 = Bottle()
#app1.route('/')
def homePage():
return "========= home1 ==============="
#app2.route('/')
def homePage_2():
return "========= home2 ==============="
vhost = cherrypy._cpwsgi.VirtualHost(None,
domains={
'www.domain1.com': app1,
'www.domain2.com': app2,
}
)
cherrypy.tree.graft(vhost)
cherrypy.config.update({
'server.socket_host': '192.168.1.4',
'server.socket_port': 80,
})
cherrypy.engine.start()
cherrypy.engine.block()
you could make www.domain1.com and www.domain1.com point to one IP adress of you server, so it servers for 2 domain in one Web Server.

Can't reach Eve REST API

I'm using Eve to create a REST API for MongoDB.
It's all working fine, except for the fact that I can't reach the API from any other computer (in the same network), or even a different URL (e.g.: if I set SERVER_NAME = 'localhost:29000', I will not be able to reach the API with 127.0.0.1 and vice versa).
I've been looking around for hours, and I can't seem to find an answer. I also tried other REST API's for MongoDB like Kule, and they seem to work just fine, but they don't have as many options as Eve has.
Eve's SERVER_NAME seems to be based on the configuration variable by the same name from Flask: See "More on server name" below the table in the Flask Configuration docs. So it's really just for the name (hostname / subdomain handling) - the actual network interfaces it binds to therfore are probably determined by the server that runs the WSGI application.
If you're just doing the
app = Eve()
app.run()
from the quickstart example, try
app.run(host='0.0.0.0')
instead and leave the server name empty (SERVER_NAME = '').
I've never used Eve, but from what I understand about how it's built that should work

Categories