分类目录归档:CTF竞赛 CTF Contest

Jack’s 2022 New Year CTF WriteUp

榜单

本届Jack's 2022 New Year CTF共有7人参加,瓜分了121.5元奖金。

Place User Score Bonus
1 undefined 576 55.76
2 bml 576 25.76
3 shadowmov 431 24.31
4 SY 266 7.66
5 小红花 195 6.95
6 jzqsss 101 1.01
7 TaQini 5 0.05

本次比赛中,题目JackZIPPacker因无人解决,留到明年继续出题。
题目环境会始终开启,供大家玩耍。

继续阅读

第二届BJDCTF DreamerJack题目出题人题解

下面是DreamerJack同学的出题人题解。

Programming: Strenuous_Huffman

本题的题解需要占个坑。主要是因为吧。。。题目描述里说的是真的。。这个是本人的数据结构作业,老师还没审查,直接把整套源码发出来我作业就不用交了,所以先占个坑。后续整套源码会发布到Github上。不过可以先说下本题的难点在哪里。其实这个题只是我数据结构作业题的一部分,只涉及解压缩。难度相对于压缩部分较小。正统解法是BitMap+Trie Tree解压。如果暴力一点也可以不用Trie。难度就在于BitMap的编写上。因为这个压缩的时候都是按位压缩的,最低的操作单位是比特。而咱们C/C++操作的最低单位都是按字节。所以要求代码编写者对位运算有比较深刻的认识才能够写得出来。

主要的解题思路如下。编写一个BitMap类,要支持从文件加载内容到内部数组和将内部数组存储到文件中,还要支持按位对数组的访问。然后按照压缩编码和原始编码的对应关系,逐个的将压缩后的比特信息翻译为原始信息并保存。

整套源码发布遥遥无期(看老师啥时候查完作业),想要源码的同学可持续关注本文章。
PS:要提醒的一点是:我自己开发的压缩算法经过测试,确实压缩效果较差。本源码仅供教学用途使用。不要异想天开真的拿这玩意去压缩东西。。。

2020.05.09:此代码已开源:https://github.com/bjrjk/JackZIPPacker

Reverse: 8086 ASM

为什么想要出这道题目呢?我校最近正在学习8086汇编,因此出这道题目。
源码如下:

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
DATAS SEGMENT
    str1 DB 5dH,55H,5bH,64H,75H,7eH,7cH,74H
    DB 40H,7bH,7aH,40H,77H,6aH,2eH,7dH,2eH
    DB 7eH,71H,40H,67H,6aH,7aH,7bH,7aH,40H
    DB 77H,7aH,71H,57H,7eH,2fH,62H,59
DATAS ENDS

STACKS SEGMENT
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
loc:
    jmp loc
    mov CX,34
    lea BX,str1
   
lop:
    mov DI,CX
    dec DI
    xor BYTE PTR [BX][DI],31
    loop lop
    lea DX,str1
    mov AH,09H
    int 21H
    ret
START:
    MOV AX,DATAS
    MOV DS,AX
    call loc
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

本题其实很简单,str1存放的是一个MSDOS格式的以$结尾的经过异或加密的字符串。汇编代码就是把这玩意解密了一下然后syscall输出。jmp loc的死循环就是用来干扰人的。如果想要不劳而获放到DOS里直接跑会死循环。放到IDA里看的话,IDA会把lop下面那段代码当作是数据。需要把他们强转一下成代码才行。本题也可以用调试器手动改EIP执行。顺便宣传一下自己做的8086调试器套件:DOSBox-8086Assembly
PS:我汇编学的还行是真的^v^,死循环是我故意写的^v^

Misc: A Beautiful Picture

很简单的一个png隐写。说实话,图画的不怎么好看。。一看这图片长1000,高900,有没有感觉有点不对劲呢?用010HexEditor,直接把png图片高度改成1000,flag就出来了。。

更新:题目复现地址: https://buuoj.cn/
20200510更新:本人CTFd已下线。
题目下载链接:https://renjikai.com/wp-content/uploads/2020/03/BJD2_DreamerJack.zip

BJD CTF Programming notakto_1

不知名CTF比赛的不知名题目,类井字棋,要写程序判断。
写了两个程序:如下:
C++有漏洞,够用就行:

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
43
#include<iostream>
#include<algorithm>
using namespace std;
int process[10] = { 4 };
bool visited[10];
inline int cal(int x, int y) {
    return x * 3 + y;
}
bool& vis(int x, int y) {
    return visited[cal(x, y)];
}
bool check(int x, int y) {
    bool flag = false;
    flag |= vis(0, y) & vis(1, y) & vis(2, y);
    flag |= vis(x, 0) & vis(x, 1) & vis(x, 2);
    if (x == y)flag |= vis(0, 0) & vis(1, 1) & vis(2, 2);
    if (x + y == 2)flag |= vis(0, 2) & vis(1, 1) & vis(2, 0);
    return flag;
}
void print(int n) {
    for (int i = 0; i <= n; i++) {
        cout << process[i];
    }
    cout << endl;
}
void dfs(int step) {
    bool flag = true;
    for (int i = 0; i < 9; i++) {
        if (visited[i])continue;
        visited[i] = true;
        process[step] = i;
        if (check(i / 3, i % 3) == 0) {
            dfs(step + 1);
            flag = false;
        }
        visited[i] = false;
    }
    if (flag&&step%2==1)print(step);
}
int main() {
    visited[4] = true;
    dfs(1);
}

python连带着往外发socket麻烦得很:

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
43
from pwn import *
sock = remote("222.186.56.247",8122)
wordList = []
currentWord = ""

def findNewWord():
    global currentWord,wordList
    for elem in wordList:
        if elem[0:len(currentWord)]==currentWord:
            return elem
    raise Exception("Error:Word Not found!")

def loadDic():
    global wordList
    with open("situation.txt","r") as f:
        wordList = f.readlines()
   
def getIntfromSock(sock):
    sock.recvuntil("My move: ")
    x = sock.recv(1)
    if x==b' ': x = sock.recv(1)
    return int(x)

def payGame(i):
    global currentWord,wordList,sock
    print("the ith:",i)
    currentWord=""
    while len(currentWord) < 5:
        backupWord = findNewWord()
        print("Send:",backupWord[len(currentWord)])
        sock.sendline(str(backupWord[len(currentWord)]))
        currentWord += backupWord[len(currentWord)]
        if len(currentWord)==5:
            print("break")
            break
        currentWord += str(getIntfromSock(sock))
        print("currentWord",currentWord)
    sock.recvuntil("win!")

loadDic()
for i in range(150):
    payGame(i)
sock.interactive()

代码链接:notakto

2017红包解析

红包网址:http://rb.renjikai.website/2017-redbag1/

解析rb1:老套路,审查元素form的Hidden,year=2017提交即可。
出现decode_base64('u606du559cu4f60u4eecu901au8fc7u0072u0062u0031u7ea2u5305')
base64解码得
刚刚才发现我出错了,本来应该是base64解码的,我忘了给字符串加Base64了……
直接对u606du559cu4f60u4eecu901au8fc7u0072u0062u0031u7ea2u5305进行unicode转中文(网上各类小工具,用Notepad把u替换\u即可)得到“恭喜你们通过rb1红包”,这个是支付宝中文口令。
查看rb1源代码可以发现注释small hint for rb2:sql injection,明确rb2目标sql注入。

解析rb2:sql注入:username和password都输入即可,出支付宝红包口令translate_to_chinese("congratulation")+"C2AEE99934",translate_to_chinese("congratulation")是“恭喜”+"C2AEE99934"=“恭喜C2AEE99934"即为支付宝中文红包口令。

解析rb3:新套路,暴力破解。
查看html源码,有注释guess is a 4-digit postive number,可以编写脚本从1000尝试到9999自动Post即可,最后发现这个数是5716,输出数字口令88281030。

目前该页面已经移动到http://rb.renjikai.website/2017-redbag1/(早已下线),感兴趣的同学可以稍后尝试,源代码稍后发布
源代码下载地址:https://pan.renjikai.com/Bucket/2017-redbag1.zip