ctfshow-misc-1-56-图片隐写详解

1.解压得到。

2.拖进010,发现是png

PNG:文件头格式为89 50 4E 47 0D 0A 1A 0A,文件尾格式为49 45 4E 44 AE 42 60 82。

所以将txt文件改成png,即可。

 3.

一个bpg图片,要下一个软件打开:Honeyview · 免费图像查看器 · 下载和功能说明

下载后打开这图片就行。

Honeyview

一款图片查看器,文件出现改动的时候可以实时变化,并且宽容性极强,没看见过他打不开的图片

4.

1.txt拖101发现是png文件,2.txt发现是jpg文件,3.txt发现是bmp文件,4.txt是gif文件,5.txt是tif文件,6.txt是webp文件

要学到一些知识

1.BMP(位图):
	文件头标识:BM(即 0x42, 0x4D)

2.GIF(图形交换格式):
	文件头标识:GIF87a 或 GIF89a(即 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 或 0x47, 0x49, 0x46, 0x38, 0x39, 0x61)

3.JPEG(联合照片专家组):
	文件头标识:FF D8(即 0xFF, 0xD8)

4.PNG(便携式网络图形):
	文件头标识:89 50 4E 47 0D 0A 1A 0A(即 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A)

5.TIFF(标记图像文件格式):
	文件头标识(多种):42 49 4D 00、49 49 2A 00、4D 4D 00 2A(即 0x42, 0x49, 0x4D, 0x00 或 0x49, 0x49, 0x2A, 0x00 或 0x4D, 0x4D, 0x00, 0x2A)

6.WebP(Web 图片格式):
	文件头标识(多种):52 49 46 46、57 45 42 50(即 0x52, 0x49, 0x46, 0x46 或 0x57, 0x45, 0x42, 0x50)

7.ICO(图标文件格式):
	文件头标识:00 00 01 00(即 0x00, 0x00, 0x01, 0x00)

8.PCX(PC 绘图文件格式):
	文件头标识:0A(即 0x0A)

9.PSD(Adobe Photoshop 文件格式):
	文件头标识:38 42 50 53(即 0x38, 0x42, 0x50, 0x53)

杂项基础知识-部分_png文件尾-CSDN博客

然后有就是刚刚下的软件,太牛了,直接打开。无敌好用

5.

拖进101,然后看到文件尾,看到flag。

6.

ctrl+f搜索ctfshow,找到flag。

7.

跟上面一样的啊。

8.

题目提示要

这要下载foremost,然后创造一个foremost-file存储分离后的文件(其实好像可以不要创造,指定一个新命名的文件夹会自动创造)。

CTF中的神兵利刃-foremost工具之文件分离_foremost分离文件-CSDN博客

分离后,一定要root权限打开那文件夹,不然图片看不了!一定要记得。

9.

这题提示flag在题目块,直接秒。

10.

这里要用binwalk,kali自带。

binwalk -e file --run-as=root

很强啊,比foremost好用。

从这里知道,一般可以用binwalk看图片藏了什么文件(其同时会分离,可以查看分离文件有没有藏flag),若藏了图片就用foremost分离看看。

11.

此题又要用一个软件,Tweakpng是一个用于 Windows 平台的低级 PNG 图像文件操作工具。它允许用户查看和编辑 PNG 文件的元数据,适用于需要深入了解和修改 PNG 文件内部结构的用户,下面这篇文章有,并且还有其它工具。

一、图片隐写[Stegsolve、binwalk、010editor、WaterMark、BlindWaterMark、文件头尾、tweakpng、APNG Disassembler]-CSDN博客

然后删除第一个idat。

打开即可misc11。

12.

这个idta太多了,又要下载一个软件,看下文。工具 PNG Debugger 的安装使用_pngdebugger-CSDN博客

PNG Debugger 可以进行读取 PNG 图片的数据,检测各数据块中的 CRC 是否正确,在 Windows 下使用。
CRC 码是 循环冗余校验码 的简称,是 png 图片中一种的数据, 是目前使用非常广泛的数据校验方式,不仅能校验传递过来的数据正确性,还能筛查出哪一位出现了错误。
比如可用于判断 png 图片的宽和高是否正确。

起始位置就是debug文绝对路径。

看完上面的步骤我们可以将misc12放到test文件里(我是这样,模范上面的文章)

pngdebugger ../test/misc12.png     //‘../前有空格’

工具 PNG Debugger 的安装使用_pngdebugger-CSDN博客

这里跑出来都是对的,一个个删,直到出现flag。(最后删了8个)

13.

提示flag再图片末尾,但是没找到,所以看看wp,发现有两种解法。

第一种观察到了ctfshow,但是都隔着一个字符,所以只有隔着字符读就好了。

第二个就是脚本读嘛。

a="631A74B96685738668AA6F4B77B07B216114655336A5655433346578612534DD38EF66AB35103195381F628237BA6545347C3254647E373A64E465F136FA66F5341E3107321D665438F1333239E9616C7D"
r = ''
s=bytes.fromhex(a)
for i in range(0,len(s),2):
        r+=chr(s[i])
print(r)
#fromhex函数把一串16进制字符,每两位转换成16进制的对象

14.

dd if=misc14.jpg of=1.jpeg skip=2103 bs=1

15.

直接搜索就好。

16.

提示说flag在图片数据,直接binwalk看看。

17.

binwalk分析得出有一个bzip,但是什么都分离不出来

zsteg工具:用于检测被隐写在png,bmp图片里的数据。

kali下载。 

git clone https://github.com/zed-0xff/zsteg

cd zsteg/

gem install zsteg

发现隐藏的数据,位置处于extradata:0;用命令提取出来。

zsteg -E  "extradata:0" misc17.png > 1.txt

然后binwalk。

binwalk -e 1.txt --run-as=root

分出来了一个压缩包。

18.

提示:flag在标题、作者、照相机和镜头型号里。

点开属性,都在详细信息里面。照相机和镜头型号往下拉就可以看到。

19.

题目提示:flag在主机上的文档名里。

EXIF信息查看器,用这个查看器(上面的题也可以)查看详细图片属性。

20.

题目提示:flag在评论里。同样刚刚的查看器打开。

由前几个西替爱抚秀,明显是ctfshow的谐音,所以由此读出flag是

ctfshow{c97964b1aecf06e1d79c21ddad593e42}

21.

提示flag在序号里。

这样交肯定是错的,一般flag都是16进制的字符,所以这里需要将x,y的分辨率与定位4段10进制数字转换分别为16进制,依次拼接。

ctfshow{e8a221498d5c073b4084eb51b1a1686d}

脑洞必须大啊。

22.

提示在图片里

binwalk试了没用,101也看不出,看wp。下载新工具:magicexif,开始使用 MagicEXIF 元数据编辑器

magicexif元数据编辑器是一款非常专业的照片magicexif元数据编辑器,该软件可以通过分析照片的元数据以及
编码特征来计算图像可信度,从而判断照片是否被修改,同时还能对相机的快门次数、镜头参数、光圈档位等进行
查看和编辑。

就是一坨,看不清,换方法。

使用工具exiftool ExifTool完全入门指南  kali自带。

可仿造命令

exiftool -ThumbnailImage -b misc22.jpg > 1.jpg

勉强看清楚。

23.

提示在时间,还是用exit

看上面文章执行命令

exiftool a.jpg //读取文件a.jpg的所有元数据
exiftool --ExposureTime misc23.psd //我直接读曝光时间           

在线时间戳转换工具 - UU在线工具
 

这里利用在线时间戳转换,然后将时间戳分别转化为16进制,拼接一起即可。

874865822 2699237688 2156662245 460377706  #全部转为16进制
ctfshow{3425649ea0e31938808c0de51b70ce6a}

41.

jpg图片,但是头格式错了,010修改。

图片没信息。binwalk看看。

也没有,怎么办,我想想。不会了,看wp,我直接一句***,脑洞真大,010搜索F001(其实后面想了想,做不出还是没看懂提示,笨蛋排字不就是F001排字嘛),注意换16进制字节。

提取就是

ctfshow{fcbd427caf4a52f1147ab44346cd1cdd}

图片结构

用tweakpng打开发现CRC校验错误(tweakpng只限制了png),说明要改宽高了
修改png,jpg,gif,bmp四种图片文件的宽高
png: 前四位是宽,后四位是高 //第二行改宽高
jpg: 前两位是高,后两位是宽 //jpg图片文件格式为FFC0后3字节接图片宽高
bmp:前四位是宽,后四位是高,但是是倒着写//第二行改宽高
03 B6———>写成B6 03

先打开属性,确定目前宽高数据,再转换成十六进制在010 editor中找

ctfshow-MISC入门_ctfshowmisc入门-CSDN博客

24.

提示:flag在图片上面。那我们就改一下图片高度。

查看属性,提示flag在上面,那么就改高度。文件头占了53字节,文件结尾在675053字节处。又因为每个像素点由三个字节表示,每个字节控制一种颜色,分别为红、绿、蓝三种颜色。所以文件真实像素大小为(675053-53)/3=225000,所以高度=225000/900=250(16进制是FA),其实这种可以直接拉到最大EE,没必要精密计算。

25.

题目提示flag在图片下面。一样的,这次懒得计算。

但是看到了别人的方法,还是再复现一下。

上面讲述了crc,可以判断png宽高是否正确。所以先看看crc对不对,拖进TweakPNG

发现不对,用脚本爆破算,当图片大小为i:j时的CRC校验值,与图片中的CRC比较,当相同,则图片大小已经确定。

import binascii
import struct
 
crcbp = open("misc25.png", "rb").read()    #打开图片
crc32frombp = int(crcbp[29:33].hex(),16)     #读取图片中的CRC校验值
print(crc32frombp)
 
for i in range(4000):                        #宽度1-4000进行枚举
    for j in range(4000):                    #高度1-4000进行枚举
        data = crcbp[12:16] + \
            struct.pack('>i', i)+struct.pack('>i', j)+crcbp[24:29]
        crc32 = binascii.crc32(data) & 0xffffffff
        # print(crc32)
        if(crc32 == crc32frombp):            #计算当图片大小为i:j时的CRC校验值,与图片中的CRC比较,当相同,则图片大小已经确定
            print(i, j)
            print('hex:', hex(i), hex(j))
            exit(0)

学到一个脚本。嘿嘿嘿。

26.

题目提示flag在图片下面,那不跟上面一样,脚本爆破

脚本太好用了吧舒服。

27.

提示依旧是下面。这里jpg修改宽高上面讲了。

jpg: 前两位是高,后两位是宽 //jpg图片文件格式为FFC0后3字节接图片宽高

28.

不知道为什么改那就用模板看看。

29.

这个git图片由许多帧合成的,所以需要每帧都改高度。

先用上面的方法将git图片高度改了。再用stegsolve

30.

题目提示正确的宽度是950。bmp图,950=3b6

alt+4也可以改

31.

题目提示:高度是正确的,但正确的宽度是多少呢。先看下此文章

bmp格式图的解析_bmp图片格式解析像素-CSDN博客

由上面的文章知道前53字节是头文件。文件结尾字节是457255,头文件字节是53.但是注意最后会剩下2字节,而rgb是3字节构造成的。所以计算是可以去除它。

a=(457255-53)/3
a/=150
print(a)
1082.6666666666667  //如果不算最后2位不构成的rgb字节,算出来的就是整数。

 这个题目好像不是正确宽度flag就不会出。

32.

题目提示:高度是正确的,但正确的宽度是多少呢

直接脚本爆破。

import binascii
import struct

crcbp = open("misc32.png.", "rb").read()  # 打开图片
crc32frombp = int(crcbp[29:33].hex(), 16)  # 读取图片中的CRC校验值
print(crc32frombp)

for i in range(4000):  # 宽度1-4000进行枚举
    for j in range(4000):  # 高度1-4000进行枚举
        data = crcbp[12:16] + \
               struct.pack('>i', i) + struct.pack('>i', j) + crcbp[24:29]
        crc32 = binascii.crc32(data) & 0xffffffff
        # print(crc32)
        if (crc32 == crc32frombp):  # 计算当图片大小为i:j时的CRC校验值,与图片中的CRC比较,当相同,则图片大小已经确定
            print(i, j)
            print('hex:', hex(i), hex(j))
            exit(0)

 这个代码只能爆破png图片。

33.

依旧是脚本爆破。

34.

题目提示:出题人狗急跳墙,把IHDR块的CRC也改了,但我们知道正确宽度肯定大于900

CRC爆破png图片宽度和高度原理以及python代码_根据crc得出正确高度-CSDN博客

看上面的文章明白了crc正确爆破宽高的原理,现在题目crc不正确,怎么办?自然是换一个脚本爆破。

import zlib
import struct
filename = "misc34.png"
with open(filename, 'rb') as f:
    all_b = f.read()
    #w = all_b[16:20]
    #h = all_b[20:24]
    for i in range(901,1200):  #界定宽度的范围
        name = str(i) + ".png"
        f1 = open(name,"wb")
        im = all_b[:16]+struct.pack('>i',i)+all_b[20:]
        f1.write(im)
        f1.close()

35.

jpg图片代码爆破(已知高度爆破宽度)

这里拿到图片,显然宽高都小了,设置高为600(一直加高度,知道可看到字符就开始爆破),再来爆破。

import zlib
import struct
filename = r"misc35.jpg"
with open(filename, 'rb') as f:
    all_b = f.read()
    #w = all_b[159:161]
    #h = all_b[157:159]
    for i in range(901,1200):
        name = str(i) + ".jpg"
        f1 = open(r"misc35" + name,"wb")
        im = all_b[:159]+struct.pack('>h',i)+all_b[161:]
        f1.write(im)
        f1.close()

爆破出来宽度是1000. 

36.

题目提示出题人坦白从宽,正确的宽度在920-950之间。先调整一下高度,将所有帧的高度修改。

看到一些乱码字符。

import zlib
import struct
filename = r"D:\desktop_in_D\题目附件垃圾桶\misc36.gif"
with open(filename, 'rb') as f:
    all_b = f.read()
    #w = all_b[159:161]
    #h = all_b[157:159]
    for i in range(920,951):
        name = str(i) + ".gif"
        f1 = open(r"D:\desktop_in_D\题目附件垃圾桶\\" + name,"wb")
        im = all_b[:38]+struct.pack('>h',i)[::-1]+all_b[40:] # gif 宽度长度区域两个字节,所以用 >h
        f1.write(im)
        f1.close()


 

37.

直接放到stegsolve

拼接即可。

38.

TweakPng 里面打开,发现是有APNG,是 png 的扩展,动图。

使用Honeyview拿到flag(honeyview可以看许多图片的动图,stegsolve好像只能看git图片)

flag片段分别在第 9,14,21,31,34 帧上面。

39.

287帧没找到flag。这题其实是动图的每一帧间隔时间不同传递信息

apt-get install imagemagick          //安装工具

 执行命令将每帧的间隔时间导出到 1.txt

identify -format "%T" misc39.gif > 1.txt

str = '3737363636373737373736373636373736363737363737373636373737373637363636373736373737373737373637373737373737363737363737363736373637373636373636373737363636363737363636373637373636373637373636373736373736363737363637373736363736373737363637363737363736373737363637373637373636363736363737363737373737363636373637373636373637363737363637363637373637373636373737363636373736363736363637373736363736373736373736363737363637373737363636363736373737363637373736363736373737363636373637373636363737373736363636373637373636363636373736373636363737363736373637373736363737373737373637'

# 37  替换为1,36替换为0
str = str.replace('37','1')
str = str.replace('36','0')
print(str)
# # 七个字符为一组转化为 ascii 字符
str = [chr(int(str[i:i+7],2)) for i in range(0,len(str),7)]

print(''.join(str))

然后 flag 41个字符 287 / 41 = 7,所以把 01 字符串分为 41 组,一组 7 个字符,转 ascii ; 

 

杂项入门-图片篇(文件结构)_010修改图片高度-CSDN博客

40.

tweakpng打开发现是apng(png动图)。

APNG图片分解器(APNG Disassembler)是一个用来分解APNG图片的软件,使用这个工具你可以把APNG动画图片中的每一帧都分解出来,并且把帧导出保存为图片.

打开txt发现:

用脚本把每个 txt 的 229 位置上的数提取转 ascii 字符

flag=""
for i in range(1,69):
    if(i<10):
        f = open('apngframe0'+str(i)+'.txt')
    else:
        f = open('apngframe'+str(i)+'.txt')
    s = f.read()
    flag += chr(int(s.split("/")[0][6:]))
print(flag)

注意讲python脚本与文件放在一个文件夹。 

42.

把长度转为 ascii字符即可 

s = [229,152,191,229,152,191,49,99,116,102,115,104,111,119,123,48,55,56,99,98,100,48,102,57,99,56,100,51,102,50,49,53,56,101,55,48,53,50,57,102,56,57,49,51,99,54,53,125]
for i in s:
    print(chr(i),end='')

ctfshow{078cbd0f9c8d3f2158e70529f8913c65}

43.

tk发现crc错误。我们使用 PNG Debugger看看哪些crc错误。

很好,全错,将错误的IDAT块的crc-code提取出来,拼接起来转字符串即可得到flag(从010中也也可以看到idat块)

ctfshow{6eb2589ffff5e390fe6b87504dbc0892}

44.

这个idat块太多了,先提取出来。

把 CRC 校验结果 OK 计为 1 , FAILED 记作 0,统计联合起来转为 ascii。 

 但是要把文本中前十行和最后4行 IHDR 和 IEND 的无用数据去掉,这样就变成 344 个 01 了。刚好够整除 8,8位一组转 ascii 码

# 二进制转换为字符串 8 位一组
def bin2str(bin_str):
    strs = ''
    for i in range(0, len(bin_str), 8):
        strs += chr(int(bin_str[i:i + 8], 2))
    return strs

strs=''
file_name=r'D:\桌面\网安必备\png-debugger-master\Debug\misc44.txt'
with open(file_name, "r") as f:
    lines = f.readlines()
    for line in lines:
        if "OK" in line:
            strs += '1'
        elif "FAILED" in line:
            strs += '0'
# strs 转为 ascii

print(bin2str(strs))

杂项入门-图片篇(文件结构)_010修改图片高度-CSDN博客

ctfshow{cc1af32bf96308fc1263231be783f69e}

45.

hint:有时候也需要换一换思维格式

这里将把 png在线 转化为 bmp,然后 binwalk -e 分离得到 flag.png

PNG转BMP - 免费在线将PNG文件转换成BMP

ctfshow{057a722a5587979c34966c2436283e70}

这个我是看wp才知道的,为啥要转bmp,咋想到的,我真不理解。

46.

通过identify查看它的偏移量,提取出GIF的详细信息

identify misc46.gif > message.txt 

提取它每次偏移的值当做坐标,再作图

import re
import matplotlib.pyplot as plt
from PIL import Image

f = open("misc46", "r")
s = f.read()
#  正则表达式寻找偏移量
data_s = re.findall(r'GIF .*?\+(\d+)\+(\d+)', s, re.DOTALL)
#  将data_s里的坐标从str类型转换成int类型,不然后面的坐标不能识别
data_s = [[int(i) for i in j] for j in data_s]

#  创建一个新的RGB图像,大小为400*70的像素,背景颜色为白色(RGB的值为(255,255,255))
img = Image.new('RGB', (400, 100), (255, 255, 255))
#  创建一个新的RGB图像,大小为1*1的像素,背景颜色为黑色(RGB的值为(0,0,0))
new = Image.new('RGB', (1, 1), (0, 0, 0))

#  循环每次的坐标
for i in data_s:
    #  将new(黑色像素点)粘贴到img(白色像素点)上,相当于填充
    img.paste(new, i)

#  显示img图像
plt.imshow(img)
#  显示窗口以查看图像
plt.show()

ctfshow{05906b3be8742a13a93898186bc5802f}

说实话,想不到。

47.

tk打开发现是apng,且有偏移量。我们010打开有 fcTL 块,是帧控制块, 属于 PNG 规范中的辅助块,包含了当前帧的序列号、图像的宽高及水平垂直偏移量,帧播放时长和绘制方式(dispose_op 和 blend_op)等,每一帧都有一个 fcTL 块。

所以需要从十六进制中提取出偏移量的坐标,再通过坐标进行绘图。直接上大佬脚本。

import struct  # 导入struct模块,用于处理二进制数据
from PIL import Image  # 导入PIL库中的Image模块,用于图像处理
import matplotlib.pyplot as plt  # 导入matplotlib的pyplot模块,用于绘图

try:
    # 尝试打开名为'misc47.png'的文件,并以二进制读取模式读取
    f = open('misc47.png', 'rb')
    c = f.read()  # 读取文件的全部内容到变量c中
    # 从c中找到特定的十六进制序列'6663544C00000001',并截取该位置之后的所有内容
    c = c[c.index(bytes.fromhex('6663544C00000001')):]
    pp = []  # 初始化一个空列表,用于存储解析出来的数据

    # 遍历范围从1到1124,步长为2
    for i in range(1, 1124, 2):
        # 在c中查找特定的模式'6663544C0000'后跟一个无符号短整型i的位置
        start = c.index(bytes.fromhex('6663544C0000') + struct.pack('>h', i))
        # 截取从start位置开始的30个字节
        fc = c[start:start + 30]
        # 打印出fc中特定位置的两个字节序列
        print(fc[18:20], fc[22:24])
        # 解析fc中特定位置的两个字节序列为无符号短整型,并打印出来
        print(struct.unpack('>h', fc[18:20]) + struct.unpack('>h', fc[22:24]))
        # 将解析出来的整型值添加到列表pp中
        pp.append(struct.unpack('>h', fc[18:20]) + struct.unpack('>h', fc[22:24]))

    # 创建一个新的白色图像,大小为400x70像素
    img = Image.new('RGB', (400, 70), (255, 255, 255))
    # 遍历列表pp中的每个元素
    for i in pp:
        # 创建一个新的黑色单像素图像
        new = Image.new('RGB', (1, 1), (0, 0, 0))
        # 将单像素图像粘贴到大图像上,位置由i指定
        img.paste(new, i)

    # 使用matplotlib显示图像
    plt.imshow(img)
    plt.show()

except FileNotFoundError:
    # 如果文件未找到,打印错误信息
    print("文件未找到,请检查文件路径是否正确。")
except Exception as e:
    # 如果发生其他错误,打印错误信息
    print("发生错误:", str(e))

ctfshow{6d51f85b45a0061754a2776a32cf26c4}

48.

hint:附件的第(Di)七(Qi)题(Ti)中有提示

先换文本查看,

查看dpt(题目提示)。

了解到是有一个 DQT 模块,选中模块可以看到是文本中一行内容,是题目的一点提示。
大致意思是计算 FF 的数量并减1

所以我们计算 FF 数量-1,算 32 组刚好就是 flag

0 12 11 0 7 10 13 13 9 0 9 13 0 13 6 0 10 9 2 1 0 1 10 8 11 5 12 7 2 2 3 10

转16进制0cb07add909d0d60a92101a8b5c7223a

ctfshow{0cb07add909d0d60a92101a8b5c7223a}

49.

这题看不懂一点,直接照着wp做吧。

FF E0 - FF EF,16种,刚好32个,E 后面那位就是 flag 里的内容。将数据流16进制导出在txt。然后用此代码即可。

with open('misc49.txt', 'r') as file:  # 打开文件
    content = file.read()  # 读取文件内容
    content = content.replace('\n', '').replace(' ', '')  # 去除换行符和空格
    content_list = content.split('FFE')[1:]  # 以'FFE'为分隔符分割内容,忽略空字符串

result = ""  # 初始化结果字符串
for i in content_list:  # 遍历处理后的列表
    result += i[:1]  # 取每个分割后的字符串的第一个字符

# 生成flag字符串,并取前32个字符
flag = "ctfshow{" + result.lower()[:32] + '}'
print(flag)  # 打印最终的flag字符串

ctfshow{0c618671a153f5da3948fdb2a2238e44}

 50.

拼接即可。

ctfshow{84470883ee1eec2e886436461bf79111}

53.

使用工具Stegsolve RGB 通道设置都为0 即可得到flag

ctfshow{69830d5a3a3b5006f7b11193e9bc22a2}

54.

这里是竖排的所以需要调整一下参数

ctfshow{b1f8ab24b8ca223d0affbf372ba0e4fa} 

55.

图片是倒的,用代码调正,

from PIL import Image

img = Image.open('misc55.png')

img.transpose(Image.FLIP_TOP_BOTTOM).save('out.png')

发现是pk头。 

保存bin,然后改成zip压缩包后缀,解压打开即可。

56.

R4、R2、R1、G4、G2、G1通道有隐写痕迹

ctfshow{1b30c28a5fca6cec5886b1d2cc8b1263}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值