This is a very broad question, but I'll do my best to cover it all briefly.
A website can be a very complex piece of software. Whilst many sites may be static, i.e. only serving plain HTML documents, a large number of them are dynamic, i.e. outputting HTML content from a script, which may access database resources or files. These are commonly written in PHP or ASP.NET, but there are many other technologies out there. As such, an error in one of those scripts might allow an attacker to compromise the server.
However, we're already getting ahead of ourselves. The server is already an extremely complicated system - it contains hardware, firmware and software. The hardware takes signals from external sources (e.g. a network cable, or a keyboard) and translates them into data that can be stored in RAM and processed by system software. The translation process and state management is often handled by a special type of software running directly on hardware peripherals, which is called firmware. That firmware helps translate the incoming raw data into the complex structures needed by the system software. From there, the operating system software (e.g. kernel) takes those raw structures and provides a layer of abstraction to user programs. This can be another very complicated set of software. On top of all of that, we have user programs that run on the operating system, which might include your web server or FTP server.
All of these layers represent an attack surface, which essentially means that they have a potential for software bugs that might be exploited by an attacker. The most commonly attacked layer is the user programs, but all of them have potential as a target. For example, the firmware of a network card might decode the 802.11n wifi protocol, then translate the data into ethernet frames. If a flaw is discovered in the network card's firmware, it may be possible to cause the device to malfunction, by sending a specially crafted packet of data over a wifi signal. This might result in a denial of service (DoS) condition, which causes the device to stop transmitting and receiving data.
The operating system is an incredibly complicated piece of software, which again may represent a large attack surface. Vulnerabilities in the operating system and its kernel are less common these days, but they still exist. A good example of this is MS08-067, which is a vulnerability in a Windows service that allows a remote attacker to send a specially crafted packet that contains executable code, and that code ends up being run on the server. That code might cause a new user to be created on the system (which can later be logged into via remote desktop) or a command prompt to be spawned and piped back to the attacker over a TCP connection. Both of these types of attack result in the attacker fully compromising the server, without ever needing to know credentials for the server itself or its FTP service.
Of course, these types of bugs also affect user-installed services, including the web server software itself (e.g. Apache / IIS) and FTP, SSH, VNC, SQL, etc. It's entirely possible for any of these services to have remote code execution bugs, command injection bugs, denial of service bugs, authentication bypass bugs, etc. Keeping them up to date is critical, because these bugs are frequently discovered and patched. Not keeping them up to date might result in an attacker using a bug to gain unauthorized access to the system.
Finally, we have the actual website. If you're using a dynamic site (known as a web application) via PHP or ASP.NET, you're essentially taking a HTTP request from a user, parsing that HTTP request into a format that can be understood by the web application, performing an action based on the request, and outputting some content. All of these areas might have bugs in them, but the most common area is the part where an action is performed based on the user request. For example, we might take a parameter from the URL and use it in an SQL database query to get a list of forum posts, then output the results in a HTML format. If the SQL query operation is poorly written, a malicious user may be able to craft a specially formatted URL that causes the query to behave differently - for example return all user records rather than all forum posts. This is called SQL injection. They can then take those credentials and crack any hashed passwords offline, then use them to log into the site.
Another common vulnerability is an Insecure Direct Object Reference bug, which occurs when a web application doesn't properly control access to resources. For example, you might have a list of documents that your user has access to, with numeric IDs being passed into a script which displays the document, e.g.
document.php?id=123. Whilst the list of documents only displays the ones the user has access to, the user might change the ID in the URL to directly reference a document that they shouldn't have access to. If proper checks aren't included, the user might be able to access pages or operations that they shouldn't be able to. This might result in a malicious user being able to change another user's settings.
Many other classes of web application bugs exist - remote file inclusion (RFI), local file inclusion (LFI), unrestricted upload bugs, session ID leakage / predictability, insecure communication, etc. It's probably a good idea to check out the OWASP Top 10 for a more comprehensive list.
So, all in all, there are a lot of vectors via which an attacker may break into a website, and services such as FTP are only a small part of the picture.