1) How can we determine that php matches the database as PostgreSQL? Suppose a php + PostgreSQL website with error echo enabled has an injection point. We are in xx. php? Id = n followed by a single quote '. Its echo will be like this: Warning: pg_query () [function. pg-query]: Query failed: ERROR: unterminated quoted string at or near "'" LINE 1: select * from now where no = 111 '^ in/home/sites/web/school/detail. php on line 307 has several keywords to judge the database as PostgreSQL: the PostgreSQL function pg_query () keyword function. pg in pg-query is familiar with MySQL error echo. Have you found that this unterminated quoted string at or near is not MySQL? The difference between MySQL error echo and this is too big. 2) for the number of fields and the encoding problem between fields, we first inject the above point order by 2 to confirm that the number of fields in the now data table is greater than 2, when we order by 2000, it is obviously impossible to have 2000 data records in that table segment. Of course, there will be an error in Warning: pg_query () [function. pg-query]: Query failed: ERROR: order by position 2000 is not in select list in/home/sites/web/school/detail. php on line 307 makes it possible to guess the correct number of fields. If the number of fields is 14, follow the MySQL step xx. php? Id = 0 + union + select + 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 is OK? But it has a 99% probability problem: Warning: pg_query () [function. pg-query]: Query failed: ERROR: UNION types character varying and integer cannot be matched in/home/sites/web/school/detail. what does php on line 307 echo mean? The problem is very simple. The number of fields before and after union is the same, but the type is different. This is like finding the following: Before Union (the original program): SELECT number, text, date, number, number, time, text, number, text, text, number, number, text, after Union: SELECT number, the number is almost the same as the number we are about to find the ghost game. What we want to do is to correct the difference between fields. The error message does not indicate which of the 14 fields has a problem. We need to adjust the number of fields at one time. I am afraid there is a possibility that n is the 14th power. What should I do? It's very easy. Let's start with 1, 2, 3, 4 ..... All these fields are changed to NULL, for example, xx. php? Id = Correct id number + and + 1 = 1 + union + select + null, null, null, and null will display the original news page correctly. Then, we try to replace null with numbers and replace one with one, if the correct news page is still returned, the number is retained and the next one is replaced. If the error message is returned, null is returned and the next one is replaced. Then we get: Before Union (the original program ): SELECT number, text, date, number, number, time, text, number, text, number, number, text, text, number Union (we inject): SELECT number, NULL, NULL, number, number, NULL, NULL, number, NULL, actual number, number is a minority, generally, we use text-based display bits. It is very easy to find the text-type display bit. Like numbers, replace and confirm in sequence, but this time it is not replaced with numbers, but with text, such as before 'A' Union (the original program ): SELECT number, text, date, number, number, time, text, number, text, number, number, text, text, number Union (we inject): SELECT number, 'A', NULL, number, number, NULL, 'A', number, 'A ', is the number clear? Finally applied to reality: xx. php? Id = 0 + union + select + 1, 'A', null, 2, 3, null, 'B', 2, 'C', 3, 'D', 4, 'E' and '6' will display the digits if the number is no more than 10. 3) When GPC is set to on, a function of PHP is magic quotes. It is called "automatic string escape", that is, you set. php? Id = 3' or '1' = '1 after access, PHP automatically converts it to. php? Id = 3 \ 'or \ '1 \' = \ '1 and then what is the problem with the next step? As we mentioned above, replace the struct field with 'A' to confirm in sequence. If GPC is on, isn't 'A' changed to \ 'a \'??? Yes, it's changed. So this step cannot be performed? The answer is yes. You need to know that computers are designed by humans, and people are the source of computer inspiration. First, what is the purpose of our injection? Display content. So why should we use 'A? 'A' is only a character used for judgment. It is the same as and 1 = 2. It is only used for judgment and has no practical significance. and 1 = 2 can be replaced with 1 = 3, 1 = 4, even 1 = 1000000000000000000000, which is only used for judgment and meaningless. What if we replace 'A' with something meaningful? For example, version () does not need to be enclosed in quotation marks. For a comparison, see xx. php? Id = 0 + union + select + 1, 'A', null, 2, 3, null, 'B', 2, 'C', 3, 'D', 4, 'E', 6 xx. php? Id = 0 + union + select + 1, version (), null, 2,3, null, version (), 2, version (), 3, version (), 4, version (), 6 the entire statement does not use any single quotation mark (4) annotator problem PostgreSQL annotator is not #, that is, if a statement is not ended at the end, it cannot be terminated by adding/* or % 23. So what is it used? Obviously, MySQL, MSSQL, SQLite, and PostgreSQL can also be replaced with % 2b % 2b, with the same effect. It's easy to remember, 2B, second force. In the test, % 2b % 2b may cause a brief loss of response to the access. At present, I do not know where the problem is, but the horizontal line does not show 5) TIPS: PostgreSQL Administrator Account (similar to MySQL root, MSSQL sa) is named S, root database (similar to MySQL mysql database, MSSQL master database) the names are ipvs root and sa's dual-force Administrator with a null password. PostgreSQL also has many dual-force administrators with empty passwords. I have encountered some bash shells that set nologin for PostgreSQL. You know later, you can try to log on to its shell. Well, it's reasonable to say so much about it. How to apply it to practice?