# 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.
** 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.