SQL Injection, ignore first select command - sql-server

I am trying to build a scenario that would allow me to expose additional data from a server (for case-demo purposes). The server calls a vulnerable SQL code:
EXEC my_storeProc '12345'
where "12345" (not the single quotes) is the parameter. This performs a SELECT statement. I would like to eliminate this execution and instead call my own select statement, however the server side code will only accept the first select statement called, contained within the aforementioned EXEC call. Calling the second statement is easy:
EXEC my_storeProc '12345 ' select * from MySecondTable--
(the -- at the end will block the closing single quote added by the server to prevent errors). My problem is that although there are 2 select statements, the server will only parse the first one. Is there a way to cancel the first EXEC call without throwing an error so that the second one would be taken instead? Perhaps even a UNION but there isn't much I can do with only one variable open to exploit (variable being 12345 in this case).

You have to think of how it will be executed, specifically you want it called so it doesn't raise an exception and put the kabosh on the whole statement. You can't set the result to always true with a proc call, so there is no real way escape the proc. Instead, you'll want to slip a second command in, Your desired code looks like;
exec my_Storeproc '1234'; select * from mysecondtable
So we need to close the quotes, and make a new statement. That would mean the string with the insert needs to be;
1234'; select * from mysecondtable where 1 = '1
There is a flaw in this, whatever command you are executing is not being returned to the UI. To get the data you'll have to add a server connection to the second command.
To make the second command unnecessary you would have to inject code into the proc, which is a non starter since the proc is already complied and sql injection relies on confusing the compiler as to what is data and what is commands. For a more verbose explanation of that check out this answer:
https://security.stackexchange.com/a/25710

Related

SSIS Execute SQL Task - Input String in wrong format

I have an Execute SQL Task which tries to execute a stored procedure, like this:
EXEC usp_stored_proc ?, ?, ? OUTPUT, ? OUTPUT;
I have 4 variables mapped to parameters. Ignoring the output parameters, these are both strings mapped to NVARCHAR params (as expected by the stored procedure).
When I run the package, an error tells me that execution failed with the message input string is not in the correct format. However, when I use a breakpoint to find the runtime values of the input parameters (or at least the variables mapped to them) and execute the same line of SQL in SSMS using the runtime values, it works fine.
Can anyone help? I'm at the end of my tether with this. I can't even find out the exact parameter causing the issue although it's probably both as the values follow the same format.
More details:
Connection type: OLE DB
Input Variable: String = schema.table
Mapped Param: NVARCHAR, ParamName = 0, ParamSize = -1
UPDATE
Solved the issue by making a new execute sql component that calls a stripped down procedure. I then slowly added lines of code to the procedure and additional parameters until arriving at the same component I started with and now it works. Comparing the original and rebuilt tasks, I see absolutely no differences (same with the procedure), so I don't know why this issue was occuring.
Try changing the parameter size (ParamSize) to match the parameter size within the stored procedure; if nvarchar(50) then set it to 50.
Solved the issue by making a new execute sql component that calls a stripped down procedure. I then slowly added lines of code to the procedure and additional parameters until arriving at the same component I started with and now it works. Comparing the original and rebuilt tasks, I see absolutely no differences (same with the procedure), so I don't know why this issue was occurring.

SQL Query Select Line Number (SSMS)

Do any of you know of a command or function that would produce the line number of the query window inside of select statement? For example, if you are on line 34 it you would have select statement and the results would show 34. I am not looking to use row_number() function because we are not referencing a table.
You can't do what you want without altering the stored procedure and adding PRINT 'something' statements.
While this tactic can be useful for quick-and-dirty stored procedure debugging, it does not beautify the code and, is not considered sustainable. There are better methods. Maybe look at a tutorial like this: https://www.sqlshack.com/debugging-stored-procedures-sql-server-management-studio-ssms/

Procedure not running in toad asking for the variable

I'm using TOAD for Oracle. I'm trying to execute a stored procedure with two parameters - one IN and one OUT. It looks like this:
PROCEDURE get_stuff (
parm_1 IN VARCHAR2,
parm_2 OUT currefcursor)
In the SQL Editor window in TOAD, I've tried various things to no avail. I'm sure this is something simple that I'm missing, 'cause I've tried all sorts of things I've seen in other solutions here at Experts Exchange, but can't get past various errors. Here's what I think should work from what I've seen here:
var p1 VARCHAR2 := 'some text';
var p2 currefcursor;
EXEC get_stuff( :p1, :p2 );
When I run this, though, the SQL Editor pops up a window titled 'Variables' that appears to be looking for a value. No matter whether I put something in the 'Value' textbox or not, when I click OK, it says:
ORA-00900: invalid SQL statement
and highlights the 'var' in front of p1.
Please tell me what I'm missing!
Status Solved Priority Medium Security Public Views 21999
As the second parameter is OUT, you have to declare the variable which will accept that value. Here's how; I don't know what currefcursor type is - I guess you do.
declare
l_out currefcursor;
begin
get_stuff(:p1, l_out);
end;
/
A simple option to view the result would be this: put this code into the editor and run it as a script; the result will be displayed in the Script Output tab.
variable l_out currefcursor
exec get_stuff(:p1, :l_out);
print l_out
Or, you could even create a wrapper function which returns cursor, and then select from it:
create or replace function f_get_stuff(p1 in number)
return currefcursor
is
l_out currefcursor;
begin
get_stuff(p1, l_out);
return l_out;
end;
/
select f_get_stuff(:p1) from dual;
You can use Toad to execute without writing the execution harness yourself as well. Here is one method using the Schema Browser. Select your object and right-click > Execute.
You are presented with a dialog asking for your input parameters. Set your inputs and you can see the generated execution harness below. You can also use this generated code as an educational guide to see one method of writing the code yourself.
Click OK and your function/procedure is executed and results are shown.

Trying to escape a sp_executesql variable

I've run in to a problem with a software I'm configuring. I do not have access to the source code, only the config.
The issue is as follows, in the configuration the software expects me to enter a string, but I would like the string to jump out of the compare and instead execute a funtion.
Using sql profiler I get something like this:
exec sp_executesql N'SELECT * FROM dummyTable WHERE (Name LIKE #Pattern)',N'
This does not work in my setup, because pattern is not clearly defind in advanced. I need to take the
variable passed as pattern and run it trough a sql function but I can't figure out how. Typically Pattern contains a single char, in my example "1". I've tried altering the Pattern to use an escape char and run my function on it, but I think I'm missing someting (If this is at all possible).
The variable I've send from config is as follows:
{0}' or Name like dbo.RunCalulation({0})
Giving me the following:
'…#Pattern nvarchar(43)',#Pattern=N'1'' or Name like dbo.RunCalulation(1) '
This executes, but does not give any response, so I think the esacpe char does not work, and it compares the whole string to Name.
I'm real stuck at this, hope someone has a good idea what to do (I know that not having the source code is a real problem here.
One of the huge advantages of query parameters (such as #Pattern) is that they help protect against SQL injection (which is what you are trying to do).
So the answer is that you cannot do what you want. There's no way to escape the #Pattern parameter and add some of your own SQL to that query, because everything you pass as #Pattern will be interpreted as data, and never as SQL command text (which is the reason why your SQL text ends up inside the single quotes, and why your quote is automatically escaped to ''.).

PRINT statement in T-SQL

Why does the PRINT statement in T-SQL seem to only sometimes work? What are the constraints on using it? It seems sometimes if a result set is generated, it becomes a null function, I assumed to prevent corrupting the resultset, but could it's output not go out in another result set, such as the row count?
So, if you have a statement something like the following, you're saying that you get no 'print' result?
select * from sysobjects
PRINT 'Just selected * from sysobjects'
If you're using SQL Query Analyzer, you'll see that there are two tabs down at the bottom, one of which is "Messages" and that's where the 'print' statements will show up.
If you're concerned about the timing of seeing the print statements, you may want to try using something like
raiserror ('My Print Statement', 10,1) with nowait
This will give you the message immediately as the statement is reached, rather than buffering the output, as the Query Analyzer will do under most conditions.
The Print statement in TSQL is a misunderstood creature, probably because of its name. It actually sends a message to the error/message-handling mechanism that then transfers it to the calling application. PRINT is pretty dumb. You can only send 8000 characters (4000 unicode chars). You can send a literal string, a string variable (varchar or char) or a string expression. If you use RAISERROR, then you are limited to a string of just 2,044 characters. However, it is much easier to use it to send information to the calling application since it calls a formatting function similar to the old printf in the standard C library. RAISERROR can also specify an error number, a severity, and a state code in addition to the text message, and it can also be used to return user-defined messages created using the sp_addmessage system stored procedure. You can also force the messages to be logged.
Your error-handling routines won’t be any good for receiving messages, despite messages and errors being so similar. The technique varies, of course, according to the actual way you connect to the database (OLBC, OLEDB etc). In order to receive and deal with messages from the SQL Server Database Engine, when you’re using System.Data.SQLClient, you’ll need to create a SqlInfoMessageEventHandler delegate, identifying the method that handles the event, to listen for the InfoMessage event on the SqlConnection class. You’ll find that message-context information such as severity and state are passed as arguments to the callback, because from the system perspective, these messages are just like errors.
It is always a good idea to have a way of getting these messages in your application, even if you are just spooling to a file, because there is always going to be a use for them when you are trying to chase a really obscure problem. However, I can’t think I’d want the end users to ever see them unless you can reserve an informational level that displays stuff in the application.
Query Analyzer buffers messages. The PRINT and RAISERROR statements both use this buffer, but the RAISERROR statement has a WITH NOWAIT option. To print a message immediately use the following:
RAISERROR ('Your message', 0, 1) WITH NOWAIT
RAISERROR will only display 400 characters of your message and uses a syntax similar to the C printf function for formatting text.
Please note that the use of RAISERROR with the WITH NOWAIT option will flush the message buffer, so all previously buffered information will be output also.
I recently ran into this, and it ended up being because I had a convert statement on a null variable. Since that was causing errors, the entire print statement was rendering as null, and not printing at all.
Example - This will fail:
declare #myID int=null
print 'First Statement: ' + convert(varchar(4), #myID)
Example - This will print:
declare #myID int=null
print 'Second Statement: ' + coalesce(Convert(varchar(4), #myID),'#myID is null')
For the benefit of anyone else reading this question that really is missing print statements from their output, there actually are cases where the print executes but is not returned to the client. I can't tell you specifically what they are. I can tell you that if you put a go statement immediately before and after any print statement, you will see if it is executed.
Do you have variables that are associated with these print statements been output? if so, I have found that if the variable has no value then the print statement will not be ouput.

Resources