Case 06 → Something fishy 🎣

Background: Kuanda has been recruiting cyber-crime specialists and every new member has to spend a week at the National Gallery of Art.

Mission: If you can decode the instructions, you might just have a shot at infiltrating their system and finding out what they’re really up to.

For all the marbles: Who is the leader of Kuanda.org?


It’s Sherlock Holmes up in this.

We receive a decoded text that new recruiters receive:

12204/497 62295/24 50883/678 47108/107 193867/3,
45534/141 hidden 100922/183 143461/1 1181/505 46187/380.
41526/155 66447/199 30241/114, 33745/154 12145/387 46437/398 177191/131:
293/64 41629/1506 210038/432, 41612/803 216839/1.

404/258 rules 40/186 1472/222 122894/2 46081/105:
41594/650 32579/439 44625/141 184121/19 33254/348 357/273 32589/821,
46171/687 punctuations 62420/10 50509/48 1447/128,
176565/82'56721/591 561/225 insensitive, 30744/129 76197/32.

1319/42 41599/216 68/457 136016/146, 42420/126'46198/389 42429/158 40091/108 41667/252,
1515/555 177593/223 176924/73 45889/65 159836/96 35080/384 32578/199.
1607/167 124996/9 71/56, 1303/187 45640/1114 72328/247 75802/11,
1168/146 163380/12 57541/116 206122/738 365/267 46026/211 46127/19.

119295/425 45062/128 12198/133 163917/238 45092/8 54183/4 42453/82:
561/433 9/387 37004/287 1493/118 41676/38 163917/238 3159/118 63264/687
1/905 1493/109 43723/252, 136355/1 1159/134 40062/172 32588/604,
158574/1 45411/8 10/892 127587/175 - 633/9 72328/247 1514/615 42940/138.

164958/84 221014/479 151526/7 111124/138, 41668/206 34109/46 1514/555,
147789/2 3228/152 993/323 166477/167 178042/167, 50753/91'207786/8 12/372.
1108/158'42423/150 12/309 66154/9 213566/11 44981/158 1197/300
40184/149 92994/63-71071/179 75093/7 211718/18 74211/5 46144/399.

We also know that new recruiters spend time at the National Gallery of art.

There is probably clues in the paintings.

Let’s inspect the digital repository structure!

NationalGalleryArt
| take 5

The key seems to be, the nth word from the provenance text of the xth object where x/n.

Let’s create a search index of objectId to word.

NationalGalleryArt
| project ObjectId, word = extract_all(@'(\w+)', ProvenanceText)
| mv-expand with_itemindex=index word
| extend ObjectId = strcat(tostring(ObjectId), '/', index)
| project-away index
| take 5

Untitled

We store the code to a datatable and extact the code words

Code 
| extend codeword = extract_all(@'(\d+/\d+)', code)
| mv-expand codeword
| project ObjectId = tostring(codeword)

We then decode the codewords

Code 
| extend codeword = extract_all(@'(\d+/\d+)', code)
| mv-expand codeword
| project ObjectId = tostring(codeword)
| join kind=inner(NationalGalleryArt
    | project ObjectId, word = extract_all(@'(?m)(\w+)', ProvenanceText)
    | mv-expand with_itemindex=index word
    | extend ObjectId = strcat(ObjectId, '/', index)
    | project-away index)
    on ObjectId
| project ObjectId, word

Now we need to replace the codes with the decoded words

Code 
| extend ObjectId = extract_all(@'(\d+/\d+)', code)
| mv-expand ObjectId to typeof(string)
| join kind=inner(NationalGalleryArt
    | project ObjectId, word = extract_all(@'(?m)(\w+)', ProvenanceText)
    | mv-expand with_itemindex=index word
    | extend ObjectId = strcat(ObjectId, '/', index)
    | project-away index)
    on ObjectId
| project ObjectId, word, code
| summarize Object_Id = make_list(ObjectId), word = make_list(word) by code
| project code = replace_strings(code, Object_Id, word)

in catalogue of titles Grand, three hidden words Demand your Hand. when found all, they form A line: A clear timeline, simply Fine.

words rules are simple to Review: at least three Letters have in view, all punctuations Mark the End, they’re case insensitive, my friend.

to find all words, you’ll need some skill, seeking the popular will guide you still. below The King, the first word mounts, the Second shares with Third their counts.

reveal the last word with Wise thought: take first two letters from word most sought into marked dozen, and change just one, and with those two - the word is done.

so search the titles, high and low, and when you find it, you’ll know. you’ve picked the Image that revealed the pass-code to the World concealed.

We need to crack what this means:

  • We are looking for three words.
  • They are case insensitive
  • The first word is below the King
  • The second word shares the same count with the third
  • For the third word, first two letters from the most popular word

We do a word count of the titles

NationalGalleryArt
| extend found = extract_all(@'(\w{3,})', Title)
| mv-expand found to typeof(string)
| summarize count() by tolower(found)
| order by count_ desc
| extend rn = row_number()

The first word:

NationalGalleryArt
| extend found = extract_all(@'(\w{3,})', Title)
| mv-expand found to typeof(string)
| summarize count() by tolower(found)
| order by count_ desc
| extend rn = row_number()
| serialize next=next(Column1) 
| where Column1=="king"

Untitled

The second word:

NationalGalleryArt
| extend found = extract_all(@'(\w{3,})', Title)
| mv-expand found to typeof(string)
| summarize count() by tolower(found)
| order by count_ desc
| extend rn = row_number()
| where count_ == '161'

Untitled

The third word:

reveal the last word with Wise thought:
take first two letters from word most sought
into marked dozen, and change just one,
and with those two - the word is done.

The first ranked word == ‘the’ and the twelfth word == ‘man’. When we put them together, we get

MANTH ~ MONTH

Words: day year month

so search the titles, high and low, and when you find it, you’ll know. you’ve picked the Image that revealed the pass-code to the World concealed.

NationalGalleryArt
| where tolower(Title) contains "day" and tolower(Title) contains "month" and tolower(Title) contains "year"

Untitled

Inspecting the scripts within the website. Found LoginPage.tsx.

const {debouncesHintUrl, setHintError} = React.useMemo(() => { 
    const tools=  {
    setHintError: function () {
        setShowError({
          onHint: true,
          errorMessage: "Error: invalid link-hint"
        });
        setValidHintUrl(false);
      },
      debouncesHintUrl: debounce((url: string) => {
        if (!url) {
          return;
        }
        if (!url.match(/^https:\/\/api\.nga\.gov.*default.jpg$/)) {
          tools.setHintError();
          return;
        }
        setHintUrl(url);
      }, 300),

    };
    return tools;
  }, []);

The login hint is the URL to the image!

Untitled

KOTSPUOST

Follow the octopus for the password

Untitled

Case 05 → Devils and details 🪵

Towards OSCP

comments powered by Disqus