+++ author = "Maik de Kruif" title = "Twisted robot" subtitle = "Beginners Quest 5 - Google CTF" date = 2021-09-24T19:40:00+01:00 description = "A writeup for challenge 5 of the beginners quests of the Google CTF." cover = "img/writeups/google-ctf/2021/beginners-quest/5/cover.png" tags = [ "Google CTF", "Beginners Quest", "ctf", "hacking", "writeup", "misc", ] categories = [ "ctf", "writeups", "hacking", "misc", ] +++ ## Story line ### Istanbul - Bazaar It’s a hot day, and your skin is cracking and dry. It’s difficult to make your way through the crowded bazaar. A high pitch voice pierces through the soundscape from a salesman that’s trying to sell colorful fabrics and then from another corner comes delicious smells. You spot a hand waving - it’s your contact that you’ve been waiting to meet. "Take a seat, my friend, I’m Gökhan, have you been to Istanbul before? No, really? I’m sure that you will have a great time, I’ve ordered tea for the two of us. Show me the amulet, will you?. Wow, this is really something from my younger days, this is as mysterious as it is beautiful and belongs to “The cloaked brotherhood”. They are very dangerous, and eventhough your quest is urgent, I would advise you to not continue looking for the owner of this. Go home, and forget about it." In the blink of an eye, four tough guys show up, and you start to run together with Gökhan through the crowded marketplace and then up on a rooftop. The tough guys are closing in, but the two of you climb down from the rooftop, run around a corner and are able to hide in two crates. #### Challenge: Twisted robot (misc) We found this old robo caller. It basically generates random phone numbers to spam. We found the last list of numbers in generated and also some weird file... Maybe it's got to do with these new beta features they were testing? ### After solving Gökhan is pointing at a parked vehicle. He tells you that you will have to try and reach it and that if you stay where you are, that you will get captured sooner or later. The guards know the neighborhood like their own backpocket. At first you doubt the plan, it seems like a very risky option. Gökhan then finally tells you he's not going to stay there, and his last offer is for you to go with him. #### Stay ([7]({{< ref "7.md" >}})) Gökhan exits the crate, and makes a quick sprint for the car. The tough guys spot him, and they approach. As he enters the car he tries to start it, and the car makes an ominous sound, as the bad guys are closing in. He looks back through the rear window, and sees that the bad guys are about to jump on the back of the car, and they are pulling out guns. He tries to start the car furiously one more time and... IT WORKS! Gökhan disappears off in the distance. You overhear the tough guys when they are talking about a person, “Mesut”, that got classified information. You quickly send a message to the boss to look up the person. After a short wait you receive a response that he is currently on his private yacht in Croatia. Looks like it is time for some travel again. #### Come with Gökhan ([8]({{< ref "8.md" >}})) As you and Gökhan are leaving the crates to enter a car, you spot the tough guys coming after you, and they are pulling out weapons. Gökhan starts the car and the two of you take off. After a decent distance outside of the city, he gives you an invitation to a private conference that will take place in Buenos Aires. ## Attachment [attachment.zip](/files/writeups/google-ctf/2021/beginners-quest/5/attachment.zip) {{< code language="py" title="RoboCaller1337.py" isCollapsed="true" >}} ```py import random # Gots to get that formatting right when send it to our call center def formatNumber(n): n = str(n) return f'{n[:3]}-{n[3:6]}-{n[6:]}' # This generates random phone numbers because it's easy to find a lot of people! # Our number generator is not great so we had to hack it a bit to make sure we can # reach folks in Philly (area code 215) def generateRandomNumbers(): arr = [] for i in range(624): arr.append(formatNumber(random.getrandbits(32) + (1<<31))) return arr def encodeSecret(s): key = [random.getrandbits(8) for i in range(len(s))] return bytes([a^b for a,b in zip(key,list(s.encode()))]) def menu(): print("""\n\nWelcome to the RoboCaller!! What would you like to do? 1: generate a new list of numbers 2: encrypt a super secret (in beta) 3: decrypt a super secret (coming soon!!) 4: exit""") choice = '' while choice not in ['1','2','3']: choice = input('>') if choice == '1': open('robo_numbers_list.txt','w').write('\n'.join(generateRandomNumbers())) print("...done! list saved under 'robo_numbers_list.txt'") elif choice == '2': secret = input('give me your secret and I\'ll save it as "secret.enc"') open('secret.enc','wb').write(encodeSecret(secret)) elif choice == '3': print("stay tuned for this awesome feature\n\n") elif choice == '4': print("Thank you for using RoboCaller1337!") return def main(): while True: menu() if __name__ == "__main__": main() ``` {{< /code >}} {{< code language="txt" title="robo_numbers_list.txt" isCollapsed="true" >}} ```txt 263-170-6234 467-553-7030 220-146-1293 630-328-6023 413-553-0465 528-403-6609 454-641-6157 396-906-1900 445-477-6643 578-095-2052 216-516-7520 314-161-3710 628-223-8174 512-530-6992 464-456-5861 631-453-4232 377-004-3494 328-898-2557 231-249-9423 420-346-3494 605-091-2725 595-329-3910 576-809-4557 425-030-9549 389-181-5710 621-627-6043 423-199-4297 579-089-8585 589-493-0846 375-597-0939 541-648-2941 453-069-7058 543-829-0828 417-111-8475 348-244-2759 290-882-6713 522-462-5631 296-565-4379 586-916-6837 603-365-6384 476-088-1715 526-794-4364 570-480-9107 427-082-3513 418-582-5172 294-148-5624 591-766-9391 581-588-1423 554-956-1539 339-448-0163 633-317-6710 529-345-6802 510-151-9942 589-325-3637 291-288-6435 536-342-5711 431-379-8656 306-181-2272 287-750-2264 435-289-4194 609-844-8168 254-346-9938 477-230-3596 224-779-5283 351-591-9900 472-433-7441 259-370-4161 390-390-2128 271-570-0282 532-522-3403 231-987-9206 273-558-2616 232-775-4473 286-546-5820 567-085-6134 303-874-3098 517-707-7333 439-636-1845 641-978-4477 221-606-7704 356-456-0141 621-732-2415 569-522-9393 404-995-4514 573-986-7745 407-677-1104 225-688-0071 219-031-4274 355-266-3258 624-119-4589 313-157-7824 518-033-0420 462-462-1679 435-580-6776 232-015-6685 585-746-5975 359-937-2568 426-271-0216 618-678-9397 318-533-9973 560-054-9472 251-899-2041 295-475-7765 590-304-8246 535-896-4676 538-266-6918 282-578-1932 621-085-1982 471-750-3026 605-061-1357 491-478-9362 531-518-2579 542-766-2906 391-955-0814 271-424-2279 429-855-1832 598-055-6110 429-626-4468 559-114-4811 582-184-7627 499-756-4897 412-170-2198 551-289-1076 397-901-9532 367-175-9646 418-401-3012 223-706-1395 556-314-7884 427-512-9355 441-717-0237 586-758-7240 639-239-7961 563-296-1195 532-034-4947 493-797-3707 240-611-7275 286-614-0798 421-788-3182 292-386-6585 216-386-1373 594-193-2268 337-029-6841 444-662-2067 375-664-3202 293-053-1463 284-235-3914 453-792-3489 266-783-6052 336-422-4671 460-035-3225 470-633-3867 234-048-5223 479-812-5684 606-457-0299 604-025-5219 584-232-4973 534-831-8849 488-941-7239 569-682-8387 250-288-5751 548-842-8852 537-471-2881 473-732-5683 600-901-1360 244-545-5850 611-587-7286 493-004-5626 541-097-0083 318-276-8582 245-121-2701 253-657-5692 587-739-7213 346-259-4605 358-583-6937 636-360-3508 335-700-9223 443-401-2276 580-846-2364 414-725-9375 528-421-5892 606-581-0093 549-745-9361 286-689-9360 218-754-0615 321-168-4565 392-771-7530 292-211-8722 338-038-3332 583-603-7610 472-413-9015 510-699-6253 327-105-5061 347-747-7710 532-690-4353 307-141-9393 614-124-9061 431-024-6717 574-101-4075 632-578-6542 277-867-6340 324-715-7328 374-913-2900 221-589-8179 229-100-8677 306-006-3850 572-818-6626 477-129-5073 568-463-6658 536-661-1868 307-094-0858 248-972-7972 507-465-6313 592-140-8643 635-756-2115 231-603-0653 310-669-1732 577-741-6941 327-413-3011 484-314-6788 398-283-4866 333-140-1452 372-012-4273 265-303-9517 389-626-2935 227-237-4448 302-214-1402 257-043-3569 339-178-6072 467-085-9034 370-830-3049 527-417-1646 360-260-6692 418-021-9682 224-191-9935 475-252-8920 258-028-1912 485-558-4912 475-641-7490 312-575-1076 221-080-0996 565-758-4057 606-410-6813 380-364-3878 454-647-2580 558-276-5241 454-930-4133 425-279-0788 634-055-1448 387-308-6704 297-447-2024 325-867-9896 366-669-5395 370-728-9888 515-812-6899 290-897-7319 608-784-7731 306-673-3231 248-002-8127 556-900-1349 558-045-6325 330-120-0416 503-768-1631 315-471-5872 287-925-3595 597-434-5185 500-420-1998 276-255-9286 260-165-4499 634-488-7067 550-656-9222 364-996-1908 393-231-0222 314-836-5961 278-146-7285 258-469-2984 458-789-6127 376-740-8946 244-618-6086 587-168-0361 275-523-6075 605-784-9728 377-514-5609 263-776-1318 609-187-9670 243-602-9787 253-775-4101 408-681-2234 406-675-5201 496-579-4417 566-496-2682 503-553-5948 439-293-2040 383-486-6162 323-283-9234 305-479-8863 478-975-6735 354-724-0291 330-167-6218 237-014-6927 332-972-5118 336-818-8016 232-442-6385 381-560-9510 491-498-2317 491-354-6757 492-988-1457 504-965-5273 623-178-2982 634-591-5132 331-525-1342 404-793-5431 319-217-4107 426-481-1776 586-057-4203 545-939-6860 222-490-9288 265-820-2560 214-953-0167 643-906-2918 240-098-8109 234-229-5525 520-069-2571 333-323-9940 574-581-5631 620-982-0443 376-752-7970 491-787-0757 613-684-5525 440-860-3533 256-223-7638 637-243-1657 216-758-4109 603-205-8094 641-246-9999 444-144-1846 355-714-3959 638-675-0199 377-418-0369 586-516-3786 466-160-7684 585-714-3750 249-234-7101 515-494-7889 595-840-9246 566-590-0137 358-175-7059 597-287-7017 287-942-8287 442-059-3333 575-505-6136 582-311-6644 619-262-5832 641-788-3280 500-425-4419 218-860-8515 584-013-1982 635-304-8233 413-023-9360 479-795-4224 617-013-8823 417-989-2352 599-480-4023 240-440-2193 299-079-3077 486-349-6987 520-519-6531 606-723-6888 604-485-3290 397-591-6728 222-732-4786 579-723-9610 536-385-6396 328-207-1008 312-228-8345 644-212-3015 470-159-3454 224-910-8039 390-956-1685 335-913-5456 347-509-5657 627-631-4607 299-531-9650 460-460-4197 295-431-0008 318-347-7116 361-830-5578 296-014-3473 592-647-0418 255-674-6356 274-042-5312 325-171-2177 477-736-2939 431-571-1160 305-047-9411 630-334-9642 381-695-7832 298-958-0065 625-500-4706 529-536-9523 383-823-4781 414-338-6319 264-259-0104 478-344-9117 377-027-4085 511-706-8104 613-897-8628 473-831-4406 356-775-0560 332-288-4564 352-970-1774 292-376-4341 319-525-3358 312-514-8535 320-070-0911 290-445-6791 498-406-2432 571-079-8429 276-991-8864 481-943-3126 300-932-1931 546-824-1119 246-372-8126 457-455-4498 288-703-2121 564-818-7304 385-921-6819 629-576-4994 445-109-7495 234-199-7440 632-582-4939 502-998-8220 447-225-4830 498-776-9758 512-819-2534 593-249-1838 346-730-7389 387-061-3438 612-634-6490 304-590-7107 336-236-8058 280-109-9842 532-456-4518 494-312-1472 576-075-3393 502-770-3549 314-251-4866 395-081-9884 362-320-4067 550-221-6228 578-292-6373 560-076-7938 376-384-4159 408-610-4527 407-474-3128 504-027-5065 401-434-6766 511-795-6354 244-790-9831 370-882-6561 464-032-5501 335-056-6491 535-523-9560 563-151-5751 310-650-9154 293-427-5198 227-854-7364 298-835-7781 273-952-9012 372-909-4330 598-402-8660 243-015-8194 383-775-3972 580-873-1801 603-389-4616 435-894-4631 221-659-0436 421-068-3372 576-550-9159 600-740-4753 304-667-9863 398-463-0613 228-119-7649 632-929-1125 418-318-7960 481-314-3005 220-193-6628 376-247-2252 230-189-8583 443-754-1310 307-629-5088 443-234-5273 604-417-4882 371-452-6491 244-192-9948 436-547-5170 255-052-6193 589-472-9545 422-443-9210 471-193-0096 326-900-8982 534-113-4669 370-370-7079 236-477-6842 582-225-8431 330-375-2592 258-253-0724 352-635-3974 277-093-0733 276-827-6629 399-408-4024 299-332-2510 369-955-9431 270-411-8250 505-556-4268 509-193-1267 390-556-9212 545-455-8494 621-160-7841 400-314-8126 301-366-4666 566-601-5258 497-181-3783 475-458-5134 231-329-9853 643-929-0930 467-709-3820 476-757-4475 220-068-1085 306-235-7886 600-225-3007 463-008-1308 542-224-9895 490-906-7623 439-771-8632 528-612-0493 527-246-8898 358-761-7567 555-591-5964 340-723-1623 616-706-2286 479-042-1523 567-628-3190 237-335-5616 342-661-9978 511-003-2993 365-015-3536 579-912-9244 277-699-2447 572-716-1892 432-103-7130 500-710-9000 244-105-1867 395-361-9492 531-841-0316 576-664-6128 363-937-1524 570-451-8880 407-256-2659 550-243-2375 629-676-6662 238-241-4419 595-426-7736 605-009-1897 268-368-8879 276-606-9527 351-839-4116 479-653-9492 549-268-4096 223-918-1181 311-654-3871 464-091-8325 507-686-1330 326-205-4956 438-871-2036 611-564-1201 324-442-1210 547-150-7680 237-378-9286 365-038-6522 262-981-4774 414-149-0176 220-121-1826 423-447-3437 487-112-2749 224-428-8478 251-934-9033 274-700-5893 469-421-0585 344-241-4166 401-960-8975 261-506-6354 589-256-3123 305-932-3116 418-063-9114 600-969-4231 363-050-1450 627-535-7555 487-543-9495 461-161-1043 512-384-1050 234-199-2812 541-513-3632 630-049-9049 585-881-3200 460-978-5106 635-887-0620 298-611-3587 272-932-0243 554-772-3962 618-711-7118 426-926-4284 596-851-6696 306-766-1867 445-639-1594 467-786-0153 515-688-5843 291-664-2547 295-859-0241 605-833-5133 476-067-3223 356-715-8717 625-145-6351 439-027-8936 446-996-9104 ``` {{< /code >}} ## Recon The attachment contains tree files: `RoboCaller1337.py`, `secret.enc` and `robo_numbers_list.txt`. Looking at the python script, we can assume the other two files are generated with it. It contains a function `generateRandomNumbers()`, which generates 624 random phone numbers. It also has a function `encodeSecret()`, which encodes a key with a random number. `robo_numbers_list.txt` looks like a big list with 624 phone numbers. `secret.enc` appears to contain just raw bytes. ## Solving When starting on this challenge I was actually clueless how to solve this. I though the key was random. But then I remembered why you don't use the default random methods. They're not actually random, but rather pseudorandom. Pseudorandom numbers are generated using an algorithm that generates a sequence of numbers whose properties approximate the properties of sequences of random numbers. This sequence is determined by an initial value, called a seed. Although this seed could be actually random, once you know it, you can calculate all the values it would output. From reading [the python documentation of `random.py`](https://github.com/python/cpython/blob/main/Lib/random.py), we can see it uses the Mersenne Twister algorithm with a period of 2^19937-1. Also known as MT19937. When searching for an algorithm to predict its results, I came across [this library](https://github.com/kmyk/mersenne-twister-predictor). It seems that if you know the preceding 624 numbers, you can predict the next numbers. So, let's install the package first: ```sh pip install mersenne-twister-predictor ``` Then, we need a script to read the numbers and enter them in the predictor. Let's start out by creating an instance of the predictor: ```py from mt19937predictor import MT19937Predictor predictor = MT19937Predictor() ``` Then we need the numbers to enter. To get them, I reversed the algorithm in the `RoboCaller1337.py` file: ```py with open("robo_numbers_list.txt", "r") as file: for line in file: number = int(line.replace("-", "")) - (1<<31) predictor.setrandbits(number, 32) ``` Now that the numbers are added, we can read the `secret.enc` file, and try to decode it. Again, I reversed the algorithm in the original file. ```py with open("secret.enc", "rb") as file: secret = list(file.read()) flag= "" key = [predictor.getrandbits(8) for _ in range(len(secret))] for a,b in zip(key, secret): flag += chr(a^b) print(flag) ``` {{< code language="py" title="Full code" isCollapsed="true" >}} ```py from mt19937predictor import MT19937Predictor predictor = MT19937Predictor() with open("robo_numbers_list.txt", "r") as file: for line in file: number = int(line.replace("-", "")) - (1<<31) predictor.setrandbits(number, 32) with open("secret.enc", "rb") as file: secret = list(file.read()) flag= "" key = [predictor.getrandbits(8) for _ in range(len(secret))] for a,b in zip(key, secret): flag += chr(a^b) print(flag) ``` {{< /code >}} ## Solution After executing this code, we get the flag! It's `CTF{n3v3r_3ver_ev3r_use_r4nd0m}`.