CISCN 2021初赛 little evil(Ruby+解释性语言混淆+侧信道攻击)

借鉴wp:

  1. [原创]2021CISCN逆向-little_evil-CTF对抗-看雪-安全社区|安全招聘|kanxue.com
  2. CISCN Little_evil - Pandaos’s blog (panda0s.top)
  3. CISCN2021 RE writeup (s0uthwood.github.io)

获得flag:M5Ya7

学到的知识:

题目类型:
[[ruby语言逆向]] 用Ruby packer打包的ruby程序
侧信道爆破
subprocess库pyhon的使用
VM逆向(虚拟机逆向 or 代码解释器逆向)
解释性语言代码混淆 使用自己加密自己,运行时再自己解析自己
这个VM其实是Brainfuck解释器

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
...

  v25[0] = a1;
  v24 = a2;
  v3 = sub_52D704(a1, a2, a3);
  v4 = 64;
  if ( v3 )
    goto LABEL_10;
  v5 = malloc(0x1C0uLL);
  qword_1415FC0 = v5;
  if ( !v5 )
  {
    v6 = "NULL != enclose_io_fs";
    v4 = 66;
    goto LABEL_4;
  }
  v7 = v5;
  for ( i = 112LL; i; --i )
    *v7++ = 0;
  if ( sub_52E6E6(v5, &unk_B00CA0, 0LL) )
  {
    v4 = 69;
LABEL_10:
    v6 = "SQFS_OK == enclose_io_ret";
    goto LABEL_4;
  }
  if ( !getenv("ENCLOSE_IO_USE_ORIGINAL_RUBY") )
  {
    v9 = malloc(8LL * (v25[0] + 1));
    v10 = v9;
    if ( !v9 )
    {
      v4 = 101;
      v6 = &unk_819258;
      goto LABEL_4;
    }
    v11 = v24;
    v12 = v25[0];
    v13 = v25[0];
    *v9 = *v24;
    v9[1] = "/__enclose_io_memfs__/local/out.rb";
    for ( j = 1LL; j < v12; ++j )
      v10[j + 1] = v11[j];
    v15 = v13 + 1;
    v16 = 0LL;
    for ( k = 0LL; k < v15; ++k )
    {
      v18 = v10[k];
      v16 += strlen(v18) + 1;
    }
    v19 = malloc(v16);
    if ( !v19 )
    {
      v4 = 114;
      v6 = "argv_memory";
      goto LABEL_4;
    }
    for ( m = 0LL; m < v15; ++m )
    {
      strcpy(v19, v10[m]);
      v10[m] = v19;
      v19 += strlen(v19) + 1;
    }
    if ( v16 != &v19[-*v10] )
    {
      v4 = 120;
      v6 = "argv_memory - new_argv[0] == total_argv_size";
LABEL_4:
      __assert_fail(v6, "main.c", v4, "main");
    }
    v25[0] = v15;
    v24 = v10;
  }
  v21 = getenv("RUBY_DEBUG");
  ruby_set_debug_option(v21);
  setlocale(0, "");
  ruby_sysinit(v25, &v24);
  ruby_init_stack(v26);
  ruby_init();
  v22 = ruby_options(v25[0], v24);
  return ruby_run_node(v22);
}

看到这段代码可以猜测出一定是被混淆过了,在看见ruby就可以知道的ruby写的,但是不知道是如何混淆的!
看别人的wp才知道是Ruby packer打包的,去github找找源码!!
源码:github Ruby packer打包器源码

    ruby_sysinit(&argc, &argv);
    {
	RUBY_INIT_STACK;
	ruby_init();
	return ruby_run_node(ruby_options(argc, argv));
    }

发现确实一样!!打包的话那么我们就需要解包了!

是用Ruby packer打包的ruby程序,Ruby packer 会把源程序相关的打包成 squashfs 文件系统并塞进 ruby 解释器。
ruby packer 用了一个内存虚拟文件系统 enclose_io_memfs

0.第一层混淆ruby packer打包
squashfs 用 binwalk 就可以直接提取
binwalk -Me little_evil

binwalk 是一种常用于数字取证和二进制分析的工具。你提供的命令 binwalk -Me little_evil 是用来执行 binwalk 的特定操作的。下面解释一下命令中每个部分的含义:

  • binwalk:这是命令本身,表示你想要使用 binwalk 工具。
  • -Me:这些是修改 binwalk 行为的选项或标志。具体来说,-M 告诉 binwalk 在发现文件时自动提取它们,-e 告诉它递归地从其他文件中提取文件。
  • little_evil:这是你想要 binwalk 分析并从中提取文件的文件或目录的名称。
┌──(kali㉿kali)-[~/Desktop/比赛题目/历届国赛RE/CISCN 2021初赛 little evil]
└─$ binwalk -Me little_evil

Scan Time:     2024-05-16 15:27:58
Target File:   /home/kali/Desktop/比赛题目/历届国赛RE/CISCN 2021初赛 little evil/little_evil
MD5 Checksum:  0d6a007afd95126327b56b1a43c4311e
Signatures:    411

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             ELF, 64-bit LSB executable, AMD x86-64, version 1 (SYSV)
106199        0x19ED7         mcrypt 2.2 encrypted data, algorithm: blowfish-448, mode: CBC, keymode: 8bit
...
3614240       0x372620        SHA256 hash constants, little endian
3619200       0x373980        SHA256 hash constants, little endian
3619216       0x373990        SHA256 hash constants, little endian
...
13563152      0xCEF510        Copyright string: "Copyright 1995-2017 Jean-loup Gailly and Mark Adler "
13566320      0xCF0170        Copyright string: "Copyright 1995-2017 Mark Adler "

成功提取出来!根据ida获得的字符串:"/__enclose_io_memfs__/local/out.rb"
执行完了之后有一个文件夹_little_evil.extracted,我们在其中提取出主程序,路径:

_little_evil.extracted\squashfs-root\enclose_io_memfs\local\out.rb

源码经过混淆:

美化Ruby文件

这个应该是ruby的语法现学一波:https://www.runoob.com/ruby/ruby-syntax.html
发现关键字符串只有,其他的都是重复变量名:

$l1Il="";$l1lI="";def llIl()$lI1lll=$lI1lll|7;end;def l1lll()$lI1lll=10;end;def llI1l()$lI1lll=$lI1lll|4;end;def lIlI()$lI1lll=$lI1lll+3;end;def l111()$lI1lll=$lI1lll%3;end;def lI1IlI()$lI1lll=$lI1lll|3;end;def ll1l1()$lI1lll=$lI1lll*8;end;def l1lI()$lI1lll=$lI1lll-3;end;def lI1lII()$lI1lll=$lI1lll%1;end;def lIlIl()$lI1lll=$lI1lll&10;end;def lIll()$lI1lll=$lI1lll-4;end;def lII1()$lI1lll=$lI1lll%2;end;def l1III()$lI1lll=$lI1lll|1;end;def l1l111()$lI1lll=$lI1lll|5;end;def l1IIII()$lI1lll=$lI1lll%10;end;def l11I()$l1Il=$l1Il+$lI1lll.chr;end;def lIlll()$lI1lll=$lI1lll*9;end;def l11IlI()$lI1lll=$lI1lll-8;end;def lI1I1()$lI1lll=$lI1lll+5;end;def ll11lI()$lI1lll=$lI1lll&9;end;def lII1l1()send($l1Il[0,4], $l1Il[4,$l1Il.length]);end;

去网站美化一下,再去问问chatgpt:

或者直接白嫖大佬们的美化脚本:

data = open("d:/CTF_Study/Reverse/ciscn历年题目/[CISCN 2021初赛]little evil/out.rb", "r").read()
data = data.replace(";", ";\n")
data = data.replace("()", "()\n\t")
data = data.replace("end;", "end;\n")
 
count = 1     # 函数名的个数
names = {}
for line in data.splitlines():   # 得到后面有换行符\n或\t等字符的一行
    if line.startswith("def"):   # 判断一行开头是否为def
        idx = line.find("(")     # 本身函数名的后面一个位置的下标
        original_name = line[4:idx]   # 得到原先的函数名
        names[original_name] = "func" + str(count)   # 创建字典并赋值
        count += 1
print(names)
 
for element in names:
    data = data.replace(element+"()", names[element]+"()", -1)
    data = data.replace(element+";", names[element]+";", -1)
open("d:/CTF_Study/Reverse/ciscn历年题目/[CISCN 2021初赛]little evil/out2.rb", "w").write(data)

出来了!

1.第二层混淆,通过send(“eval”,“源码”),ruby语法混淆

分析ruby函数发现了:

  1. 定义了21个函数
  2. 使用send函数来执行代码
  3. 通过调用func函数来组合出真实的源码ruby,再通过func21进行执行代码
    解混淆逻辑:
    先写个测试代码了解一下send函数:
$llll = "examWorld"

def exam(param)
  puts "Hello, #{param}!"
end

def func21()
  print $llll[4, $llll.length]
  send($llll[0, 4], $llll[4, $llll.length])
end

func21

可以知道send函数的第一个参数是要调用的函数,第二个是调用函数的参数!!
通过添加一个print函数在send函数上面:

def func21()
	print $l1Il[0,4] +"\n"
	send($l1Il[0,4], $l1Il[4,$l1Il.length]);
end;

输出的函数名是:eval
所以$l1Il[4,$l1Il.length]就是要调用的源码!!!
直接添加输出函数就可以了!

def func21()
	print $l1Il[4,$l1Il.length]
	send($l1Il[0,4], $l1Il[4,$l1Il.length]);
end;

成功泄露出源码解混淆,解出来的依旧是这种混淆:

在来一次解混淆:

源码:

begin $_=$$/$$;@_=$_+$_;$-_=$_-@_
$__=->_{_==[]||_==''?$.:$_+$__[_[$_..$-_]]}
@__=->_,&__{_==[]?[]:[__[_[$.]]]+@__[_[$_..$-_],&__]}
$_____=->_{@__[[*_],&->__{__[$.]}]}
@_____=->_{@__[[*_],&->__{__[$-_]}]}
$______=->_{___,______=$_____[_],@_____[_];_____=$__[___];____={};__=$.;(_=->{
  ____[______[__]]=___[__];(__+=$_)==_____ ?____:_[]})[]}
@______=->_,__{_=[*_]+[*__];____=$__[_];___={};__=$.;(_____=->{
  ___[_[__][$.]]=_[__][$_];(__+=$_)==____ ?___:_____[]})[]}
$_______=->_{$___=[];@___=$__[_];__=___=____=$.;$____,@____={},[]
(_____=->{
  _[____]=='5'?(@____<<____):$.
  _[____]=='6'?($____[@____[$-_]]=____;@____=@____[$...$.-@_]):$.
  (____+=$_)==@___?$.:_____[]})[]
$____=$____=={}?{}:@______[$____,$______[$____]]
(______=->{_[__]==
'0'?($___[___]||=$.;$___[___]+=$_):_[__]==
'1'?($___[___]||=$.;$___[___]-=$_):_[__]==
'2'?($___[___]||=$.;$___[___]=STDIN.getc.ord):_[__]==
'3'?(___+=$_):_[__]==
'4'?(___-=$_):_[__]==
'5'?(__=($___[___]||$.)==$.?$____[__]:__):_[__]==
'6'?(__=($___[___]||$.)!=$.?$____[__]:__):_[__]==
'7'?($><<(''<<$___[___])):$.
(__+=$_)==@___?_:______[]})[]}
$_______['3351635164300000000540000000003164073000000540000003164070070000071730000000541111111131641175160343516445163530440316354031643451634235163516000000054000000000003164344354131645335163435164444516333530444403331635403164344451665163423516351600000054000000000316413443541316453351634351644445163335304444033316354031643444516651634235163516000000005400000000000316403443541316453351634351644445163335304444033316354031643444516651634235163516000000005400000000000031640344354131645335163435164444516333530444403331635403164344451665163423516351600000540000000000031643443541316453351634351644445163335304444033316354031643444516651635164453030441633544033164533516351643000000005400000000003164171111744516644'];rescue Exception;end

2.第三层混淆,通过修改变量名函数名进行Ruby语法混淆

这个解决起来非常困难,对于一个ruby语言的新手来说,根本看不懂!!
去看别人的wp,发现需要使用特别复杂的解混小脚本,太复杂了,看不懂一点所以得自己想办法解决!

0.事后诸葛亮,直接侧信道泄露flag加源码插桩来解决
a.源码插桩

根据别的大佬的wp可以知道这是一个简易的VM,所以就可以想到一个VM的特征,检查flag的时候一定是一个个字节的检查,也就是输入的字符串正确的越多,VM循环的次数也就越多!
先找到VM解析switch:

(______=->{_[__]==
'0'?($___[___]||=$.;$___[___]+=$_):_[__]==
'1'?($___[___]||=$.;$___[___]-=$_):_[__]==
'2'?($___[___]||=$.;$___[___]=STDIN.getc.ord):_[__]==
'3'?(___+=$_):_[__]==
'4'?(___-=$_):_[__]==
'5'?(__=($___[___]||$.)==$.?$____[__]:__):_[__]==
'6'?(__=($___[___]||$.)!=$.?$____[__]:__):_[__]==
'7'?($><<(''<<$___[___])):$.
(__+=$_)==@___?_:______[]})[]}

chatgpt优化一下,而且在每个分支上插入一个变量来实现程序插桩,var0~7:

(______=->{
_[__]=='0'?($___[___]||=$.;
$___[___]+=$_;var0 += 1):
_[__]=='1'?($___[___]||=$.;
$___[___]-=$_;var1 += 1):
_[__]=='2'?($___[___]||=$.;
$___[___]=STDIN.getc.ord;var2 += 1):   #输入位置!
_[__]=='3'?(___+=$_;var3 += 1):
_[__]=='4'?(___-=$_;var4 += 1):
_[__]=='5'?(__=($___[___]||$.)==$.?$____[__]:__;var5 += 1):
_[__]=='6'?(__=($___[___]||$.)!=$.?$____[__]:__;var6 += 1):
_[__]=='7'?($><<(''<<$___[___]);var7 += 1):$.
(__+=$_)==@___?_:______[]})[]
}

再整理一下得出一个插桩版本的ruby脚本:

begin 
var0 = 0;
var1 = 0;
var2 = 0;
var3 = 0;
var4 = 0;
var5 = 0;
var6 = 0;
var7 = 0;
$_=$$/$$;
@_=$_+$_;
$-_=$_-@_
$__=->_{_==[]||_==''?$.:$_+$__[_[$_..$-_]]}
@__=->_,&__{_==[]?[]:[__[_[$.]]]+@__[_[$_..$-_],&__]}
$_____=->_{@__[[*_],&->__{__[$.]}]}
@_____=->_{@__[[*_],&->__{__[$-_]}]}
$______=->_{___,______=$_____[_],@_____[_];
_____=$__[___];
____={};
__=$.;
(_=->{
  ____[______[__]]=___[__];
  (__+=$_)==_____ ?____:_[]})[]}
@______=->_,__{_=[*_]+[*__];
____=$__[_];
___={};__=$.;
(_____=->{
  ___[_[__][$.]]=_[__][$_];
  (__+=$_)==____ ?___:_____[]})[]}
$_______=->_{$___=[];@___=$__[_];
__=___=____=$.;
$____,@____={},[]
(_____=->{
  _[____]=='5'?(@____<<____):$.
  _[____]=='6'?($____[@____[$-_]]=____;
  @____=@____[$...$.-@_]):$.
  (____+=$_)==@___?$.:_____[]})[]
$____=$____=={}?{}:@______[$____,$______[$____]]
(______=->{
_[__]=='0'?($___[___]||=$.;
$___[___]+=$_;var0 += 1):
_[__]=='1'?($___[___]||=$.;
$___[___]-=$_;var1 += 1):
_[__]=='2'?($___[___]||=$.;
$___[___]=STDIN.getc.ord;var2 += 1):
_[__]=='3'?(___+=$_;var3 += 1):
_[__]=='4'?(___-=$_;var4 += 1):
_[__]=='5'?(__=($___[___]||$.)==$.?$____[__]:__;var5 += 1):
_[__]=='6'?(__=($___[___]||$.)!=$.?$____[__]:__;var6 += 1):
_[__]=='7'?($><<(''<<$___[___]);var7 += 1):$.
(__+=$_)==@___?_:______[]})[]
}
$_______['3351635164300000000540000000003164073000000540000003164070070000071730000000541111111131641175160343516445163530440316354031643451634235163516000000054000000000003164344354131645335163435164444516333530444403331635403164344451665163423516351600000054000000000316413443541316453351634351644445163335304444033316354031643444516651634235163516000000005400000000000316403443541316453351634351644445163335304444033316354031643444516651634235163516000000005400000000000031640344354131645335163435164444516333530444403331635403164344451665163423516351600000540000000000031643443541316453351634351644445163335304444033316354031643444516651635164453030441633544033164533516351643000000005400000000003164171111744516644'];rescue Exception;end
puts "\n"
puts "var0: #{var0}"
puts "var1: #{var1}"
puts "var2: #{var2}"
puts "var3: #{var3}"
puts "var4: #{var4}"
puts "var5: #{var5}"
puts "var6: #{var6}"
puts "var7: #{var7}"

开始测试插桩的作用:
分别输入:1234569、M5、M5Y,可以很明显知道var2就算用来对比flag是否正确的位置!

既然知道了是哪个变量来对比数据的正确性,那么就可以开始侧信道泄露flag了!

b.侧信道泄露flag
import re
import subprocess

def AnalysisOutput(outputstr): #解析出字符中var2的值
    # 定义正则表达式模式来匹配变量名和值
    pattern = r'var(\d+): (\d+)'
    # 使用正则表达式找到匹配的变量名和值
    matches = re.findall(pattern, outputstr)
    # 将结果存储在字典中
    variables = {}
    for match in matches:
        var_name = 'var' + match[0]
        var_value = int(match[1])
        variables[var_name] = var_value
        if match[0] == "2":
            return int(match[1])
    
def burp(tmpstr,idx,value):
	tmpvalue = value
	for i in range(33,127):  # 从 0 到 10
		input_str = tmpstr + b"\n"
		process = subprocess.Popen(["ruby", "fin1.rb"],  # 运行我插桩的ruby 脚本
							 stdin=subprocess.PIPE,stdout=subprocess.PIPE)
		output, _ = process.communicate(input_str)  # 输入数字并获取输出
		#print(output)
		if b"OK" in output: #如果有OK则表明爆破成功!
			return tmpstr,-1
		tmpvalue = AnalysisOutput(output.decode('utf-8'))
		if tmpvalue != value:
			return tmpstr,0
		tmpstr[idx] += 1


flag = bytearray(b"!"*10) #由于不知道flag的长度,所以直接定义为10试试
idx = 0
while idx < 10:
    keystr,a = burp(flag,idx,idx+1)
    if a == -1:
        print("flag是:",flag)
        break
    print(keystr)
    #flag = keystr
    idx += 1

成功爆破出flag,正确的flag是M5Ya7:

1.大佬的解混淆脚本,再源码分析,再分析VM,就出flag了:

这个VM其实是Brainfuck解释器

import re
data = open("3.rb", "r").read()

target = '1'
for i in re.findall(r"\$_[^_]", data, re.M | re.S):
    if i[-1] != "=":
        print(i)
        data = data.replace(i, target + i[-1])

# @_
target = '2'
for i in re.findall(r"@_[^_]", data, re.M | re.S):
    if i[-1] != "=":
        print(i)
        data = data.replace(i, target + i[-1])

# $-_ => -1

target = '-1'
for i in re.findall(r"\$-_[^_]", data, re.M | re.S):
    if i[-1] != "=":
        print(i)
        data = data.replace(i, target + i[-1])

# $__ -> proc1

target = '$proc1'
for i in re.findall(r"\$__[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, target + i[-1])

# @__
target = '@proc2'
for i in re.findall(r"@__[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, target + i[-1])

# $_____
target = '$proc3'
for i in re.findall(r"\$_____[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, target + i[-1])

# @_____
target = '@proc4'
for i in re.findall(r"@_____[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, target + i[-1])

# $______
target = '$proc5'
for i in re.findall(r"\$______[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, target + i[-1])


# @______
target = '@proc6'
for i in re.findall(r"@______[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, target + i[-1])

target = '@varX'
for i in re.findall(r"@___[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, target + i[-1])

# $_______
target = '$proc7'
for i in re.findall(r"\$_______[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, target + i[-1])

# $___
target = '$arr1'
for i in re.findall(r"\$___[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, target + i[-1])



# $____
target = '$var3'
for i in re.findall(r"\$____[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, target + i[-1])

# @____
target = '@var4'
for i in re.findall(r"@____[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, target + i[-1])

# [^_]____[^_]
target = 'var5'
for i in re.findall(r"[^_]____[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, i[0] + target + i[-1])

# [^_]___[^_]
target = 'var6'
for i in re.findall(r"[^_]___[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, i[0] + target + i[-1])


# ______
target = 'var7'
for i in re.findall(r"[^_]______[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, i[0] + target + i[-1])

# _____
target = 'var8'
for i in re.findall(r"[^_]_____[^_]", data, re.M | re.S):
    print(i)
    data = data.replace(i, i[0] + target + i[-1])
    data = data.replace(i, i[0] + target + i[-1])

data = data.replace(";", ";\n", -1)
try:
    open("out4.rb","w").write(data)
except Exception as e:
    print(e)

解混淆后的源码:

begin $_=$$/$$;
@_=1+1;
$-_=1-2;
$proc1=->_{_==[]||_==''?$.:1+$proc1[_[1..-1]]}
@proc2=->_,&__{_==[]?[]:[__[_[$.]]]+@proc2[_[1..-1],&__]}
$proc3=->_{@proc2[[*_],&->__{__[$.]}]}
@proc4=->_{@proc2[[*_],&->__{__[-1]}]}
$proc5=->_{var6,var7=$proc3[_],@proc4[_];
var8=$proc1[var6];
var5={};
__=$.;
(_=->{
  var5[var7[__]]=var6[__];
(__+=1)==var8 ?var5:_[]})[]}
@proc6=->_,__{_=[*_]+[*__];
var5=$proc1[_];
var6={};
__=$.;
(var8=->{
  var6[_[__][$.]]=_[__][1];
(__+=1)==var5 ?var6:var8[]})[]}
$proc7=->_{$arr1=[];
@varX=$proc1[_];
__=var6=var5=$.;
$var3,@var4={},[]
(var8=->{
  _[var5]=='5'?(@var4<<var5):$.
  _[var5]=='6'?($var3[@var4[-1]]=var5;
@var4=@var4[$...$.-2]):$.
  (var5+=1)==@varX?$.:var8[]})[]
$var3=$var3=={}?{}:@proc6[$var3,$proc5[$var3]]
(var7=->{_[__]==
'0'?($arr1[var6]||=$.;
$arr1[var6]+=1):_[__]==
'1'?($arr1[var6]||=$.;
$arr1[var6]-=1):_[__]==
'2'?($arr1[var6]||=$.;
$arr1[var6]=STDIN.getc.ord):_[__]==
'3'?(var6+=1):_[__]==
'4'?(var6-=1):_[__]==
'5'?(__=($arr1[var6]||$.)==$.?$var3[__]:__):_[__]==
'6'?(__=($arr1[var6]||$.)!=$.?$var3[__]:__):_[__]==
'7'?($><<(''<<$arr1[var6])):$.
(__+=1)==@varX?_:var7[]})[]}
$proc7['3351635164300000000540000000003164073000000540000003164070070000071730000000541111111131641175160343516445163530440316354031643451634235163516000000054000000000003164344354131645335163435164444516333530444403331635403164344451665163423516351600000054000000000316413443541316453351634351644445163335304444033316354031643444516651634235163516000000005400000000000316403443541316453351634351644445163335304444033316354031643444516651634235163516000000005400000000000031640344354131645335163435164444516333530444403331635403164344451665163423516351600000540000000000031643443541316453351634351644445163335304444033316354031643444516651635164453030441633544033164533516351643000000005400000000003164171111744516644'];
rescue Exception;
end

下面就是大佬的操作了!:CISCN Little_evil - Pandaos’s blog (panda0s.top)

  • 48
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值