WolvCTF 2023

Beginner

Charlotte's Web

F12审计页面源码,发现注释里有/src,于是访问得到以下页面:

image
很明显,用requests发个put类型的包访问即可:

import requests

url = "https://charlotte-tlejfksioa-ul.a.run.app/super-secret-route-nobody-will-guess"  # 请求地址
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36'
}  # 请求头
response = requests.put(url=url,headers=headers)
print(response.text) # 返回字符串的数据
print(response.content.decode('utf-8'))  # 返回字节格式的数据

baby-re

idapro查看字符串即可。

We Will Rock You

根据题目名可以猜测解压密码是rockyou系列口令中的一个,使用kali自带的rockyou.txt进行字典攻击就行。

yowhatsthepassword

考查伪随机数的性质。exp:

import random
import base64

def generate(seed):
  random.seed(seed)
  c = 0
  while c != ord('}'):
    c = random.randint(97, 126)
    print(chr(c), end='')
  print()

secret = 'ly9ppw=='
s = int(base64.b64decode(secret).hex(), 16)
generate(s)

elytra

利用16进制编辑器查看txt,发现0x0d和0x0a这两种不可见字符,发现他们总是以0x0a或者0x0d 0x0a这样的格式出现,所以可以猜测前者对应0,后者对应1,二进制转字符即可。

from Crypto.Util.number import *

f = open('iwon.txt','rb')
s = f.read().replace(b'\r\n',b'1').replace(b'\n',b'0').decode()[2:]
print(s)
c = ''
for i in s:
    if i == '0' or i == '1':
        c = c+i
print(c)
print(long_to_bytes(int(c,2)))

escaped

jail如下:

print("Welcome to my `cat` program. Give me a string and I'll output it back.")
code = input("Enter your string (with double quotes) >>> ")

import ast

if code[0] == '"' and code[-1] == '"' and all(ch != '"' for ch in code[1:-1]):
  compiled = compile('print("' + eval(code) + '")', "out", mode = "exec")
  exec(compiled)

要求发送给server的command必须由""包裹,而command不能再出现",因此可以用\x22来替代"进行绕过,具体用以下本地代码进行测试:

print("Welcome to my `cat` program. Give me a string and I'll output it back.")
code = input("Enter your string (with double quotes) >>> ")

if code[0] == '"' and code[-1] == '"' and all(ch != '"' for ch in code[1:-1]):
  print(eval(code))
  print('print("' + eval(code) + '")')
  compiled = compile('print("' + eval(code) + '")', "out", mode = "exec")
  exec(compiled)

得到绕过方案:

image

theyseemerolling

index占了四个字节,正好与key的高四字节异或,所以flag每次加密仅与key的低四字节异或,只需要用wctf和密文对应部分求key_low即可。

from Crypto.Util.strxor import strxor
import binascii

c = '983f687f03f884a9983f687e0ff2afbc983f687d03a891bd983f687c2bf68990983f687b04e9c0a9983f687a2be8c4a6983f687910c482ff983f687818f7afb6983f687744ee8290983f687644ec9e90983f687517e989bf983f687400ab8dcf'
c = binascii.a2b_hex(c)
t = ''
key_low = strxor(b'wctf',c[4:8])
for i in range(0,len(c),8):
    c_ = c[i+4:i+8]
    t = t + strxor(c_,key_low).decode()
print(t)
# wctf{i_sw3ar_my_pr0f_s4id_r0ll_y0ur_0wn_crypt0}

Crypto

keyexchange

由于DH密钥交换的私钥b由我们输入,那么选取b=1,server发来的就是异或用的secret_key,解密即可。

from Crypto.Util.number import *
import binascii
from pwn import xor

# 发送b等于1就行
key = 2668543409797992702612269088654818531186102270928948082263047581634905998245835832145035015716260403837151010929035746010436046852973802973806425668037266
key = long_to_bytes(key)
c = '4590e5e19727a0dc8303af55ba035bfc943b419cbc144adfc2f1364659e57866cdd0884dc74ae11400067905371e5e953065fac9600f6a7b515b4ef0f357aa92'
c = binascii.unhexlify(c)
print(xor(c,key))

Z2kDH

主要是要理解DH在这里为何能成立:
\(\small Pub_B = 5 ^ b\;mod\;m//4,Pub_A=5^a\;mod\;m//4,secret=(Pub_B\cdot4+1)^b\;mod\;m//4\)
不难猜测必须满足:
\(\small Pub_B\cdot4+1 =5^a\;mod\;m\;,Pub_A\cdot4+1 =5^b\;mod\;m\)
于是用上述关系求解dlp即可。
dlp可参考stackexchange,只要知道阶比较光滑就行了,exp很简单:

from Crypto.Util.number import *

modulus = 1 << 258
def Z2kDH_exchange(public_result, private_exponent):
    return pow(public_result * 4 + 1, private_exponent, modulus) // 4

c1 = 0x99edb8ed8892c664350acbd5d35346b9b77dedfae758190cd0544f2ea7312e81 * 4 + 1
c2 = 0x40716941a673bbda0cc8f67fdf89cd1cfcf22a92fe509411d5fd37d4cb926afd * 4 + 1

P = Zmod(modulus)
y = P(c1)
g = P(5)
a = discrete_log(y,g)
print(a)
a = 88617125774223989137279841031386538078792427262478144097382619232683487654785
secret = pow(0x40716941a673bbda0cc8f67fdf89cd1cfcf22a92fe509411d5fd37d4cb926afd * 4 + 1, a, modulus) // 4
print(long_to_bytes(secret))
# wctf{P0HL1G_H3LLM4N_$M4LL_pr1M3}

Misc

Abstract Art

自动立体图——"Magic Eye" image,可以用解码工具显现物体的大致轮廓:tool,显然是个茶壶,所以flag为wctf{teapot}.

yellsatjavascript

jail
const readline = require("readline");
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// you can run code but you can't access the flag

rl.question(">>> ", (answer) => {
  flag = process.env['flag']
  if (answer.match(/flag/)) {
    console.log(':(');
    process.exit(1);
  }
  if (answer.match(/\./)) {
    console.log('hey, are you trying to access functions? :(');
    process.exit(1);
  }
  if (answer.match(/[{}]/)) {
    console.log('do you think calculators have curly braces? :(');
    process.exit(1);
  }
  eval(answer);
  rl.close();
});

rl.on('close', () => process.exit(0));

js脚本的命令执行,过滤了flag . {},绕过flag可以用base64编码,js引用对象可以不用.而改用console['log'],最后调用eval(atob)把flag的base编码解出来。所以payload为console['log'](eval(atob('ZmxhZw==')))

Limited Characters

jail
import string

allowed = set("1<rjhniocd()_'[]+yremlsp,. ")

code = input("Enter your code:\n>>> ")

if set(code) != allowed:
    raise Exception("No no no! Only: \"1<rjhniocd()_'[]+yremlsp,. \" allowed")

exec(eval(code))

限定了payload所能包含的字符,但没有限定长度,可考虑用chr()来构造set中没有的字符。目的payload为print(open('flag.txt').read()),只利用set中已有的字符(*代表set外的字符)可以构造prin*(open('*l**.***').re*d()),所以只需要想办法把星号用chr()和数字运算替换即可。可用的运算符只有+<<,但也足够了,payload:
'prin'+chr(1+111+(1<<1+1))+'(open('+chr(11+11+11+1+1+1+1+1+1)+chr((1+1+1+11+11<<1+1)+1+1)+'l'+chr(((1<<1)+(11+11)<<1+1)+1)+chr(1+1+1+(1+1+1+11+11<<1+1))+'.'+chr((1+11<<1)+(1+11+11<<1+1))+chr((11+1+1+1<<1)+(1+11+11<<1+1))+chr((1+11<<1)+(1+11+11<<1+1))+chr(11+11+11+1+1+1+1+1+1)+').re'+chr(((1<<1)+(11+11)<<1+1)+1)+'d()'+'''+'1<rjhniocd()_[]+yremlsp,. ')'''

yellsatpython

参考ctftime_wp,主要就是利用open('flag.txt')是一个可遍历的对象,那么用min/max都会遍历该对象返回最短/长的文本,因此payload为min(open('flag'+chr(0x2e)+'txt')).

Forensics

Dino Trading

首先分析FTP协议,很容易分离出一张jpg图片,文件并没有冗余的其他格式文件,猜测是某种隐写,用steghide info 1.jpg 可以看到一个txt文件,于是sudo steghide extractf -sf 1.jpg提取再解base64即可:wctf{an_1mage_in_a_peecap_b64} .

posted @ 2023-03-20 12:08  ZimaB1ue  阅读(254)  评论(0编辑  收藏  举报