第九届山东省赛科来杯:简单的JS、左上角的秘密writeup

本文介绍了参与第九届山东省赛科来杯的解题过程,涉及JavaScript逆向工程和图像隐写技术。在MISC部分,通过分析简单的JS脚本来解决问题。在STEGO部分,解析了加密的hex文件,还原图片,并从左上角的像素中揭示隐藏的G值信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MISC

简单的JS

题目中给了一个js脚本,如下

function pseudoHash(string, method) {
  // Default method is encryption
  if (!('ENCRYPT' == method || 'DECRYPT' == method)) {
    method = 'ENCRYPT';
  }
  // Run algorithm with the right method
  if ('ENCRYPT' == method) {
    // Variable for output string
    var output = '';
    // Algorithm to encrypt
    for (var x = 0, y = string.length, charCode, hexCode; x < y; ++x) {
      charCode = string.charCodeAt(x);
      if (128 > charCode) {
        charCode += 128;
      } else if (127 < charCode) {
        charCode -= 128;
      }
      charCode = 255 - charCode;
      hexCode = charCode.toString(16);
      if (2 > hexCode.length) {
        hexCode = '0' + hexCode;
      }     
      output += hexCode;      
    }
    // Return output
    return output;
  } else if ('DECRYPT' == method) {
    // DECODE MISS
    // Return ASCII value of character
    return string;
  }
}
pseudoHash('19131e18041b1d4c47191d19194f1949481a481a1d4c1c461b4d484b191b4e474f1e4b1d4c02', 'DECRYPT');

这个脚本大体流程如下

flag中的字符X
将字符X转化为十进制ASCII码
X>127
X<128
M=383-X
M=127-X
将M转化为两位16进制数输出

简单的逆向一下,写出解题脚本

#f里是简单的js中的值
f = '19131e18041b1d4c47191d19194f1949481a481a1d4c1c461b4d484b191b4e474f1e4b1d4c02'
flag = ''
for h in range(0,len(f),2):
    tmp = int(f[h]+f[h+1],16)
    if (tmp<128):
        flag += chr(127-tmp)
    else:
        flag += chr(383-tmp) 
print (flag)
#flag{db38fbff0f67e7eb3c9d274fd180a4b3}

STEGO

左上角的秘密

题目给出了一个python脚本和hex文件

# encoding=utf-8
flag_enc = open("flag_enc.hex", "wb")
def file_encode(flag):
    i = 1
    while True:
        byte_str = flag.read(1)
        if (byte_str == b''):
            exit()
        byte_str = hex_encode(byte_str)
        file_write(flag_enc, byte_str)
        # print(byte_str, end="")
        i = i + 1
def hex_encode(byte_str):
    tmp = int.from_bytes(byte_str, byteorder="big")
    if (tmp % 2 == 0):
        tmp = (tmp + 1) ^ 128
    else:
        tmp = (tmp - 1) ^ 128
    tmp = bytes([tmp])
    return tmp
def file_write(flag_enc, byte_str):
    flag_enc.write(byte_str)

if __name__ == '__main__':
    with open("./flag.png", "rb") as flag:
        file_encode(flag)
    flag_enc.close()

这个脚本将flag图片加密成为了一个16进制文件,即题目给出的16进制文件,
简单逆向,还原图片

flag_enc = open("flag.png", "wb")
with open("flag_enc.hex", "rb") as flag:
    while True:
        byte_str = flag.read(1)
        if(byte_str == b''):
            exit()
        tmp = int.from_bytes(byte_str, byteorder="big")
        if (tmp % 2 == 0):
            tmp = (tmp + 1) ^ 128
        else:
            tmp = (tmp - 1) ^ 128
        tmp = bytes([tmp])
        flag_enc.write(tmp)
    flag_enc.close()

还原出图片
flag.png
将图片左上角剪下来,分析像素点,发现斜线像素中的G值隐藏信息,使用脚本分析
flag2.png

from PIL import Image           # 导入图片处理的包
from base64 import b64decode    # 导入base64解码的包


im = Image.open('flag2.png')    # 打开图片,图片名为flag2
width = im.size[0]              # 返回图片的宽
height = im.size[1]             # 返回图片的高
pim = im.load()                 # 读取图片的像素信息
tmp = ''                        # 空字符串,接收base64
for h in range(height):         # 循环遍历每一个像素

    for w in range(width):
        # 除去白色的像素点[0][1][2]分别代表RGB三个值,只取其中的G值
        if(pim[w,h][0] == 255 & pim[w,h][1] == 255 & pim[w,h][2] == 255):
            # print(pim[w,h])   # (R,G,B)表示第一通道
            continue
        tmp += chr(pim[w,h][1]) # 将像素点的值(Ascii形式)转化为字符串
        
flag = b64decode(tmp)           # base64解这个字符串
print(flag.decode('utf-8'))     # 以utf-8的形式输出
# flag{c6e4c99a6388c5d2a9ae6ef6a843cea6}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值