War stories. Part 1

@CesantaHQ

by Sergey Lyubka, Cesanta CTO, for Dublin C/C++ User Group

1. Mongoose web server: MySQL connect fail

  • Early 2005 (actually, December 31, 2004)
  • OS: MS Windows
  • Mongoose web server running PHP CGI application
  • PHP script uses MySQL for storing data
  • ... and fails to connect to the database!

1. Mongoose web server: MySQL connect fail

  • Checking PHP error messages:
mysql_connect(): Can't create TCP/IP socket (10106)

 

  • Checking MSDN for error code 10106:

WSAEPROVIDERFAILEDINIT

10106

 

Service provider failed to initialize.

The requested service provider could not be loaded or initialized. This error is returned if either a service provider's DLL could not be loaded (LoadLibrary failed) or the provider's WSPStartup orNSPStartup function failed.

1. Mongoose web server: MySQL connect fail

  • Running PHP script by hands from the command prompt:
  • ... works fine
  • Created a test C program with mysql_connect() call
  • An underlying Winsock socket() call failed with code 10106.

any guess what's going on?

1. Mongoose web server: MySQL connect fail

  • Does a web server runs programs any differently?
  • Yes. According to the CGI/1.1 standard,
    • A web server must run a CGI script from the directory where that CGI script lives
    • A web server must run a CGI script with the redirected standard IO (that is to make a webserver able to read CGI script's stdout, and pass a POST buffer to the stdin)
    • A web server must start a CGI script with specifically constructed environment (that is mainly to pass HTTP headers to the CGI script as special variables, e.g. HTTP_CONTENT_LENGTH).

1. Mongoose web server: MySQL connect fail

  • Same directory: checked from the cmd line, works fine.
  • Redirected IO: thought for a minute.. messy to test. skipped to the next
  • Environment:
    • Ran "set" command in the prompt
    • Started to copy variables one by one into the environment created by the web server

1. Mongoose web server: MySQL connect fail

1. Mongoose web server: MySQL connect fail

  • Winsock's socket() call needs a SYSTEMROOT environment variable
  • All programs started by Windows inherit their environment from the parent process, with has SYSTEMROOT variable
  • If for some reason that variable is absent, then the program cannot do any TCP/IP networking
  • Try it for yourself!
  • Then try to find that in the MSDN documentation

1. Mongoose web server: MySQL connect fail

  • Winsock implementation sits in WS2_32.dll
  • Speculation:
  • socket() function might access some configuration parameters via the SYSTEMROOT environment variable

2. Mongoose web server: CGI code disclosure

  • Late 2008
  • Problem: a security advisory is published!
  • Windows version of Mongoose shows CGI file content instead of executing a CGI file
  • ... if a CGI file name has a whitespace character appended to it

2. Mongoose web server: CGI code disclosure

  • I have run a simple CGI file from the unit test,
    • http://localhost:8080/env.cgi
  • Added a space to the end of the URI in the browser
  • And, yeah, I saw a CGI file content!
  • A security hole was there indeed
  • Mongoose was identifying CGI file by file extension
  • All files ended with ".cgi" were treaded as CGI
  • The rest were shown as-is, like regular files

any guess what was going on?

2. Mongoose web server: CGI code disclosure

  • It was not very hard to find!
  • Windows runtime code
  • And, yeah, I saw a CGI file content!
  • A security hole was there indeed
  • Mongoose was identifying CGI file by file extension
  • All files ended with ".cgi" were treaded as CGI
  • The rest were shown as-is, like regular files

any guess what was going on?

2. Mongoose web server: CGI code disclosure

  • Windows' fopen() implementation,
  • .. which sits in the runtime library msvcrt.dll,
  • .. happily opens files which have garbage at the end of file name!

// Opens "a.cgi" with no error
FILE *fp = fopen("a.cgi    ", "r");
  • Garbage could be a white space, or '+', or '.',or characters with the upper half of the ASCII table

2. Mongoose web server: CGI code disclosure

  • Bottom line:
  • Windows may successfully open a file whose path does not exist in the filesystem
  • Because MSVC runtime is trying to be smart and prettify the file name by trimming some characters
  • Beware! This is a potential security hole

Thank you!

contact me at

sergey.lyubka@cesanta.com

War stories. Part 1

By Sergey Lyubka

War stories. Part 1

This presentation goes over notable and sometimes funny software engineering experiences from the past

  • 945