Skip to content

Latest commit

 

History

History
403 lines (348 loc) · 11.3 KB

File metadata and controls

403 lines (348 loc) · 11.3 KB

Writeup for tell me a message

@ctf_shiho

# Reversing part:

---
Tue Sep 17 14:37:19 JST 2019 ~/ctf/permanent/akictf/tellmeamessage 100%
> nm -D tellme-39079dcc9a39dfb72bc6f40842bdeac8 | grep -i dump
(snip)
08093bf0 T
> cat x.gdb 
b perl_run
run
call (void)Perl_dump_all()
quit

anent/akictf/tellmeamessage 100%
> cat x.gdb 
b perl_run
run
call (void)Perl_dump_all()
quit
Tue Sep 17 14:43:31 JST 2019 ~/ctf/permanent/akictf/tellmeamessage 100%
> gdb --quiet tellme-39079dcc9a39dfb72bc6f40842bdeac8 -x x.gdb
(snip)
{
65535TYPE = leave  ===> DONE
    TARG = 1
    FLAGS = (VOID,KIDS,PARENS)
    PRIVATE = (REFCOUNTED)
    REFCNT = 1
    {
65535    TYPE = enter  ===> 65535
    }
    {
65535    TYPE = nextstate  ===> 65535
        FLAGS = (VOID)
        LINE = 1
        PACKAGE = "main"
    }
    {
65535    TYPE = sassign  ===> 65535
        FLAGS = (VOID,KIDS,STACKED)
        {
65535        TYPE = chr  ===> 65535
            TARG = 4
            FLAGS = (SCALAR,KIDS)
            {
65535            TYPE = add  ===> 65535
                TARG = 3
                FLAGS = (SCALAR,KIDS)
                {
65535                TYPE = readline  ===> 65535
                    TARG = 2
                    FLAGS = (SCALAR,KIDS)
                    {
65535                    TYPE = gv  ===> 65535
                        FLAGS = (SCALAR)
                    }
                }
                {
65535                TYPE = const  ===> 65535
                    FLAGS = (SCALAR)
                    SV = IV(0)
                }
            }
        }
        {
65535        TYPE = padsv  ===> 65535
            TARG = 1
            FLAGS = (SCALAR,REF,MOD,SPECIAL)
            PRIVATE = (INTRO)
        }
    }
    {
65535    TYPE = nextstate  ===> 65535
        FLAGS = (VOID)
        LINE = 2
        PACKAGE = "main"
    }
    {
65535    TYPE = sassign  ===> 65535
        FLAGS = (VOID,KIDS,STACKED)
        {
65535        TYPE = const  ===> 65535
            FLAGS = (SCALAR)
            SV = PV("obzyuz\215\203\221\177ai"\0)
        }
        {
65535        TYPE = padsv  ===> 65535
            TARG = 5
            FLAGS = (SCALAR,REF,MOD,SPECIAL)
            PRIVATE = (INTRO)
        }
    }
    {
65535    TYPE = nextstate  ===> 65535
        FLAGS = (VOID)
        LINE = 3
        PACKAGE = "main"
    }
    {
65535    TYPE = leaveloop  ===> 65535
        FLAGS = (VOID,KIDS)
        {
65535        TYPE = enteriter  ===> 65535
            TARG = 7
            FLAGS = (LIST,KIDS,STACKED)
            {
65535            TYPE = null  ===> 65535
                  (was pushmark)
                FLAGS = (SCALAR)
            }
            {
65535            TYPE = null  ===> 65535
                  (was list)
                FLAGS = (LIST,KIDS)
                {
65535                TYPE = pushmark  ===> 65535
                    FLAGS = (SCALAR)
                }
                {
65535                TYPE = const  ===> 65535
                    FLAGS = (SCALAR)
                    SV = IV(0)
                }
                {
65535                TYPE = subtract  ===> 65535
                    TARG = 9
                    FLAGS = (SCALAR,KIDS)
                    {
65535                    TYPE = length  ===> 65535
                        TARG = 8
                        FLAGS = (SCALAR,KIDS)
                        {
65535                        TYPE = padsv  ===> 65535
                            TARG = 5
                            FLAGS = (SCALAR)
                        }
                    }
                    {
65535                    TYPE = const  ===> 65535
                        FLAGS = (SCALAR)
                        SV = IV(1)
                    }
                }
            }
        }
        {
65535        TYPE = null  ===> 65535
            FLAGS = (VOID,KIDS)
            {
65535            TYPE = and  ===> 65535
                FLAGS = (VOID,KIDS)
                OTHER ===> 65535
                {
65535                TYPE = iter  ===> 65535
                    FLAGS = (SCALAR)
                }
                {
65535                TYPE = lineseq  ===> 65535
                    FLAGS = (VOID,KIDS)
                    {
65535                    TYPE = nextstate  ===> 65535
                        FLAGS = (VOID)
                        LINE = 4
                        PACKAGE = "main"
                    }
                    {
65535                    TYPE = print  ===> 65535
                        FLAGS = (VOID,KIDS)
                        {
65535                        TYPE = pushmark  ===> 65535
                            FLAGS = (SCALAR)
                        }
                        {
65535                        TYPE = ord  ===> 65535
                            TARG = 14
                            FLAGS = (SCALAR,KIDS)
                            {
65535                            TYPE = bit_xor  ===> 65535
                                TARG = 13
                                FLAGS = (SCALAR,KIDS)
                                {
65535                                TYPE = substr  ===> 65535
                                    TARG = 12
                                    FLAGS = (SCALAR,KIDS)
                                    {
65535                                    TYPE = null  ===> 65535
                                          (was pushmark)
                                        FLAGS = (SCALAR)
                                    }
                                    {
65535                                    TYPE = padsv  ===> 65535
                                        TARG = 5
                                        FLAGS = (SCALAR)
                                    }
                                    {
65535                                    TYPE = padsv  ===> 65535
                                        TARG = 7
                                        FLAGS = (SCALAR)
                                    }
                                    {
65535                                    TYPE = const  ===> 65535
                                        FLAGS = (SCALAR)
                                        SV = IV(1)
                                    }
                                }
                                {
65535                                TYPE = padsv  ===> 65535
                                    TARG = 1
                                    FLAGS = (SCALAR)
                                }
                            }
                        }
                    }
                    {
65535                    TYPE = unstack  ===> 65535
                        FLAGS = (VOID)
                    }
                }
            }
        }
    }
    {
65535    TYPE = nextstate  ===> 65535
        FLAGS = (VOID)
        LINE = 6
        PACKAGE = "main"
    }
    {
65535    TYPE = print  ===> 65535
        FLAGS = (VOID,KIDS)
        {
65535        TYPE = pushmark  ===> 65535
            FLAGS = (SCALAR)
        }
        {
65535        TYPE = const  ===> 65535
            FLAGS = (SCALAR)
            SV = PV("\n"\0)
        }
    }
}

SUB utf8::unicode_to_native = (xsub 0x80fd6f0 0)

SUB utf8::encode = (xsub 0x80fdaa0 0)

SUB utf8::valid = (xsub 0x80fdb10 0)

SUB utf8::native_to_unicode = (xsub 0x80fd7a0 0)

SUB utf8::decode = (xsub 0x80fda10 0)

SUB utf8::downgrade = (xsub 0x80fd850 0)

SUB utf8::upgrade = (xsub 0x80fd930 0)

SUB utf8::is_utf8 = (xsub 0x80fc990 0)

SUB DynaLoader::dl_error = (xsub 0x81120f0 0)

SUB DynaLoader::dl_undef_symbols = (xsub 0x8111db0 0)

SUB DynaLoader::dl_install_xsub = (xsub 0x81121c0 0)

SUB DynaLoader::dl_find_symbol = (xsub 0x81123b0 0)

SUB DynaLoader::dl_load_file = (xsub 0x8112600 0)

SUB DynaLoader::boot_DynaLoader = (xsub 0x8111e10 0)

SUB DynaLoader::dl_unload_file = (xsub 0x81124e0 0)

SUB attributes::bootstrap = (xsub 0x80ff290 0)

SUB Regexp::DESTROY = (xsub 0x80fc8e0 0)

SUB UNIVERSAL::isa = (xsub 0x80fe9b0 0)

SUB UNIVERSAL::VERSION = (xsub 0x80fdbf0 0)

SUB UNIVERSAL::can = (xsub 0x80fe050 0)

SUB PerlIO::get_layers = (xsub 0x80fcc50 0)

SUB PerlIO::Layer::NoWarnings = (xsub 0x8102790 0)

SUB PerlIO::Layer::find = (xsub 0x8102c70 0)

SUB Internals::SvREFCNT = (xsub 0x80fd620 0)

SUB Internals::hv_clear_placeholders = (xsub 0x80fd5b0 0)

SUB Internals::hash_seed = (xsub 0x80fca70 0)

SUB Internals::SvREADONLY = (xsub 0x80fcad0 0)

SUB Internals::HvREHASH = (xsub 0x80fc8f0 0)

SUB Internals::rehash_seed = (xsub 0x80fca10 0)

(snip)

---

As above results, we know the given binary is equivalent to below code:

```perl
$x = chr(0 + <STDIN>);
$y = "obzyuz\215\203\221\177ai";
for ($i = 0; $i < length($y); $i++) {
  print ord(substr($y, $i, 1) ^ $x);
}
print "\n";
```

# Guessing part

I changed the code to print raw text

```perl
$x = chr(0 + <STDIN>);
$y = "obzyuz\215\203\221\177ai";
for ($i = 0; $i < length($y); $i++) {
  print (substr($y, $i, 1) ^ $x);
}
print "\n";
```

... and brute-forced for $x. after some times, I was interested to the result, when tried `$x = -1`. so I try $x = -1, 255, 65535, 4294967295. 

Tue Sep 17 14:53:44 JST 2019 ~/ctf/permanent/akictf/tellmeamessage 100%
> for x in -1 255 65535 4294967295; do echo $x | perl tellme.pl 2>/dev/null; done
メ゚ヌトネヌーセャツワヤ
������r|n���
ミンナニハナイショダヨ
������������������������������������������������������������������������������������

I've seen the flag. 

@bata_24

** This write-up is before fix the bug, maybe. **

Input 0 and 1, the response is different a bit.

root@Ubuntu64:~/ctf/akictf/30# ./39079dcc9a39dfb72bc6f40842bdeac8
0
1119812212111712214113114512797105 -> 111, 98, 122, 121, 117, ...
root@Ubuntu64:~/ctf/akictf/30# ./39079dcc9a39dfb72bc6f40842bdeac8
1
1109912312011612314013014412696104 -> 110, 99, 123, 120, 116, ...
root@Ubuntu64:~/ctf/akictf/30#

Only LSB is toggled. maybe this is XOR-cipher. Let's brute-force with assumption that xor-key is 1byte.

root@Ubuntu64:~/ctf/akictf/30# cat test.py
import sys
lists = [111,98,122,121,117,122,141,131,145,127,97,105]
for i in xrange(256):
  print i, ":",
  for j in lists:
    sys.stdout.write(chr((j^i)%256))
  print
root@Ubuntu64:~/ctf/akictf/30# py test.py
...
190 :ムワトヌヒト3=/チ゚ラ
191 :ミンナニハナ2<.ダヨ
192 :ッ「コケオコMCQソ。ゥ
...

191 is very suspicious, but something is wrong.

Remember first response, you will notice that only 3bytes are bigger than 0x7f(=127), and those were broken.

Therefore, you should toggle MSB.

root@Ubuntu64:~/ctf/akictf/30# py
>>> [arr^0b10000000 for arr in [141,131,145]]
[13, 3, 17]
>>>

root@Ubuntu64:~/ctf/akictf/30# cat test.py
import sys
#lists = [111,98,122,121,117,122,141,131,145,127,97,105]
lists = [111,98,122,121,117,122,13,3,17,127,97,105]
#for i in xrange(256):
for i in xrange(191,192):
  print i, ":",
  for j in lists:
    sys.stdout.write(chr((j^i)%256))
  print
root@Ubuntu64:~/ctf/akictf/30# py test.py
191 :ミンナニハナイショダヨ

OK, you got the true flag.