0%

isa_ctf2

Web - Code Check(湖湘杯)

源码分析

从get请求id参数中解密出正确id,然后执行sql查询语句,将查询结果返回到数组
decode函数:
将传入的data(也就是get方法的id参数)解2次base64后
使用aes-128位 CBC模式 填充为ZeroPadding 解密,key为ydhaqPQnexoaDuW3 iv为2018201920202021
检测解密后的数据后7位是否为hxb2018
如果不是则输出<script>window.location.href="/index.php";</script>
也就是js跳转到/index.php
否则,返回去除首尾空格以及末尾hxb2018后的明文数据

temper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import base64
from Crypto.Cipher import AES
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
pass


class AESCipher:
def __init__(self, key,iv):
self.key = key[0:16]
self.iv = iv[0:16]

def __pad(self, text):
"PHP只有ZeroPadding"
text_length = len(text)
amount_to_pad = AES.block_size - (text_length % AES.block_size)
if amount_to_pad == 0:
amount_to_pad = AES.block_size
pad = '\0'
return text + pad * amount_to_pad

def encrypt(self, raw):
raw = self.__pad(raw)
cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
return base64.b64encode(base64.b64encode(cipher.encrypt(raw)))

def encrypt(text):
Enc = AESCipher("ydhaqPQnexoaDuW3","2018201920202021")
return Enc.encrypt(text+"hxb2018")

def tamper(payload, **kwargs):
return encrypt(payload)

Misc - Disk(湖湘杯)

ftk打开发现有4个flag文件,保存下来是二进制,转十进制然后转ascii
https://www.jianshu.com/p/62c629c076ad

其实直接010打开搜索flag就可以发现有ads隐写了,不过用工具更方便

Reverse - Replace(湖湘杯)

upx脱壳,我是直接copy算法出来爆破解决的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "stdafx.h"
#include<iostream>
using namespace std;
int main() {
unsigned char byte_402150[] = { 0x32,0x61,0x34,0x39,0x66,0x36,0x39,0x63,0x33,0x38,0x33,0x39,0x35,0x63,0x64,0x65,0x39,0x36,0x64,0x36,0x64,0x65,0x39,0x36,0x64,0x36,0x66,0x34,0x65,0x30,0x32,0x35,0x34,0x38,0x34,0x39,0x35,0x34,0x64,0x36,0x31,0x39,0x35,0x34,0x34,0x38,0x64,0x65,0x66,0x36,0x65,0x32,0x64,0x61,0x64,0x36,0x37,0x37,0x38,0x36,0x65,0x32,0x31,0x64,0x35,0x61,0x64,0x61,0x65,0x36 };
unsigned char byte_4021A0[] = { 0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76,0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0,0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15,0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75,0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84,0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF,0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8,0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2,0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73,0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB,0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79,0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08,0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A,0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E,0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF,0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16,0x48 };

char v5; // al
int v6; // esi
int v7; // edi
char v8; // al
int v9; // eax
char v10; // cl
int v11; // eax
int v12; // ecx

for (int i = 0; i < 35; i++) {

for (int j = 32; j < 127; j++) {
v5 = j;
v6 = (v5 >> 4) % 16;
v7 = (16 * v5 >> 4) % 16;
v8 = byte_402150[2 * i];
if (v8 < '0' || v8 > '9')
v9 = v8 - 87;
else
v9 = v8 - 48;
v10 = byte_402150[2 * i + 1];
v11 = 16 * v9;
if (v10 < '0' || v10 > '9')
v12 = v10 - 87;
else
v12 = v10 - 48;
if (byte_4021A0[16 * v6 + v7] != ((v11 + v12) ^ 0x19))
continue;
cout << (char)j;
}

}
return -1;
}

而dalao都是直接看破算法的本质 Orz

要求table[input[i]] == atoi(data[2i]+data[2i+1])^0x19
https://www.anquanke.com/post/id/164604#h2-5

Reverse - HighwayHash64(湖湘杯)

分析

这种题一般都会修改默认的加密参数,所以编译时需要修改默认的c语言文件
基本上参考dalao的方法,编译修改过的模块,用python爆破

第一个判断,用来验证 flag 的长度,经过爆破,确定 flag 的长度为 19(也可动态调试获得0x13)
第二个判断,用来验证 flag 格式内的值,也可以爆破,来确定 flag 格式内的值

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from highwayhash import *

key = b"\0" * 32
data = b"\0" * 64

def reserveHex(text):
ret = ""
lens = len(text)
times = int(lens/2)
for i in range(times):
ret+=text[lens-2*i-2:lens-2*i]
return ret

res = bytes.fromhex(reserveHex("D31580A28DD8E6C4"))

i=20
while True:
i-=1
data=str(i)
data=data.rjust(2,"0")
data=bytes.fromhex(data+"000000")
op=highwayhash_64(key, data)
if op == res:
print (i)
break
else:
print(".")

i=1532649709
#因为已经爆破出来是1532649708,所以就直接写了
res = bytes.fromhex(reserveHex("E3BE26AF8730545A"))
while True:
i-=1
data=str(i)
data=data.rjust(10,"0")
data=bytes(data,"ascii")
op=highwayhash_64(key, data)
if op == res:
print (i)
break
else:
print(".")

趣味密码

+++++ +++++ [->++ +++++ +++<] >++.+ +++++ .<+++ [->– -<]>- -.+++ +++.< ++++[ ->+++ +<]>+ +++.< ++++[ ->— -<]>- -.+++ ++.++ ++++. <+++[ ->— <]>– —-. <+++[ ->+++ <]>++ ++.<+ ++[-> —<] >—- .<+++ [->++ +<]>+ ++++. +.<++ +[->- –<]> –.++ +++.- —– -.<++ ++++[ ->— —<] >.<++ ++++[ ->+++ +++<] >++++ +++++ ++.++ +++++ .—- —– .++++ .—- -.<++ +[->+ ++<]> +++++ .<

一段bf代码,在线解密得到flag

flag{interestingCrypto}

你玩英雄联盟吗

是一个流量包,wireshark打开,搜索flag,发现post了一个压缩包
导出发现有密码,但是可以明文攻击
解压出来的flag.zip是伪加密,修复后解压出一个反色的二维码
反色后在线解析得到flag

紫霞仙子

分析

jpg文件后隐藏有一个zip文件,提取出来后发现是伪加密,解压出一个包含rgb值的txt文件,有74884行
数字帝国查询,得到分解因式的结果
2x2x7x193

猜测高度宽度为386,194
于是用搜索引擎查找rgb值转图片,得到一个转换脚本
手动删除txt文件的括号后使用脚本转换

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from PIL import Image

x = 386 #x坐标 通过对txt里的行数进行整数分解
y = 194 #y坐标 x * y = 行数

im = Image.new("RGB", (x, y)) #创建图片
file = open('rgb.txt') #打开rbg值的文件

#通过每个rgb点生成图片
for i in range(0, x):
for j in range(0, y):
line = file.readline() #获取一行的rgb值
rgb = line.split(",") #分离rgb,文本中逗号后面有空格
im.putpixel((i, j), (int(rgb[0]), int(rgb[1]), int(rgb[2]))) #将rgb转化为像素
#im.save('flag.jpg')
im.show()