ctfshow sprouting new plan
According to several solution ideas of web1, I realized the pass and kill of the following questions. When I think about it carefully, I feel that these questions are good for novices like me
Title 1: web1 code is very secure and has no loopholes
Open the topic. Obviously, this topic examines code audit. We paste the code to audit a wave
<html> <head> <title>ctf.show Mengxin plan web1</title> <meta charset="utf-8"> </head> <body> <?php # Include database connection files include("config.php"); # Judge whether the parameter id submitted by get exists if(isset($_GET['id'])){ $id = $_GET['id']; # Judge whether the value of id is greater than 999 if(intval($id) > 999){ # If the id is greater than 999, exit directly and return an error die("id error"); }else{ # Splicing sql statements with id less than 999 $sql = "select * from article where id = $id order by id limit 1 "; echo "Executive sql For: $sql<br>"; # Execute sql statement $result = $conn->query($sql); # Judge whether there are query results if ($result->num_rows > 0) { # If there is a result, get the value $row of the result object while($row = $result->fetch_assoc()) { echo "id: " . $row["id"]. " - title: " . $row["title"]. " <br><hr>" . $row["content"]. "<br>"; } } # Close database connection $conn->close(); } }else{ highlight_file(__FILE__); } ?> </body> <!-- flag in id = 1000 --> </html>
Most of the topics have comments, so let's learn about the functions
1.isset() function: according to the topic notes, we can probably know that isset function is used to detect whether variables exist
2.intval(): the feature of intval function is actually used here
We write the following code
<?php $id=$_GET['id']; //Defines a variable that passes a GET parameter var_dump($id); //Use VaR_ The dump function outputs what this variable looks like echo "<br />"; //Line feed, easy to distinguish var_dump(intval($id)); //Use VaR_ What does the dump function output look like after being processed by the intval function ?>
Shall we pass? id=1000, the output result is as follows:
Let's pass it on again? id='1000 ', the output result is as follows:
You can see:
$id=$_GET['id']
We pass the parameter '1000' to the variable id, and the direct output is still '1000';
However:
var_dump=intval($id)
It can be found that int(0) is output after being processed by intval function
I'll change the code
<?php $id=$_GET['id']; var_dump($id); echo "<br />"; var_dump(intval($id)); if(intval($id)>999) { echo "true"; } else { echo "false"; } ?>
Expand: I'll expand my knowledge in this place
When processing intval function, if
1. When there are characters in the parameter, the function will directly return 0
2. When a character is in front of a parameter and a number is behind it, the returned value is also 0, for example: abc123
3. When the transmission parameter is preceded by a number and followed by a character, the preceding number is returned and the following character is set to 0
Solution 1: according to this feature and the prompt of the topic, flag in id = 1000
We try to construct a payload:
?id='1000'
Successfully get the flag:
ctfshow{85577894-0cb1-4d0d-9fa2-f7f1b03d77c2}
What if we use it directly here? If id=1000, then
According to this sentence of the title, the error will be returned directly
Solution 2: since the problem has been echoed, can we try to use SQL injection to find the flag according to the echo prompt?
Let's try to construct:
?id=100 or id=1000
After returning, we found that we can also get the flag in this way. This is because when we enter id=100 or id=1000, we first compare 100 and 999 in the if statement, and then query the things in id=1000 to bypass
Solution 3: after searching the articles of some bigwigs, I found another construction method, so I'll learn by the way:
We can construct Negation:
?id=~~1000
Let me talk about the principle:
Suppose we take 10 as an example:
The binary representation of 10 is 1010
Into 32-bit binary: 0000 0000 0000 1010
Bit inversion is: 1111 1111 1111 1111 1111 1111 1111 0101
Then we know that the first 0 / 1 represents positive and negative, so there are:
-111 1111 1111 1111 1111 1111 1111 0101
Negative numbers are represented by complement, and then the complement is the inverse of the original code plus 1, so we subtract 1 from the complement and then take the inverse
-111 1111 1111 1111 1111 1111 1111 0100
-000 0000 0000 0000 0000 0000 0000 1011
Calculated: - 11
In this place, we need to reverse it twice. Because the last data to be queried is the number in 1000, it is still 1000 after two reverse operations, but this can bypass the previous restrictions
Solution 4:
We can also construct a payload:
?id=100%2B900
We know that the database can do calculations, so we construct 100 + 900, but we should pay attention not to inject the + sign directly, because the + sign in the url will be directly parsed into spaces by PHP
Topic 2: web2
The second question is the same as the first question. The difference is that a regular filter is added
if(preg_match("/or|\+/i",$id)){ die("id error"); }
This regular expression filters or and +; The following symbol i marks this is a case insensitive search
If you don't understand, it's recommended that you take a look at the knowledge of regular expressions
Regular expression - matching rules | rookie tutorial
In this way, the second solution above can't be used, but other solutions can be used correctly, as long as there are no filtered keywords, and we can bypass the fourth solution above by changing the + sign to the * sign
Construct payload:
?id='1000'
Topic 3: web 3
if(preg_match("/or|\-|\\|\*|\<|\>|\!|x|hex|\+/i",$id)){ die("id error"); }
Good guy, we filter more this time. In fact, or and + - * /!, are filtered out here!, However, we construct payload:
?id='1000'
It can still be used
Topic 4: web4
if(preg_match("/or|\-|\\\|\/|\\*|\<|\>|\!|x|hex|\(|\)|\+|select/i",$id)){ die("id error"); }
This time, the payload filter has more impact:
?id='1000'
Topic 5: web5
if(preg_match("/\'|\"|or|\||\-|\\\|\/|\\*|\<|\>|\!|x|hex|\(|\)|\+|select/i",$id)){ die("id error"); }
This time, we finally filtered the '", so let's try to take the opposite:
?id=~~1000
Successfully bypassed
Topic 6: web6
if(preg_match("/\'|\"|or|\||\-|\\\|\/|\\*|\<|\>|\^|\!|x|hex|\(|\)|\+|select/i",$id)){ die("id error"); }
Construct payload:
?id=~~1000
Topic 7: web7
if(preg_match("/\'|\"|or|\||\-|\\\|\/|\\*|\<|\>|\^|\!|\~|x|hex|\(|\)|\+|select/i",$id)){ die("id error"); }
Oh, Huo, we found that the ~ symbol is filtered here. It seems that we can only think of other methods. After thinking about it, according to the previous use of binary negation to bypass, can we directly use binary representation 1000 to bypass?
Construct payload:
?id=1111101000
I found it impossible. I thought about it and added the identifier:
?id=0b1111101000
Bypass successful
Interested friends can read this article
ctfshow Mengxin plan web 1-8_ Yu's blog - CSDN blog_ ctfshow Mengxin Web