avatar

目录
SarCTF Write(吐)Up(嘈)

SarCTF

cover

On February 15-16, 2020, the online CTF (jeopardy) competition was held - SarCTF, with the support of the Saratov State University.

鹅国某个大学主办的CTF,由于有时差,比赛15号晚上十点才开始,持续24小时。logo设计的不错,第一眼看上去,还以为右上角是只熊,仔细一看,原来是个帽子…不得不吐嘈一下主办方的服务器,十点一到,瞬间挤爆,各种连接不上,主办方折腾了半天,推迟到十点半,比赛终于开始了。

刷新了许久,终于刷出Challenges的我直接奔向逆向题,扫了一眼,一共有三道题,一道linux,两道win,由于担心服务器不一会儿后又会宕掉,于是就全下载了下来。

linux那题极为简单,1分钟就做完了,没成想,提交flag却卡了整整5分钟…交完flag的我,正准备解决剩下两道题,随手刷新了一下页面,嗯??逆向的题消失了,只剩下我刚做的一道了…莫非是题目出问题了?于是看了看群里的消息,有个师傅吐嘈道:

Yeah I went to input flag and it’s gone haha

翻译:我刚想交flag,题目就消失了,哈哈(尬笑)。

主办方如是回答道:

These two jobs will not be deleted and will not be returned.

翻译:这两道题没有被删除,但是你也别想再看到他们了。

嗯??这是什么神仙操作……


说到官方交流群,倒是有不少好玩儿的,其中有位俄国老兄,发了张图片:

wine

一台电脑,一壶烈酒,点点灯光,此情此景,虽不乏惬意,却也是十分壮烈,不愧是战斗民族…

p.s.此时电脑屏幕显示的是502Error(网关挂掉了)


好了,闲言少叙,回归正题,这次比赛是跟学校里的另外六名小伙伴儿组队参加的(我第一次组队参加线上赛!终于不是孤身一人了哈哈)虽说解出的题目不多,但也涨了不少见识。刚开赛的时候排名还比较靠前,大概在十几名,后来大家都困了就都去睡觉了,第二天一起来,排名就掉到了100开外,于是一路猛追,最终在417个队伍里面排名第47,也还不错啦~
rank
mem
bd
tsolve

这次比赛的题型居然没有pwn,不过多了个PPC(Professional Programming Challenges),看着比较新鲜,其实就是考察编程能力,其实也没有考察什么编程能力,顶多算是处理socket的输入输出…

Reverse

Crossw0rd

  • 题目描述:

    While the children were playing toys, Sherlock was solving crosswords in large volumes.

    cw

  • 考察点:逆向分析

  • 难度:入门

  • 初始分值:1000

  • 最终分值:309

  • 完成人数:264

非常简单的逆向分析题,首先反汇编程序,分析程序流程:

c
1
2
3
4
5
6
7
8
9
10
11
12
13
unsigned __int64 check(void){
char v1; // [rsp+0h] [rbp-20h]
unsigned __int64 v2; // [rsp+18h] [rbp-8h]

v2 = __readfsqword(0x28u);
puts("Welcome. You're in function check. Please Enter a password to continue. 1 attempt remaining:");
scanf("%s", &v1);
if ( (unsigned __int8)e(&v1) )
puts("You cracked the system!");
else
puts("Wrong password! Your attempt is over.");
return __readfsqword(0x28u) ^ v2;
}

流程很简单,就是检查输入的字符串是否为flag,检查字符串的有6个函数,分别如下:

c
1
2
3
4
5
_BOOL8 __fastcall e(char *a1){
bool v1; // al
v1 = a1[7] == '5' && a1[17] == 'g' && a1[2] == 'A' && b(a1);
return v1 != 0;
}
c
1
2
3
4
5
_BOOL8 __fastcall b(char *a1){
bool v1; // al
v1 = a1[15] == 'i' && a1[9] == 'r' && a1[1] == 'L' && d(a1);
return v1 != 0;
}
c
1
2
3
4
5
_BOOL8 __fastcall d(char *a1){
bool v1; // al
v1 = a1[10] == '3' && a1[18] == '}' && a1[6] == 'a' && f(a1);
return v1 != 0;
}

剩下的三个函数都差不多,就不一一列出了,其中a1就是我们输入的字符串,这些函数做的就是检查字符串中的某个字节是否正确。

解法很简单,只要在相应位置填入对应的字符,即可拼得flag(不用写脚本,打个草稿就行):

re

FLAG{3a5yr3v3r5ing}

PPC

Mind palace I

  • 题目描述:

    It looks like the situation is hopeless, there is no time to think. However, you can use the mind palace and solve all problems instantly.

    Code
    1
    nc 212.47.229.1 33001

    mp1

  • 考察点:摩尔斯电码、socket编程

  • 难度:简单

  • 初始分值:1000

  • 最终分值:802

  • 完成人数:142

nc连接上题目,显示有一个字符串pip,过了一会儿变成了piiiip,过了一会又变回去了,就这样一直跳来跳去……刚开始没意识到,后来经过imagin师傅提醒,可能是摩尔斯电码,于是dump出数据,将pip视作.(dot),将piiiip视作-(dash),得到摩尔斯电码:

…. . .-. . ..- .–. — -. - …. . .-.. .- .–. . .-.. — ..-. – -.– -.-. — .- - -.– — ..- – .- -.– … . . - …. . .-. .. -… -… — -. — ..-. – -.– -.. . -.-. — .-. .- - .. — -. -… ..- - - …. . – . -.. .- .-.. .. - … . .-.. ..-. .. -.- . . .–. .. -. .- .-.. . .- - …. . .-. -. .–. — ..- -.-. …. .- - …. — – . ..-. .-.. .- –. … …. . .-. .-.. — -.-. -.- .-.. .. -.- . … -.– — ..- .-. – — .-. … .

解密后得到字符串:

HERE UPON THE LAPEL OF MY COAT YOU MAY SEE THE RIBBON OF MY DECORATION BUT THE MEDAL ITSELF I KEEP IN A LEATHERN POUCH AT HOME FLAG SHERLOCK LIKES YOUR MORSE

刚开始直接扔到google翻译里,愣是没找到Flag在哪儿,后来仔细看了下,倒数5个单词开始就是FLAG

FLAG{SHERLOCK_LIKES_YOUR_MORSE}

dump数据的脚本如下:

python
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
#!/usr/bin/python
#coding=utf-8
#__author__:TaQini

from pwn import *

p = remote('212.47.229.1', 33001)

# context.log_level = 'debug'

se = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim, data)
sea = lambda delim,data :p.sendafter(delim, data)
rc = lambda numb=4096 :p.recv(numb)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info_addr = lambda tag, addr :p.info(tag + ': {:#x}'.format(addr))

l = []
def solve(ans='-1'):
data = ru('\r')
print data
l.append(data)

for i in range(1200):
solve()

print l

# dump morse code:
# HERE UPON THE LAPEL OF MY COAT YOU MAY SEE THE RIBBON OF MY DECORATION BUT THE MEDAL ITSELF I KEEP IN A LEATHERN POUCH AT HOME FLAG SHERLOCK LIKES YOUR MORSE

# FLAG{SHERLOCK_LIKES_YOUR_MORSE}

p.interactive()

Mind palace II

  • 题目描述:

    It’s time to strain your brains.

    Code
    1
    nc 212.47.229.1 33002

    mp2

  • 考察点:ROT13、socket编程

  • 难度:简单

  • 初始分值:1000

  • 最终分值:890

  • 完成人数:106

nc连接上题目后,显示如下内容,分析下不难看出message为密文,将其rot13解密之后的结果输入answer中,就会出现下一个密文

shell
1
2
3
4
5
6
7
8
9
$ nc 212.47.229.1 33002
===============================================
Telegrams come very quickly
Help Sherlock Holmes decipher all messages
===============================================
Message: CERHAVBAF
Answer: PREUNIONS
Message: FGHZCREF
Answer:

解密100轮之后就会给flag,脚本如下:

python
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
#!/usr/bin/python
#coding=utf-8
#__author__:TaQini

from pwn import *

p = remote('212.47.229.1', 33002)

context.log_level = 'debug'

se = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim, data)
sea = lambda delim,data :p.sendafter(delim, data)
rc = lambda numb=4096 :p.recv(numb)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info_addr = lambda tag, addr :p.info(tag + ': {:#x}'.format(addr))

def solve(ans='-1'):
ru('Message: ')
data = ru('\n')
ru('Answer: ')
print data
data = data.decode('rot13')
print data
if(ans!='-1'):
sl(ans)
else:
sl(str(data))
i = 0
while True:
solve()
print i
i+=1

# find flag after 100 times
# FLAG{Y0U_V3RY_F45T3R_CRYPT0GR4PH}

p.interactive()

Mind palace III

  • 题目描述:

    100% of brain CPU

    Code
    1
    nc 212.47.229.1 33003

    mp3

  • 考察点:逻辑运算、socket编程

  • 难度:简单

  • 初始分值:1000

  • 最终分值:896

  • 完成人数:103

nc连接上题目后,显示如下内容,分析下不难看出是要输入逻辑运算后的结果,结果正确就会出现下一个运算式:

shell
1
2
3
4
5
6
7
8
$ nc 212.47.229.1 33003
===============================================
Let's see how quickly you can solve these examples
===============================================
[>] 41 OR 103
[>] Result: 111
[>] 49 XOR 80
[>] Result:

算对100次之后就会给flag,脚本如下:

python
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
#!/usr/bin/python
#coding=utf-8
#__author__:TaQini

from pwn import *

p = remote('212.47.229.1', 33003)

context.log_level = 'debug'

se = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim, data)
sea = lambda delim,data :p.sendafter(delim, data)
rc = lambda numb=4096 :p.recv(numb)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info_addr = lambda tag, addr :p.info(tag + ': {:#x}'.format(addr))

op = {'XOR':'^', 'OR':'|', 'AND':'&'}
def solve(ans='-1'):
ru('[>]')
data = ru('\n')
ru('[>]')
print data
data = data.split()
res = eval(data[0]+op[data[1]]+data[2])
if(ans!='-1'):
sl(ans)
else:
sl(str(res))

while True:
solve()

# find flag after 100 times
# FLAG{0HH_Y0UR3_4_V3RY_5M3RT_M4TH3M4T1C}

p.interactive()

Misc

Deep dive

  • 题目描述:

    Worth digging into these tricks.

    dd

  • 考察点:批处理脚本

  • 难度:简单

  • 初始分值:1000

  • 最终分值:701

  • 完成人数:174

题目给了附件flag.txt,用file指令识别下,发现它实际上是个压缩包

shell
1
2
$ file flag.txt
flag.txt: POSIX tar archive (GNU)

经过解压后还是个压缩包,但是换了一种压缩方式:

shell
1
2
3
4
5
$ tar xvf flag.txt
./
./flag.txt
$ file flag.txt
flag.txt: Zip archive data, at least v2.0 to extract

至此大概明白这题要考察的就是自动解压缩包,不同压缩类型的压缩包需要不同的指令来解压,所以此题关键在于正确识别文件类型。python有个filetype库可以实现文件类型识别。

根据压缩包类型解压,大概解压700多次就有flag了(膜Y1ng师傅手动解压300余次)脚本如下:

python
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
#!/usr/bin/python
#__author__:TaQini

from os import system
import filetype
i = 0
while True:
kind = filetype.guess('./flag.txt')
if not kind:
print "right! flag is:"
system("cat ./flag.txt")
break
elif kind.extension == 'xz':
system('mv ./flag.txt ./flag.xz')
system('xz -d ./flag.xz')
system('mv ./flag ./flag.txt')
elif kind.extension == 'gz':
system('mv ./flag.txt ./flag.gz')
system('gzip -d ./flag.gz')
system('mv ./flag ./flag.txt')
elif kind.extension == 'tar':
system('tar xvf ./flag.txt')
elif kind.extension == 'zip':
system('mv ./flag.txt ./flag.zip')
system('unzip ./flag.zip')
system('rm ./flag.zip')
elif kind.extension == 'bz2':
system('bzip2 -d flag.txt')
system('mv ./flag.txt.out ./flag.txt')
i += 1
print "\n times %d"%i
# FLAG{matri0sha256}

True Detective

  • 题目描述:

    And now it’s time to show the skills of a real detective!

    https://clck.ru/MCop6

    td

  • 考察点:信息搜索、源码分析

  • 难度:简单

  • 初始分值:2000

  • 最终分值:1681

  • 完成人数:124

题目描述给的链接是个google文档,打开之后这样:

doc

要求回答5个关于伦敦的问题,天真的我以为这题是要考搜索能力,于是google了这个图片(图片店名被挡住了),发现这家店全名叫做Testo,输入Testo给了flag的第一部分

right

后来越往后做越难,什么根据图片找出地名、图片中的是哪国大使馆、这是什么公园之类的…这谁知道呀

于是审查了一下网页元素,搜索FLAG{08发现flag其实就在源码中……而且是通过js判断答案的:

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
var FB_PUBLIC_LOAD_DATA_ = [null,["Let's see how well you know London.",
[[673760842,"What is the name of the store?",null,0,[[255559616,null,0,null,
[[4,300,["(tesco|Testo)"] ,"1 - FLAG{08"] ] ] ] ,null,null,null,null,[["1cTysniECWio21dKH90wnnzNxlB4gKBJI7Bri1Q_K4moAtg",null,[740,385,0] ] ] ] ,
[2014750817,"What is the name of this place?",null,0,[[1092335700,null,0,null,
[[4,300,["(bridport|Bridport)"] ,"2 - c49c3d9a"] ] ] ] ,null,null,null,null,[["1sd8oiCWcjd1_HiCrOA2f1hrgkknzJvT_Y-tVgx5qjBanKw",null,[740,417,0] ] ] ] ,
[771036932,"Very beautiful Park where Sherlock likes to walk. Where is it?",null,0,[[1600364512,null,0,null,
[[4,300,["(finsbury|Finsbury)"] ,"3 - e8898343"] ] ] ] ,null,null,null,null,[["1-w_MvKBaer5I78ICXo70E94lH4vKSPmCRekszxbOblJRvA",null,[740,377,0] ] ] ] ,
[302390155,"Every Englishman has been to this square at least once",null,0,[[661956933,null,0,null,
[[4,300,["(euston|Euston)"] ,"4 - 7729747b"] ] ] ] ,null,null,null,null,[["1sGu1uvZD9tXdbS0ypGTsI05LDj8Bd1U03VV_vjDLI3bY6A",null,[740,385,0] ] ] ] ,
[1070034509,"Which Embassy building is shown in the photo",null,0,[[2072641709,null,0,null,
[[4,300,["(hungary|Hungary)"] ,"5 - cf1be8}"] ] ] ] ,null,null,null,null,[["174eoWKRoyVKEN21KJigFwwry_DncqoZfVECN_p6i85oWRw",null,[740,376,0] ] ] ] ]
,null,null,null,[0,0] ,null,null,"Task",48,[null,null,null,null,0] ,null,null,null,null,[2] ]
,"/forms","Новая форма",null,null,null,"",null,0,0,"","",0,"e/1FAIpQLSdpESvbfK_dafCvhkTjcLK1KBMwklUgYcy-J0mu3g_jjgisRw",0,"[]",0];

flag有5部分,拼全就是答案:

1 - FLAG{08
2 - c49c3d9a
3 - e8898343
4 - 7729747b
5 - cf1be8}

FLAG{08c49c3d9ae88983437729747bcf1be8}

end

国际小比赛,题型和国内CTF有所不同,挺好玩儿的,以后有时间还玩儿~

文章作者: TaQini
文章链接: http://taqini.space/2020/02/16/sarctf-writeup/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 TaQini
打赏
  • Wechat
    Wechat
  • Alipay
    Alipay

评论