Running CGI Scripts

Adam M Dutko
February 20, 2015

Overview


HTTP/1.1 - RFC 2616

CGI/1.1 - RFC 3875

Apache

Example

HTTP/1.1 - RFC 2616

HTTP/1.1 - RFC 2616


Hypertext Transfer Protocol (now with 2.0!)

Client / Server Behavior

Definition of URL

GET & POST (others too)

Response Codes

CGI/1.1 - RFC 3875

CGI/1.1 - RFC 3875


Common Gateway Interface

Works in Unison with HTTP Server

Defines Abstract Meta-Variables

Platform Independent Interface

Handles Application Issues (Data Access & Processing)

Apache

Apache


HTTP Server Project

Popular Web Server

Provides Server Process Environment

Configuration Files and Modular

Handles Connection, Transport, Network and Data Transfer

Example

Example Request and Response

Example Request and Response

Source: http://countuponsecurity.com/

Environment

Setup our Environment




          % curl -L https://cpanmin.us | perl - App::cpanminus
          % cpanm -i DigitalOcean 
          % cpanm -i Modern::Perl 
          % cpanm -i Class::XSAccessor 
          % cpanm -i Devel::Declare::MethodInstaller::Simple 
          % cpanm -i Sub::Name
          % cpanm --reinstall B::Hooks::OP::Check
        

new_vm.pl

            #!/usr/bin/env perl 
            use Modern::Perl '2011';
            use DigitalOcean;

            ## TODO: You should really add more error handling.
          
            my $client_id = 'CHANGE_ME';
            my $api_key   = 'CHANGE_ME';
             
            my $do = DigitalOcean->new(
                client_id      => $client_id,
                api_key        => $api_key,
                wait_on_events => 1
            );  

            my $new_droplet = $do->create_droplet(
                name      => $ARGV[0],
                size_id   => ,
                image_id  => , 
                region_id => ,
            );

          

Response Host Setup

Response Host Setup


          % perl scripts/new_vm.pl response.clevelandpm.org
 
          ...

          % ssh root@192.241.147.64 
          % Password: 
          
          % Changing password for root.
          % (current) UNIX password:
          % Enter new UNIX password:
          % Retype new UNIX password:

          ## Refer to: http://httpd.apache.org/docs/2.2/howto/cgi.html

          root@response:~ apt-get install apache2

          root@response:~ apachectl -t -D DUMP_MODULES
          ...
            cgid_module (shared)
          ...
          root@response:~  

        

Response Host Setup (Cont.)


          root@response:~ grep -R ScriptAlias /etc/apache2/* | grep 000-default
          /etc/apache2/sites-enabled/000-default:   \\
              ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

          root@response:~ grep -R AddHandler /etc/apache2/* | grep cgi-script
          /etc/apache2/mods-available/mime.conf:#AddHandler cgi-script .cgi
          /etc/apache2/mods-enabled/mime.conf:#AddHandler cgi-script .cgi

          ## Uncomment and add .pl 
          vi /etc/apache2/mods-enabled/mime.conf
            AddHandler cgi-script .cgi .pl

          ## Check configuration
          root@response:~ apachectl configtest
          Syntax OK
          root@response:~ 

          ## Reload configuration
          root@response:~ apachectl graceful
          root@response:~ 

          ## Open your web browser and check apache works!
          http://$IP_ADDRESS_OF_VM$ ... it's a GET!

        

Response Script

          root@response:~ mkdir /var/www/cgi-bin
          root@response:~ vi /var/www/cgi-bin/response.pl

          #!/usr/bin/env perl
          print "Content-type: text/html\n\n";
          print "Hello, World.";

          ## Open browser and check!
          http://$IP_ADDRESS_OF_VM$/cgi-bin/response.pl
            
          ## RUH ROH!
          [Fri Feb 20 17:08:12 2015] [error] [client 75.118.125.66] script \\ 
              not found or unable to stat: /usr/lib/cgi-bin/response.pl

          ## Move the script!
          root@response:~ mv /var/www/cgi-bin/response.pl /usr/lib/cgi-bin/
            
          ## RUH ROH!
          [Fri Feb 20 17:08:53 2015] [error] (13)Permission denied: exec of \\
              '/usr/lib/cgi-bin/response.pl' failed
          [Fri Feb 20 17:08:53 2015] [error] [client 75.118.125.66] Premature \\
              end of script headers: response.pl

          ## Change permissions!
          root@response:~ chmod +x /usr/lib/cgi-bin/response.pl

        

Request Host Setup

Request Host Setup


          % perl scripts/new_vm.pl request.clevelandpm.org

          ...

          % ssh root@192.241.147.64 
          % Password: 
          
          % Changing password for root.
          % (current) UNIX password:
          % Enter new UNIX password:
          % Retype new UNIX password:

          root@request:~  

          root@request:~ apt-get -y install make gcc

          root@request:~ curl -L https://cpanmin.us | perl - App::cpanminus

          ## Might take a while!
          root@request:~ cpanm -i LWP::UserAgent 

          root@request:~ cpanm -i Modern::Perl

        

Request Script

          
          #!/usr/bin/env perl
          use Modern::Perl '2011';
          use LWP::UserAgent;

          my $ua = LWP::UserAgent->new;
          $ua->timeout(10);

          ## Change the IP to the response host.
          ## Experiment with change response.pl to an invalid file!

          my $request = $ua->get('http://192.241.147.64/cgi-bin/response.pl');

          if ($request->is_success)
          {
              print $request->decoded_content . "\n";
          } else {
              die $request->status_line . "\n";
          }

        

Request Script (Cont.)

          
          ## Login to our response host
          ssh root@192.241.147.64

          ## Watch our requests on response
          root@response:~ tail -f /var/log/apache2/access.log

          root@request:~ perl request.pl
          Hello, World.

          ## If we change the URL to an invalid file
          root@request:~ perl request.pl
          404

          ## Watch our requests on response
          root@response:~ tail -f /var/log/apache2/access.log

          ## VOILA!!!

        

Questions???

Sources