去年sql注入很火,最近好像php注入开始流行了,其实都是最基本的知识的应用,没什么难度~~

       i d know about you, oh most knowledgable of sql users, but when i learnt how to build a database driven website from various tutorials around the internet, i never came across the phrase "sql injection"... in fact, i never came across any sql security c at all. the purpose of this article is to inform the sql programmer of the dangers of sql injecti and ways to potentially minimize the severity of any exploits in your code.

all the examples in this article are going to be using php. the reason for this choice is that php seems to be the server-side solution of choice - it's free and powerful. i'm also using mysql, as it's all i've ever used. i think all the examples here should be applicable across different database servers, but i have menti the particular database servers affected where necessary. i assume knowledge of php database functi

to start with, i'll create a database and a couple of tables, so i can dem how a certain security risk could be exploited, and to what means. rather than make a graphical representation of these tables, i'll write it in insertion sql statements, so you can stick them on your own server and test it yourself. after all, the best way to learn is to get stuck in.

代码

######################
# database structure #
######################
create database sqlsecdemo;

create table users (int userid not null auto_increment primary key, text username not null, text password not null);
insert into users set username="netjester", password="blahblah123";
insert into users set username="some password="letmein";
insert into users set username="mrstheplague", password="god";

create table messages (int messageid not null auto_increment primary key, int reluserid not null, text message);
insert into messages set reluserid=1, message="hi everybody.";
insert into messages set reluserid=2, message="what account number shall i have this large amount of m sent to?";
insert into messages set reluserid=3, message="b825km32-f please ";

create table somemoreinfo (int infoid not null auto_increment primary key, text info);
insert into somemoreinfo set info="some info here";
insert into somemoreinfo set info="even more information.";
insert into somemoreinfo set info="information overload.";




now we have this foundati i can start off by showing you the most basic of attacks. c this php statement:


代码

$result=pg_query($db,"select message from messages where reluserid=".$_get['uid']." order by messageid");




this may appear in a script that displays all messages posted by a certain user, reached from a page with a list of users to choose from. the url for a page which displays all of some posted messages would be something like http://www.sqlinjection.com/postedby.php?uid=2 so the full sql statement, with substituted variables would be:


代码

select message from messages where reluserid=2 order by messageid




now c this url: http://www.sqlinjection.com/postedby.php?u...20messages%20--

if you were to replace the %20's with spaces, as %20 is simply a url-encoded space, you would see that the sql statement sent to the server now reads like this:

select message from messages where reluserid=2; delete * from messages -- order by messageid

the semicolon ends the first sql statement, and the server is now ready for another... which we provide. the -- is the sql comment syntax - all text following that will be ignored by the server. this would be included by an attacker in case there are more search clauses or ordering directives and such following "where reluserid=2", which there are. if it was left out, the attackers injected sql statement would probably be invalid.

mysql is not vulnerable to this attack, as it allows 1 statement per query, for exactly this reason. postgresql is vulnerable however, and probably others too, as they allow multiple sql statements per query.

protecting against this type of attack is fairly simple, and can be d in two ways. ideally, both ways should be implemented. the first step is to add quote marks around the user-defined variable being comapared to reluserid, like this:

$result=pg_query($db,"select message from messages where reluserid='".$_get['uid']."' order by messageid");

so, when our attacker tries the url above, the sql statements becomes:

select message from messages where reluserid='2; delete * from messages --' order by messageid

the result of this is to put all the users input into a string, which will then be compared against reluserid. however, an attacker still has a way around this. c the effect of an attacker simply adding a ' to his input, thus unquoting the string, and then again we are at his or her mercy. this is quote possible:

http://www.sqlinjection.com/postedby.php?u...20messages%20--

our sql statement then becomes:

select message from messages where reluserid='2'; delete * from messages --' order by messageid

so it looks like we've made absolutely no progress at all. they key is to add backslashes to the user's input before each occcurrence of ' or ". this way, a user can no l open or close a string. with this implemented, the above url generates the sql statement below:

select message from messages where reluserid='2'; delete * from messages --' order by messageid

because of the escaping of the quote, the string compared to the reluserid is now "2'; delete * from messages --", and the attack is now neutralised again.

another precaution that can be taken against this kind of attack is simple data validation. as reluserid is defined in the database as being an int, comparing text to it seems illogical. so first of all, check that the value of $_get['uid'] is in fact a number, and doesn't c anything except digits. if it does, you can promptly stop execution and inform the user he or she is trying to do things that perhaps they shouldn't be doing. here's a php function which will help you do that, and the way i'd implement it in the above example.


代码

function nj_isinteger($checkstring) {
if($checkstring!='' && ereg("^[0-9]*$",$checkstring)) {
return true;
} else {
return false;
}
}

if(!nj_isinteger($_get['uid']))
exit('user inputted uid was not an integer.');




so there we have a good basis for some slightly more advanced sql injection attacks.

now, imagine you wanted a page to select and display everything from a particular table. which table it is the user decides. so it might look like this:

代码
mysql_query($db,"select * from ".$_get['table']);



here, injection can be achieved in much the same way. if the user gave the script the value "users where username='netjester'", they would be presented with my password. which is bad.

the way to protect against injection further than the table to select from, you again, add quotes around the value you're adding, and escape all quotes input by the user.

however, an important lesson is to be learnt here. if you wish to give a user a choice such as which table will be queried, decide which tables you want to allow the user to access, and then, for example, put them in a php array, and use the particular array element required using a number provided by the user. that way, a user can indirectly insert those table names you specify in the array.

ok, now how about we return to the postedby.php idea for another example.

代码

<?php

/* http://www.sqlinjection.com/big/security/h.../hole/index.php */

$db=mysql_c

mysql_select_db('sqlsecdemo');

$sql='select '.$_get['toselect'].' from messages';

$result=mysql_query($db,$sql);

while($row=mysql_fetch_array($result)) {
echo $row['message'].'<br>';
}

?>



on first glance, could be forgiven for thinking that even though this page allows a user to perform pretty much any select query they like on our database, they still wouldn't be able to see their results. this is, however, not true, because of sql's as keyword. if you do not know what as is for, it will be in any good sql tutorial. so, c this url:

http://www.sqlinjection.com/big/security/h...0from%20users--

because the password field has been given the name "message", every time the script goes to print a supposedly public message, it actually prints of our users passwords!

the rule here is again to delimit any user input with quotes, and escape any quotes within that input. better yet, give the user an indirect choice of what to add to the sql statement, so you still have 100% c of what goes in and out of the server. here's an example of a php script that uses indirection.

代码

<?php
// indirect.php

$selecttables=array('messages','somemoreinfo');

if(isset($_get['acti && $_get['acti {
$sql='select * from '.$selecttables[$_get['tableid']];
$db=mysql_c or die('couldn't c
mysql_select_db('sqlsecdemo') or die('couldn't select sqlsecdemo database');
$result=mysql_query($sql,$db);
while($row=mysql_fetch_array($result)) {
foreach($row as $k => $v) {
echo $k.': '.$v."<br>n";
}
echo "<br>n";
}
} else {
for($i=0; $i<sizeof($selecttables); $i++) {
echo '<a href="indirect.php?action=show&tableid='.$i.'">'.$selecttables[$i].'</a><br>';
}
}

?>



this is a very rough-and-ready script, just for dem purposes. as you can see, even though the first part of the sql query is dynamically created from the user's choices, the user still has no way to add their own sql code to the statement. they are simply allowed to choose from a set of predefined options.

now, this last section is specific to mysql only. i have no idea about how users and privileges are defined on any other database servers, if at all. if you want to implement similar techniques on other servers, you will have to look into it yourself.

i see a lot of people write php scripts where they make their everyday database calls after c to the database as root. as any unix enthusiast will know, root is not the account a client should be using to perform everyday tasks. it has unlimited power, and so, there is simply no room for error. instead, less privileged users should be created by the root user, and instead these should be used for everyday database queries. in unix, this practice is both for security reas and for safety reas (to prevent a user accidentally deleting the universe). here it is mainly for security reasons.

for your average php driven website, four different types of query are likely to be needed. these are select, insert, update and delete. we can create 4 different users for each type of query, with privileges allowing them to perform queries of that type. why would we want to do this? well, let's take a moment to think about the statistics of it. the majority of your web applicati mysql queries will be select queries. if there was an exploitable piece of code in your application using a select query, made by a database user with the power to alter and delete information in the database the c would be very grave. if, however, the database user used to make the select call had the ability to read the database, the potential for damage is greatly reduced.

there are two ways to set up mysql database users and their permissions. the first is by using the grant and revoke commands provides by the mysql envir and the sec is to manually edit the 'mysql' database tables. i go for the latter, as the syntax outline for grant and revoke in the mysql manual basically scares me. and also i like to have a deeper understanding of what is actually going on with my server.

so fire up your text-based mysql client. if you d know how to use this, you should really learn, because reading any further without understand that will just c you, and also it is a very useful tool during the development cycle. hit up your 'mysql' database, and then do 'describe user;' to see what the user table fields are. here's the output of that command:

代码

+-----------------+-----------------+------+-----+---------+-------+
| field | type | null | key | default | extra |
+-----------------+-----------------+------+-----+---------+-------+
| host | char(60) binary | | pri | | |
| user | char(16) binary | | pri | | |
| password | char(16) | | | | |
| select_priv | enum('n','y') | | | n | |
| insert_priv | enum('n','y') | | | n | |
| update_priv | enum('n','y') | | | n | |
| delete_priv | enum('n','y') | | | n | |
| create_priv | enum('n','y') | | | n | |
| drop_priv | enum('n','y') | | | n | |
| reload_priv | enum('n','y') | | | n | |
| shutdown_priv | enum('n','y') | | | n | |
| process_priv | enum('n','y') | | | n | |
| file_priv | enum('n','y') | | | n | |
| grant_priv | enum('n','y') | | | n | |
| references_priv | enum('n','y') | | | n | |
| index_priv | enum('n','y') | | | n | |
| alter_priv | enum('n','y') | | | n | |
+-----------------+-----------------+------+-----+---------+-------+



the 'host' field is for specifying a hostmask for the client c to the server. this can include a wildcard (%). if set to 'localhost', c from the same machine are allowed. this means a hacker elsewhere on the internet can't c to your server and start guessing at passwords - even if he or she has the right password, the c will still be refused.

the 'user' field is the name of the user. this can also be a wildcard, and will then apply to any user c to the server not specifying a username, but if you're wanting a secure server, you w want to do this.

the 'password' field c a hash produced by using the built in 'password' function in mysql.

the subsequent fields either c 'y' or 'n', depending on what you set them too. by default they are set to 'n' (do not allow the user this privilege).

first of all i'd recommend you delete all the entries except for the root user with the localhost mask.

now let's set up a group of users for the previously menti database tasks.

代码

insert into user set host="localhost", user="selectuser", password=password("passforselectuser");
insert into user set host="localhost", user="deleteuser", password=password("passfordeleteuser");
insert into user set host="localhost", user="insertuser", password=password("passforinsertuser");
insert into user set host="localhost", user="updateuser", password=password("passforupdateuser");



you may have noticed i didn't set any priviledges with these commands, so all the privileges has defaulted to 'n'. this is because the 'user' table has global scope, ie. a delete privilege here means a user can delete anything from any database in the server. instead, we set the privileges in the privilege tables with a narrower scope.

enter the 'db' table. this let's us set privileges for specific databases for specific users. a 'describe db' produces the following:

代码

+-----------------+-----------------+------+-----+---------+-------+
| field | type | null | key | default | extra |
+-----------------+-----------------+------+-----+---------+-------+
| host | char(60) binary | | pri | | |
| db | char(64) binary | | pri | | |
| user | char(16) binary | | pri | | |
| select_priv | enum('n','y') | | | n | |
| insert_priv | enum('n','y') | | | n | |
| update_priv | enum('n','y') | | | n | |
| delete_priv | enum('n','y') | | | n | |
| create_priv | enum('n','y') | | | n | |
| drop_priv | enum('n','y') | | | n | |
| grant_priv | enum('n','y') | | | n | |
| references_priv | enum('n','y') | | | n | |
| index_priv | enum('n','y') | | | n | |
| alter_priv | enum('n','y') | | | n | |
+-----------------+-----------------+------+-----+---------+-------+



the 'host' and 'user' fields have the same meaning as in the 'user' table. the 'db' field specifies which database subsequent privileges in the record are referring to. so, let's give our users the permissi they need. it's important to mention here that all the users should be given the select privilege. this is because the select privilege is needed for where clauses, as in such cases information must be read from the database.

insert into db set host="localhost", db="sqlseqdemo", user="selectuser", select_priv="y";
insert into db set host="localhost", db="sqlseqdemo", user="deleteuser", select_priv="y", delete_priv="y";
insert into db set host="localhost", db="sqlseqdemo", user="insertuser", select_priv="y", insert_priv="y";
insert into db set host="localhost", db="sqlseqdemo", user="updateuser", select_priv="y", update_priv="y";

now we have our limited privilege users set up and ready to go. but first, we need to reload the information from the privilege tables into mysql so that the changes we have made take effect. this can be d in two ways. the first is to simply shutdown and restart the server, and the sec is to use mysqladmin or the mysql client.

to do it with mysqladmin:

代码

shell> mysqladmin -u root -p flush-privileges
password: *********

to do it from the mysql client, first login as the root user, then do:

mysql> flush privileges;




the new database users are now ready to be used. by sticking to these users, any sql injection holes in your web applicati can have their severity greatly decreased.

that's it for this article, i hope you learnt something about the dangers and preventative measures surrounding sql and mysql.

代码

resources:
http://www.mysql.com/ - the official mysql website.
http://www.mysql.com/doc/en/index.html - searchable mysql manual with user comments.
http://www.php.net/ - the official php website.
http://www.php.net/manual/en/ - the php manual, with user comments.




<-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><->


[] - [ 2 - ms-dos - the forgotten tool by flapjackboy ] - []

in the times since ms-dos, new tools have been developed. rootkits, vulnerability scanners, trojans and so on. this has led not to useful gui tools, but has given birth to script kiddies, who use all these tools, but possess little or no knowledge. what people seem to forget is that although a gui is nice and mostly useful, it is not always needed and sometimes hinders activities. what some people also d realise is that the most useful set of tools is already on your pc, namely dos and its tools.

dos stands for disk operating system, and was made for ibm compatible pc's. in 1981, when ibm launched it's pc, dos was shipped with it. it was written by microsoft for ibm, and was named pc-dos. microsoft published and marketed their own version under the name ms-dos. in the early days all 'ibm-compatibles' used ms-dos. it can be doubted that dos is really a microsoft inventi as the kernel was 'inspired' on the cp/m operating system and the 'command prompt' looks like a reduced unix shell. ms-dos has been the mayor operating system until the early 1990's. they have produced many versi up to 6.22. version 3.0 or above will be ok for most programs. as ibm introduced os/2 and microsoft launched windows 95, dos seems to have vanished. microsoft, and many others, have seized their dos and dos programs developments. but i know of several other 'flavours' of dos. lineo and phystechsoft and intelligent micro software are companies who are c development of 'commercial' dos versions. and there also is the freedos project, some people have joined forces to develop a fully free dos, according to the linux idea.

so now you know about dos. boring i hear you say, so i shall get some good stuff. if, like me (and others) you enjoy exploring your box, now is a good time. open a dos shell...not much is it. a black screen with a command line...wow. well type help and hit return. look at all the commands you can use: xcopy, format...see and you've never seen before? ill go over a few interesting you can explore the rest yourself. one of my favourites is the recover command (undelete if your using 95/98). why bother downloading (and possibly paying) for an un-deleter when you can sue this? the answer is your paying for a gui. you simply put in the drive, the path, the file, and hit return. dos then recovers your file, no gui needed! another command i recommend is type. using "type <path if needed then filename>", you can type file with encoding and it appears! better not do it to a bit file though. this is extremely useful however when you need info on a file or something in it, but cannot copy it. the last i will go over is dumping (not to be c with piping). dumping means sending all the info as it happens to an output file. this is d by running a command with > output.txt on the end (output.txt can be anything you want). this way you could dump a file listing, type, commands, a graphic directory tree (yes it can be d in dos), the list is endless. have fun exploring.

next ill explain how it all relates to the security area. all you need for this is a dos shell. when you started learning, chances are you learned about telnet. from a dos shell you can run telnet...wow. the biggie is that by default on a lan, nt, 2000 and xp clients (and most servers) are running telnet servers on the lan. this lets you c to the machine in a dos shell. no gui doesn't make it any harder to do things...think and you'll come up with a few ideas. also, with a dos shell you can forge mail (my old favourite)! doesn't sound like much, but the things you can do with forged mail is incredible, and from a dos prompt you can do it quicker.

another practical use of dos is netstat. it shows c to and from your machine to another machine, and this can prove to be extremely valuable. for example, you want some ip over msn (lame example i know, but it proves my point)? start a game with them, and using netstat and/or netstat -n you can then find their ip in the list. or, on 9 out of 10 web filters, you can bypass blocked sites by using just netstat. in your web browser, try to load the site. it will come up blocked, but use netstat -n to get its ip and enter the ip into the browser...chances are it w be blocked when you put the ip in. bouncing is also of the most useful things you can do with ods. telnetting through just three machines renders you realistically almost untraceable; it's like having your own proxy. alternate data stream is something incredible you can use in dos.

it was developed with ntfs when nt came out. it has the main stream, for windows and applicati and an alternate for special data. virus scanners (apart from kaperspy) scan the main data stream, so trojans and viruses are undetectable when on the alternate stream. when the mainstream file is executed, it will be executed too. the advantages of this are obvious: hidden files (keyloggers, trojans etc.) show up clean and can be executed without trace. so how can you use this stream? well, you have to attach a file in dos. it's a bit complicated, but not too hard. the syntax is command > fileonmainstream.xxx:file on alternatestream.xxx . the way i usually do it for ease is to copy the file, so i use: "copy file.exe > file1.exe:nastyfile.exe".

see, its easy. the hard part is getting it to the victim, but ill leave you to that, all you social engineers out there. a few other examples are using dos to set up and ftp or tftp server on the target box, or if you felt really bad, dropping a trojan in for a gui. basically, i'm saying that with a bit of imaginati dos can be extremely flexible and useful.

another area of useful things in dos is the applications. by far the most used it the net module in nt, 2000 and xp systems, but most d realise its power. a remote (or local) attacker can use net.exe to do many different things. open dos and hit net, and a load of opti come up. ill take you through a few: share can be used to create, delete or modify shares on the system (e.g. some could share the targets drives for easy access later), user can be used to create, delete, and get a list of users on that system, and group can be used to modify who is in which group, and create or delete groups. net doesn't have a gui either, with skilful use of it a lot (for example, explore net services). also, most pre-compiled exploits that you can get hold of run in dos, and drop you in a dos shell. that is reason why every should know dos well. every should be familiar and capable with it, and it far more powerful that most gui programs; dos applicati are also versatile and no frills (get the dos toolkit from http://illmob.org and see what i mean). you can even irc in dos! it's a small .exe program, no install required, easy to use. if that's not a good applicati i d know what is.

in fact, some things are easier to do in dos than windows. for example, say you need to spoof your box completely (for whatever reas ip, hostname, domain and mac address. in windows, you would have to open system properties, c panel and c properties (and probably have to get hold of a few programs). in dos however, it's easy. open a shell, use hostname <hostname> to change it, ipc to set your ip and mac address, and net to change domain. no gui required, and it was d quickly.

apart from the serious side of dos, there are funny things you can do. say for example, you're in a machine, and decide to mess around (we all go through that phase). you can use net send to send popup messages to the person on that box (that usually scares them silly), or net print to print off a message to them. shutdown (or run in 95/98) can be used to log them off, switch user or reboot the machine (and you can include a comment!). start can be used to start an application in a new window (screensaver for example), or you could create a file on their desktop for instance. i'm sure every can think of something. my pers favourite is changing their system time to 1337 on 2000ad...y2k bug!

ok, say you're using dos but you really need/want a gui for whatever reason. when c to the target, chances are it will be 2000/xp. what you can then do in dos in net start "terminal services". this command starts terminal services in 2000. if you want to stop it, you use net stop "terminal services". this way you can the use remote desktop c or terminal services client to c to that box (to logon to it you need to use an account on there or create using net user). there you go, a gui!

so now you have learned a silly amount about dos, we are going to use it (in theory anyway). for this theoretic hack, we will be using a lan, of eight machines running windows 2000 sp0; is a domain c and seven are clients. on this lan you have a user account, and access to c drive and command prompt (you can tell i'm basing this on my school's network cant you?). you have password crackers and the like on c drive if you need them (which you won't). you fire up telnet, and use netstat to get the server ip (pinging the server with its netbios or hostname will let you ping it). lo and behold, it's running a telnet server. you then telnet to it, but since you are a lowly user you can view c drive and your files. we have many opti here: we could drop a trojan dump hashes, or if your not after raising privileges..you could mess about or do something silly like wipe everything. we will go for raising privileges. at your client end, we use dos to set up an ftp server. you transfer across a keylogger client, but after attaching it in the alternate data stream to something inc (such as noptepad.exe), and set it away remotely. then you wait till the admin logs on (you could net send the server or something to get his attention and get him to log and his/her password is piped to a file. you use type to get the c and then delete the file and log off the server.

now, as admin, you could log on from where you are, but if some catches you you're screwed. so, you fire up terminal services and try to log on as admin...<insert blasphemy here>!!! terminal services is disabled. no problem, you simply telnet back and start terminal services. you then login as admin over terminal services (this way if any was coming you can simply close the window then go back later), and create your own admin account. you then logout of admin, into the new account and your all d you just owned a network using nothing but dos, terminal services and a keylogger (but you could have d it without the keylogger). tracks are covered by deleting events from event logger, and you're all done.

that example shows just how versatile, flexible and powerful dos is and how much it is overlooked. it is my opinion that dos is overshadowed by new gui programs, and since ms is removing dos support from 2000 systems (although slowly), soon it could be g forever. it will be a shame to see it go. it may not be the easiest thing to get into as the learning curve is quite steep, but every should be capable of using it, as it will not let you down (its useful in everyday computing too), its flexibility is endless. i hope you enjoyed my article...now go find a box with port 23 open or something

                                                                                                                **richardlee**  中国红客联盟之红鸟飞翔