SparK_BR Posted September 8, 2011 Share Posted September 8, 2011 Hi, here, at work, we developed a system through which the user can change the website contents. The thing is, the day before yesterday somebody from either from 209.73.132.242 or 187.35.48.26, have been messing around the 'welcome screen' and managed to login and upload a c99 php shell file (that russian file and database management tool). We are using addslashes (which I heard recently can be bypassed with high unicode chars) and we also encrypt the password before comparing it with database results (our query looks for user, then we get the password and compare). So not even the SysAdmin knows the passwords. Any recomendation as how to stop these attacks? here is a piece of the log (won't do much but...): [09:45:00] <none> (187.35.48.26) MySQL: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM WHERE codigo = ''' at line 1 Stack Trace: #0 httpdocs/admin/control/system/CodeException.class.php(7): SystemLog->trace('MySQL: You have...', true) #1 httpdocs/admin/control/system/Connection.class.php(97): CodeException->CodeException('MySQL: You have...') #2 httpdocs/admin/control/system/Connection.class.php(70): Connection->throwSqlError() #3 httpdocs/admin/arquivo.php(40): Connection->query('SELECT FROM W...') #4 {main} [10:00:17] valemais (209.73.132.242) Usuário Conectado [10:07:33] valemais (209.73.132.242) Stack Trace: #0 httpdocs/admin/beam/system/Beam.class.php(270): SystemLog->trace(NULL, true) #1 httpdocs/admin/control/info/ControleBanners.class.php(175): Beam->salvar() #2 httpdocs/admin/control/system/View.class.php(607): ControleBanners->salvar() #3 httpdocs/admin/control/banners.view.php(6): View->executarAcao() #4 httpdocs/admin/load.php(5): include('/var/www/vhosts...') #5 {main} and then he managed to get into a login loop: [10:11:21] valemais (209.73.132.242) MySQL: Can't create UNIX socket (12) Stack Trace: #0 httpdocs/admin/control/system/CodeException.class.php(7): SystemLog->trace('MySQL: Can't cr...', true) #1 httpdocs/admin/control/system/Connection.class.php(97): CodeException->CodeException('MySQL: Can't cr...') #2 httpdocs/admin/control/system/Connection.class.php(75): Connection->throwSqlError() #3 httpdocs/admin/control/system/Connection.class.php(25): Connection->open() #4 httpdocs/admin/beam/system/Beam.class.php(28): Connection->Connection() #5 httpdocs/admin/beam/foundation/Usuarios.class.php(11): Beam->Beam() #6 httpdocs/admin/control/system/Object.class.php(32): Usuarios->Usuarios() #7 httpdocs/admin/control/system/SystemLog.class.php(39): Object->getSessionUser() #8 httpdocs/admin/control/system/CodeException.class.php(7): SystemLog->trace('MySQL: Can't cr...', true) #9 httpdocs/admin/control/system/Connection.class.php(97): CodeException->CodeException('MySQL: Can't cr...') #10 httpdocs/admin/control/system/Connection.class.php(75): Connection->throwSqlError() #11 httpdocs/admin/control/system/Connection.class.php(25): Connection->open() #12 httpdocs/admin/beam/system/Beam.class.php(28): Connection->Connection() #13 httpdocs/admin/beam/foundation/Usuarios.class.php(11): Beam->Beam() #14 httpdocs/admin/control/system/Object.class.php(32): Usuarios->Usuarios() #15 httpdocs/admin/control/system/SystemLog.class.php(39): Object->getSessionUser() #16 httpdocs/admin/control/system/CodeException.class.php(7): SystemLog->trace('MySQL: Can't cr...', true) #17 httpdocs/admin/control/system/Connection.class.php(97): CodeException->CodeException('MySQL: Can't cr...') #18 httpdocs/admin/control/system/Connection.class.php(75): Connection->throwSqlError() #19 httpdocs/admin/control/system/Connection.class.php(25): Connection->open() #20 httpdocs/admin/beam/system/Beam.class.php(28): Connection->Connection() #21 httpdocs/admin/beam/foundation/Usuarios.class.php(11): Beam->Beam() ... etc ... any information is welcome Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted September 8, 2011 Share Posted September 8, 2011 Are you sure that your upload form processing code is (successfully) checking if the current visitor is logged in and (actually) prevents the form processing code from running if he is not? You won't believe how many times we see 'protected' pages that continue to run the protected code following header() redirects. About the only thing I can tell from the first log printout is that you are apparently dynamically producing the query (the table_name is missing after the FROM keyword, or you removed that when you posted that information) or that code is in an included/required file with the table_name defined in a different file that includes/requires that file and someone directly included the file containing the query and perhaps was able to bypass some of the logic. The second log printout kind of suggests the same thing, that someone directly requested an included/required file that makes a database connection but the database username/password is defined in a file that normally includes/requires that file. You would need to post relevant code if you want help determining what it is or is not doing that someone could bypass. Quote Link to comment Share on other sites More sharing options...
SparK_BR Posted September 8, 2011 Author Share Posted September 8, 2011 I use OOP and MVC, so each beam/ folder class has it's own static table property, implements their getters and setters (modifying a stdClass object), and they all extend from the Beam class that assembles the queries. And I don't know how that query went empty, because even when the user changes something the whole query goes to the log. The 3 single quotes (''') in the log is what worries me. Code is in portuguese, if you know a little spanish, french or latin you may understand a thing or two. attached the control class that log into the system, code is old, so I didn't refactor it for long. [attachment deleted by admin] Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted September 8, 2011 Share Posted September 8, 2011 when the user changes something ^^^ But it's not a user doing something expected, it's a hacker doing something unexpected that your code did not take into account. The 3 single quotes (''') in the log is what worries me. ^^^ The third/final quote is from the mysql_error() output. The other two indicate that an empty string was supplied as a data value to the query, suggesting that the variables holding the table name and the data didn't exist when the query was formed. The code you attached is the log in code. Not the code that checks if the current visitor is logged in and can access any particular page. Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted September 8, 2011 Share Posted September 8, 2011 Also, for the log in code you attached, it would take seeing the functions/class that are called by that code to determine if it is possible to bypass any of the logic. You could be allowing sql injection to match any row in your table, using the simple existence of the result resource (a true value) from a query to indicate that the query matched a row, allowing an empty == empty TRUE comparison to satisfy some condition, ... Quote Link to comment Share on other sites More sharing options...
SparK_BR Posted September 8, 2011 Author Share Posted September 8, 2011 the problem is that, I only use the index.php and the load.php; the index verifies that and redirects to login, then it loads the panel and the middle part is called with Ajax and only changes the middle part of the panel calling load.php; ok, I admit that checking a session var is fragile... but is there a way to manipulate session from client side? [attachment deleted by admin] Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted September 8, 2011 Share Posted September 8, 2011 the index verifies that and redirects to login So, as already suggested, is the 'protected' code on the page that is after the redirect being executed or are you stopping execution on the page when the logic detects that the visitor is not logged in? Quote Link to comment Share on other sites More sharing options...
SparK_BR Posted September 8, 2011 Author Share Posted September 8, 2011 I attached the two files there they do: if(!$_SESSION["logged_in"]){ include("control/login.view.php"); return; } include("control/index.view.php"); Quote Link to comment Share on other sites More sharing options...
SparK_BR Posted September 8, 2011 Author Share Posted September 8, 2011 I found an entry point the arquivo.php which is responsable for getting the uploaded files from the folder to the browser, uses a query to fetch file information, that php was not using addslashes for that, because fetching file information was a secondary task in it, and the file author didn't pay much attention. he was using extract($_GET) and then passing the parameters directly to the function. now I added $connection->escape($string); and $get = array_map("addslashes",$_GET); I hope that's enough sorry for bothering (ps: geolocation on the ip showed me the hacker's house on google maps and nmap told me which services he is running on his machine and what modem he is using... unfortunatelly, I can't do anything with that info :/ ) Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted September 8, 2011 Share Posted September 8, 2011 Addslashes should never be used for security purposes. Use the proper escape function relevant to the kind of db you're using (e.g., use mysql_real_escape_string if you're using a MySQL database), or use prepared statements (look at mysqli and pdo for examples). Also, ensure that the incoming data is of the correct type. For example, if you're expecting an integer, make sure the value coming in is indeed an integer. Quote Link to comment Share on other sites More sharing options...
SparK_BR Posted September 8, 2011 Author Share Posted September 8, 2011 the $connection object there is a class that holds the db link resource as a private attribute and the escape method does mysql_real_escape_string so I'm using both, addslashes and mysql_real_escape_string... tough I might create some asserts for primitive types and type-cast when needed. thanks for the help, I will just mark the thread as solved for now. Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted September 8, 2011 Share Posted September 8, 2011 extract Just about every extract statement should use one of the second parameter choices that prevents overwriting of existing program variables. The default IS to overwrite existing program variables. I personally recommend using EXTR_PREFIX_ALL with a unique prefix so that you know exactly what the variable names will be as the result of any specific extract statement. If there are other extract statements in the script, its likely that a program variable that determines if someone is logged in or controls the program execution is being manipulated as the result of the extract overwriting variables. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.