Sunday, April 4, 2021

Host ASP.NET Core on Linux with Apache and Kestrel

Since the publication of new release of dotnet (core) v.5 there are several articles about how to setup and run a production environment in a Linux server. To be honest, most of them requires some modifications in order to implemented correctly. Thus, I decided to write a guide on how to setup, in an existing CentOS 7 Linux server, ASP.Net core (v.5) using the following configuration:

  1. Apache web server (used as a reverse proxy).
  2. Kestrel web server, serving the ASP.Net pages.
  3. DotNet Core v.5.

A proxy server forwards client requests to another server usually from an internal network (for example a LAN) to an external and usually untrusted network (usually the Internet). A reverse proxy works the opposite way: forwards requests that accepts from an external and usually untrusted network (usually the Internet) to an internal network, and specifically in our case, to the Kestrel server. 

I am not going to say much about Kestrel, since there are more than adequate articles about it out there. It is a Microsoft lightweight web server for ASP.NET core applications. Since it is very lightweight and not as functional as the well known web servers Apache, NginX and IIS, we usually put (in front) a well known web server to 'phase' the internet traffic and forwards (as a reverse proxy) the requests to the Kestrel.

Suppose that we have a (clean - text mode) CentOS 7 server box. In my case, I just set it up automatically from the control panel of my VPS provider. Actually it is very easy and cheap these days (personally I use to host a VPS server online with a Linux OS. Please note that I am not going into details of how to set the OS up, since it is out of my current scope.

Setup Apache as a reverse proxy

First of all we need to be sure that all of the installed packages are updated to their latest version, so we run the following command:

$ sudo yum update -y

Then, we install Apache web server using yum package manager:

$ sudo yum -y install httpd mod_ssl

Now, we have to configure Apache to work as a reverse proxy, i.e. to forward its requests to a different port (aka service) that the Kestrel server is listening, that is port 5000. To do this, we need to set up (create) a configuration file (that represents our application configuration file) in the well know location that Apache manages its configuration files, the: /etc/httpd/conf.d/
Suppose our application is called: demoapp, thus we enter the following:

$ sudo vi /etc/httpd/conf.d/demoapp.conf

Note: if you not an old-school and you don't like vi (aka nano-lovers) you can use an editor of your choice (like nano)... ;) 

We put into the file the following information:

<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass /
    ProxyPassReverse /
    ErrorLog /etc/httpd/logs/demoapp-error.log
    CustomLog  /etc/httpd/logs/demoapp-access.log common

<VirtualHost *:443>
    ProxyPreserveHost On
    ProxyPass /
    ProxyPassReverse /
    ErrorLog /etc/httpd/logs/demoapp-error.log
    CustomLog  /etc/httpd/logs/demoapp-access.log common
    SSLEngine on
    SSLProtocol all -SSLv2
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

Now, just run the following command to check the syntax of the above configuration:

$ sudo service httpd configtest

The response should include the following:
Syntax OK
Don't worry (for now) in case that you get a warning like the following:
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using <YOUR_SERVER_IP>. Set the 'ServerName' directive globally to suppress this message

Now, just restart Apache and also set it to run at system start-up:

$ sudo systemctl restart httpd
$ sudo systemctl enable httpd

Important note on SELinux system

By default, SELinux prevents Apache from initiating connections, so it is unable to proxy requests to Kestrel Server. Thus, it is possible to get an Access Denied error when Apache tries to communicate with Kestrel: You will see the error as 503 "Service Unavailable" on your web browser (something like  seen in the following image).

To make Apache to allow connections, run the following command on the server :

$ /usr/sbin/setsebool -P httpd_can_network_connect 1

as shown in the following image (don't worry about the error messages) :

Install the .Net SDK

We are following the Microsoft instructions here to install the Net SDK. In this example we will choose to install the SDK (that includes the RunTime). 

We run the following command to add the Microsoft package signing key to our list of trusted keys and add the Microsoft package repository:

$ sudo rpm -Uvh

The .NET SDK allows us to develop apps with .NET. If we install the .NET SDK, we don't need to install the corresponding runtime. We enter the following command to install the .NET 5:

$ sudo yum install dotnet-sdk-5.0

Then, we can run the dotnet --version command to test that the .Net 5 is successfully installed:

Create an ASP.NET core Application

Ok, now it's time to create our demo application. 

We can create and compile the application in a Windows or in a Linux system, in the same or in a different machine but we must publish it in  /var/www/demoapp/ on this machine.

For simplicity let's create our demoapp application in this server. All we need to do, is typing the commands shown in the following picture:

As you can see our default demoapp was publish in  /root/sources/apps/demoapp/bin/Debug/net5.0/publish/ catalog. We only need now, to copy it to the /var/www/demoapp/ and restart Kestrel.

$ cp /root/sources/apps/demoapp/bin/Debug/net5.0/publish /var/www/demoapp

Create the Kestrel service for our demoapp

Now, we have to create the service that will runs our demo application on Kestrel web server. 
To do this, we create a file called kestrel-demoapp.service in /etc/systemd/system

$ sudo vi /etc/systemd/system/kestrel-demoapp.service

and we enter the following info:

Description=Example .NET Web API App running on CentOS 7

ExecStart=/usr/bin/dotnet /var/www/demoapp/demoapp.dll
# Restart service after 10 seconds if the dotnet service crashes:


Now let's set to start the service every time we boot the system:

$ sudo systemctl enable kestrel-demoapp.service

and just start the service:

$ sudo systemctl start kestrel-demoapp.service

...and verify it is running:

$ sudo systemctl status kestrel-demoapp.service

Note: Each time you publish a new application or publish modifications to an existing one, you have to restart the Kestrel service as follows:
sudo systemctl restart kestrel-demoapp.service

You can also check by yourself if Kestrel works as expected, by using a line web browser (ideal for text mode environments) as lynx (you will need to install it first by typing "sudo yum install lynx"), by entering the following:

$  lynx

If everything is fine, you should see the following:

$ sudo systemctl restart kestrel-demoapp.service

and visiting your web site, you must see:

Happy Programming!!

Thursday, May 4, 2017

Uncover (very) sensitive info from Google Chrome

In this post I am going to show how we can uncover very sensitive info from Chrome thumbnails in three easy steps. The current, can also be titled as what a bad user can see whenever he/she has physical access to your box.

Google Chrome take screenshots from sites we visited in order to provide them for easy & quick access on the new tab action (image 1).
Image 1: Ops, There is an e-banking thumbnail here!

In the above picture we can see that the 4th thumbnail indicates a logged-in screen-shot from an e-bank account. Also, note that the specific user has already logged-out from this bank-account but Chrome still keeps the screen-shot taken when the user was logged-in!

The question now is, how (and if) it is possible to enlarge this specific thumbnail to a more readable size. The answer to the above questions is "Yes we can", just pay attentions to the following two images. First (image 2), we delete all non-interested thumbnails (using the default Chrome browser developer tools - aka F12) in order to relocate out target thumbnail into the upper left corner.

Image 2: remove non-interested thumbnails
Then, we can just change the main IDs of the Class tags to a non-existence name in order to make the thumbnail change to its original size (image 3)...
Image 3: Just change some div IDs... and voila!

Note that the above info is just an example. Chrome will take screen-shots at any time, any site w/o asking your default permissions, independent you are logged-in or not! Thus, e-banking images, emails, blogs, personal and private sites can be exposed randomly!

I consider this as a violation of the first factor of the Security Triad, the Confidentiality! The above issue has been referred to Chrome Bugs Matrix references here, (currently Unconfirmed).

Monday, April 13, 2015

Is PHP vulnerable and under what conditions?

We are going to analyze a special method of attacking Web Servers. It is known as LFI with PHP Info vulnerability [1]. It was first publish by Insomnia Sec at 2011. The method clever handles some PHP build-in features (such as upload and wildcards [2]) to accomplish a well formed attach that will end up with an arbitrary code execution (call me remote shell) on the victim's server. Requires two specific flaws on the server: A phpinfo() function must be available along with a LFI vulnerability. By combining the above two, a high risk attack can be implemented. The method has been tested successfully on Windows as well as Linux operating systems on IIS and Apache web servers. The same method failed on NginX web server.

Wednesday, February 25, 2015

How safe is our personal information?

What you will learn

  • How bad guys use information already exists on the net to gain access to:
    • your email accounts,
    • your financial information such as credit cards, PayPal accounts etc,
    • your internet hosting accounts (if you have any),
    • your personal web sites,
    • your personal life in general!
  • How you can protect yourself by such bad situations by following some very simple but very efficient security rules.
The actual incident that this article is based on was 100% real but for privacy reasons all referred user names are not the real ones and they have been chosen randomly. According to the same reason all images have been obscured.