Archive for the 'Auditing' Category

Signed bit-fields

jm December 28th, 2006

6.7.2 of the C standard indicates that:

Each of the comma-separated sets designates the same type, except that for bit-fields, it is implementation-defined whether the specifier int designates the same type as signed int or the same type as unsigned int.

So, when you have a bit-field of type int, it’s implementation-defined whether that bit-field is actually treated as a signed integer variable. Based on our limited testing, it appears that mainstream implementations do treat it as a signed integer, which is pretty interesting.

Continue Reading »

SQL Injection/Truncation in Stored Procedures

mark December 27th, 2006

SQL injection vulnerabilities have plagued applications for many years. When a dynamic SQL query is constructed with any sort of user-controllable input, there exists the potential for an attacker to perform arbitrary SQL queries, which might lead to sensitive information disclosure or modification. Developers wanting to protect their applications from these kinds of attacks have typically instituted filtering of user data for SQL metacharacters, moved their database query code into stored procedures, or replaced their dynamic SQL statements with prepared SQL. Prepared SQL statements are precompiled SQL queries that accept user-defined parameters without allowing for SQL injection attacks to occur. Since the SQL query is compiled beforehand, the user’s data is never parsed by the SQL parser, and thus isn’t capable of triggering metacharacter attacks.
Continue Reading »

Stored Procedure SQL Injection Cheat Sheet

jm December 26th, 2006

One thing we’ve been finding increasingly over the last year or so is a lot more instances of SQL injection within stored procedures. In order to set the stage for Mark’s SQL Truncation post, we’re presenting a brief cheat-sheet on how to audit for these issues.
Continue Reading »

Fun With Impersonation

justin December 19th, 2006

Here’s our first "Spot the Vuln" challenge. I originally put this together for a post to Matasano’s blog, but work got pretty hectic and I had to let it slip for a bit. Now I finally have a little breathing room, so I thought this would be a good place to post it.

The below function is a thread spawned from a named pipe server in Windows. The io parameter is an open named pipe handle returned from a call to ConnectNamedPipe(); data has been read from the pipe, so impersonation shouldn’t fail.

int tclient(HANDLE io) {
     int hr = 0;
     STARTUPINFO si;
     PROCESS_INFORMATION pi;

HANDLE hProc = GetCurrentProcess();
if(!ImpersonateNamedPipeClient(io)) return GetLastError();
ZeroMemory(&si, sizeof(si)); si.dwFlags = STARTF_USESTDHANDLES; si.cb = sizeof(si); DuplicateHandle(hProc, io, hProc, &si.hStdInput, GENERIC_READ, TRUE, 0); DuplicateHandle(hProc, io, hProc, &si.hStdOutput, GENERIC_WRITE, TRUE, 0); DuplicateHandle(hProc, io, hProc, &si.hStdError, GENERIC_WRITE, TRUE, 0); CloseHandle(io);
CreateProcess(NULL, SHELL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
CloseHandle(si.hStdInput); CloseHandle(si.hStdOutput); CloseHandle(si.hStdError);
hr = RevertToSelf();
if (pi.hProcess != NULL) WaitForSingleObject(pi.hProcess, INFINITE);
return hr; }

This post is open for comments, but we will be moderating first because we don’t want to spoil the fun for everyone.

HANDLE with care

justin December 5th, 2006

I made a very poorly conceived last minute change to the description of object handles on page 632; this mistake can be blamed primarily on a lack of sleep and a broken test environment.  Basically, I wrote that you can use NtQuerySystemInformation() to retrieve unnamed object handles with weak permissions. The truth is that permissions don’t apply when duplicating open handles, which I explained properly elsewhere in the chapter.  The crux of this error is really that I failed to address the PROCESS_DUP_HANDLE permission and how it prevents exactly that attack vector.

Essentially, duplicating handles between processes requires PROCESS_DUP_HANDLE permissions for both the source and destination processes; otherwise the call to DuplicateHandle() will fail with access denied.  This is important to note because having PROCESS_DUP_HANDLE permission for another process allows you to duplicate that process’ pseudo-handle for itself. The resulting handle grants full rights to the target process, including arbitrary manipulation of memory.

In the end, I think we’ve all learned a really valuable lesson about trusting judgment calls when under the influence of deadlines.

By “synonymous,” I meant “I’m an idiot”

jm December 5th, 2006

So, on page 224, in a note, I wrote:

You might see type conversions referred to as "type coercions" in programming-language literature; the terms are synonymous.

Well, I guess you can tell I got my CS degree from a public school. So, there’s two types of type conversions: explicit type conversions and implicit type conversions. Explicit ones are ones that the programmer explicitly invokes, via type-casts. Implicit conversions are the ones that the compiler does behind the scenes to make everything work. "Type coercions" are the implicit type conversions, not the explicit ones, so the above statement is wrong. While it’s rather fun being wrong while stating things authoritatively, I really hope they don’t revoke my ACM privileges. I still haven’t used my free kill.

« Prev -