The Sleighbell

Cranberry Pi #5
Balcony

Hi, I'm Shinny Upatree.

Hey! Mind giving ole' Shinny Upatree some help? There's a contest I HAVE to win.
As long as no one else wins first, I can just keep trying to win the Sleigh Bell Lotto, but this could take forever!
I'll bet the GNU Debugger can help us. With the PEDA modules installed, it can be prettier. I mean easier.

                                                                                
                              WKOdl:;oW                                         
                          WOo:'.......cW         X0KXW                          
                kdxOX     x...;.....;c.d      Xd;....':d0W                      
               W,....'cd0WN,.,WNd'...d:'N   Xl........',.:W                     
                l........':odoK  No..,0.k Wx';.....'lOWX.'N                     
                O............,oK   O..O;dWl,d'...;xN   x.o         NXKKKKXN     
                W,.....,:ccc:,..;kW k.dcdd,k'..,kW    0'cW    Xko:'.....:odOKW  
                 d........',;clll:,xWlolx'x;..oN    Wx'lW  Ko;..........,cxK    
                 N,..,codxkkkxdl:::;:xKlx,k.'O     O;,O Ko,....;cdk0KXXXXK0kOW 
                  K,.OW           Xkl':k0:o.O   Wk;:kNk:..'cd0N                 
 W0kdlc:::cloxk0XW Wkc;lx0KNWW       NxlKOxd WOl:dK0l''cdOKK0OOOO0KXNW          
  W  NOo'.........,:oxOkkxlc;,',,,,,,:dK;.dKllx0Oo,;d0XKO0KKXKKKK0OO0KXKKN      
  NOxodkO00KKK0OOkdoc:,'.,:ldxxxxxdddolx;;xdlcc::cx;0K0KKXXXXXX00KK00OOO0K      
             WNXK00000KKKK0kxoodl::::ox,.xlK0kdlccdKOOKXXXK000KKKOOOO00000W     
           X0O0000KXX00000KNK;o;...:0 d,,;lNW      0O0XXK0O0KK0OO0KKK000000     
       NXNK000O0KKKKKXKKXK000kl:cdK WXK0000000KKKNW00KK0O0K0OO0KKK00XXXXK0OW    
      WOOOOOO000000OO0KKKKXXOON  WX0OOO0XXXXXXXKOOOKK0O0K0OOOKK0O0XXXXXXK0OW    
       N000000OOOOO0000OO0XXXX0WXOOKXXXXXXXXXXXKKXX0O0XKOO0K0OOKXXXXXXKX0O0     
       KOKXKOO00000OOOO0KK0OOOK0OOX00KX0KKKKKKK00XXXXOOX0KKO0XXXXXXXXXOO0KW     
       0OKXXKKKKKK000K0OOO0KKKKOO0KKKKK0000000KKKKKK00OONO0XKO0NNXKKXXXXN       
       XOO0KXKO0KKKKKOO0K0O0KXK0KXKKKKKKKK000KKKKKKKKK0KKKK0OOONWXK00OKN        
        0OOW WOOKXXXXKKKK0KNOOOOOKKXXKKKKKKKKKKKKXXKK0OOOOKX00OOO0KXNW          
         KOO0NKOKXXXXXXXX0O0KXKKKKKK000000000000000KKKKKKNW                     
          WKOOXNKKKKKKKKK0OKW KO0XXKKKKKKKXXXXXXXXXXXKOON                       
             NXKNNKOOO00XN    W00KK000K000KXXXXXXXXXKK0X                        
                   WW          WKOOO0   KOKKKXXXXXX0OON                         
                                 NKOO0KKNNXKOOOXXOO0XW                          
                                   WNK0OOO0KXXNNXXN                             
                                        WWWWWW                                  
                                                                                
I'll hear the bells on Christmas Day
Their sweet, familiar sound will play
  But just one elf,
  Pulls off the shelf,
The bells to hang on Santa's sleigh!
 
Please call me Shinny Upatree
I write you now, 'cause I would be
  The one who gets -
  Whom Santa lets
The bells to hang on Santa's sleigh!
 
But all us elves do want the job,
Conveying bells through wint'ry mob
  To be the one
  Toy making's done
The bells to hang on Santa's sleigh!
 
To make it fair, the Man devised
A fair and simple compromise.
  A random chance,
  The winner dance!
The bells to hang on Santa's sleigh!
 
Now here I need your hacker skill.
To be the one would be a thrill!
  Please do your best,
  And rig this test
The bells to hang on Santa's sleigh!
 
Complete this challenge by winning the sleighbell lottery for Shinny Upatree.
Using gdb to Call Random Functions! hint from Shinny Upatree
Using gdb to Call Random Functions!

This challenge can be solved with at least 3 different methods. Based on given hint, intended method is to call a function from gdb. Other methods (described in details section below) are either hooking shared library by LD_PRELOAD or reverse-engineering HMAC key from binary and manually creating the hash.

Going further with intended method, there are several approaches to retrieve a list of functions (in .text segment) of ELF binary.

Function to win a challenge is called winnerwinner. To call it, execution of program must be paused by running it via gdb - gdb sleighbell-lotto, setting a breakpoint on main function - b main, resuming execution - run - and jumping to relevant function - jump winnerwinner.
                                                     .....          ......      
                                     ..,;:::::cccodkkkkkkkkkxdc;.   .......     
                             .';:codkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx.........    
                         ':okkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx..........   
                     .;okkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdc..........   
                  .:xkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkko;.     ........   
                'lkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx:.          ......    
              ;xkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkd'                       
            .xkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx'                         
           .kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx'                           
           xkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx;                             
          :olodxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk;                               
       ..........;;;;coxkkkkkkkkkkkkkkkkkkkkkkc                                 
     ...................,',,:lxkkkkkkkkkkkkkd.                                  
     ..........................';;:coxkkkkk:                                    
        ...............................ckd.                                     
          ...............................                                       
                ...........................                                     
                   .......................                                      
                              ....... ...                                       
 
With gdb you fixed the race.
The other elves we did out-pace.
  And now they'll see.
  They'll all watch me.
I'll hang the bells on Santa's sleigh!
 

Congratulations! You've won, and have successfully completed this challenge.

Afterwards, chat with Shinny Upatree:

Shinny Upatree

Sweet candy goodness - I win! Thank you so much!
Have you heard that Kringle Castle was hit by a new ransomware called Wannacookie?
Several elves reported receiving a cookie recipe Word doc. When opened, a PowerShell screen flashed by and their files were encrypted.
Many elves were affected, so Alabaster went to go see if he could help out.
I hope Alabaster watched the PowerShell Malware talk at KringleCon before he tried analyzing Wannacookie on his computer.
An elf I follow online said he analyzed Wannacookie and that it communicates over DNS.
He also said that Wannacookie transfers files over DNS and that it looks like it grabs a public key this way.
Another recent ransomware made it possible to retrieve crypto keys from memory. Hopefully the same is true for Wannacookie!
Of course, this all depends how the key was encrypted and managed in memory. Proper public key encryption requires a private key to decrypt.
Perhaps there is a flaw in the wannacookie author's DNS server that we can manipulate to retrieve what we need.
If so, we can retrieve our keys from memory, decrypt the key, and then decrypt our ransomed files.

details

  • .bashrc - relevant part
  • cat /etc/motd

  • /etc/motd
  • sleighbell-lotto - ELF binary
  • Reverse engineering the binary turns out to be a simple rand(), seeded by current time() via srand() and comparing result to 1225.

    srand(time(0));
    puts("\nThe winning ticket is number 1225.\nRolling the tumblers to see what number you'll draw...\n");
    sleep(1);
    nr = rand() % 10000;
    printf("You drew ticket number ");
    printf("%d", nr);
    puts("!\n");
    if (nr == 1225)
    	winnerwinner();
    else
    	sorry("!\n");
    exit(0);

    It means that simple function rand() hooking via LD_PRELOAD would also allow to win the challenge. Unfortunately, the host doesn't have gcc to compile shared library. So the approach is to compile it locally and upload it by pasting base64-encoded text and decoding it. After that it's just a matter of running env LD_PRELOAD=$PWD/rand_hook.so ./sleighbell-lotto and challenge is won.

    Also, HMAC key a6ec0e49731b4c29907422c23794b9a6 (used to verify challenge completion) can be retrieved either by pseudo disassembler output of winnerwinner function with radare2 or by checking third arguments (register $rdx) passed to hash creation function hmac_sha256 via gdb.

    % r2 -A sleighbell-lotto
    [Invalid instruction of 16351 bytes at 0x124 entry0 (aa)
    [x] Analyze all flags starting with sym. and entry0 (aa)
    [x] Analyze function calls (aac)
    [x] Analyze len bytes of instructions for references (aar)
    [x] Constructing a function name for fcn.* and sym.func.* functions (aan)
    [x] Type matching analysis for all functions (afta)
    [x] Use -AA or aaaa to perform additional experimental analysis.
    [0x00000a00]> pdc @ sym.winnerwinner | egrep "[a-f0-9]{32}"
               size_t strlen(const char * s : 0x00000000 = a6ec0e49731b4c29907422c23794b9a6@)
               size_t strlen(const char * s : 0x00000000 = a6ec0e49731b4c29907422c23794b9a6@)
               rcx = qword [s]          //(cstr 0x00000000) "a6ec0e49731b4c29907422c23794b9a6@"
               r8 = rcx                 //(cstr 0x00000000) "a6ec0e49731b4c29907422c23794b9a6@"
               rdx = qword [local_a0h]  ; (cstr 0x00000000) "a6ec0e49731b4c29907422c23794b9a6@"
               rax = qword [s]          //(cstr 0x00000000) "a6ec0e49731b4c29907422c23794b9a6@"
               rdi = rax                //(cstr 0x00000000) "a6ec0e49731b4c29907422c23794b9a6@"
               rcx = rax                //(cstr 0x00000000) "a6ec0e49731b4c29907422c23794b9a6@"
               rax = qword [local_a0h]  //(cstr 0x00000000) "a6ec0e49731b4c29907422c23794b9a6@"
               rdx = rax                //(cstr 0x00000000) "a6ec0e49731b4c29907422c23794b9a6@"
               rsi = rcx                //(cstr 0x00000000) "a6ec0e49731b4c29907422c23794b9a6@"
               rdx = qword [local_d8h]  //(cstr 0x00000000) "a6ec0e49731b4c29907422c23794b9a6@"
                   rsp += 0xd8              //(cstr 0x00000000) "a6ec0e49731b4c29907422c23794b9a6@" ; "6ec0e49731b4c29907422c23794b9a6@"
                   pop rbx                  //(cstr 0x00000000) "a6ec0e49731b4c29907422c23794b9a6@"
                                            //(cstr 0x00000000) "a6ec0e49731b4c29907422c23794b9a6@"