
Tivoli FastBack Server (6.1.4) is vulnerable to a stack-based buffer overflow allowing threat-actors to gain Arbitrary Code Execution (ACE) via a remote TCP-connection. The PoC provided in this repository leverages this vulnerability to establish a reverse-shell.
O aplicativo Tivoli FastBack Server (6.1.4) é vulnerável a um estouro de buffer baseado em pilha, permitindo que atores de ameaças obtenham Execução Arbitrária de Código (ACE) através de uma conexão TCP remota. O PoC fornecido neste repositório aproveita essa vulnerabilidade para executar CMD.exe no alvo e lidar com a conexão de entrada para estabelecer um reverse-shell.

[!NOTE] Este PoC é baseado em um PoC previamente publicado, e foi expandido com um bypass de ASLR além de uma arquitetura melhorada seguindo paradigmas comuns de engenharia de software. Como a estrutura multi-arquivo recomendada pode não ser desejável para todos os casos, uma versão em arquivo único do exploit é fornecida em
assets/single.py.
O PoC se comunica com o aplicativo vulnerável através da porta TCP 11460. Os dados transmitidos para esta porta devem seguir a estrutura definida abaixo:
0x00000123 0x00000000 0x00000000 0x00000000
0x00000ABC 0x00000AAA 0x00000111 0x00000BBB
0x00000222 0x00000CCC 0x00000333 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
<buffer 1> ...
<buffer 2> ...
<buffer 3> ...
Usando a estrutura de pacote mencionada, o PoC invoca a função _FXCLI_SetConfFileChunk identificada pelo opcode 0x534. Daqui, a execução leva a uma chamada para sscanf cujos argumentos são lidos do buffer (1) sem a devida sanitização. Ao fornecer um bloco de exatamente 0x118 bytes, o ponteiro eip é sobrescrito com qualquer valor que resida nos últimos 4 bytes.
Para contornar o ASLR, o PoC invoca a função FXCLI_DebugDispatch enviando o pacote de rede mencionado com o opcode 0x2000. Esta função lê o primeiro buffer para uma funcionalidade específica, algumas das quais estão listadas abaixo:
DumpMemoryPoolsReadRepositorySectorsSymbolOperationO PoC usa a funcionalidade SymbolOperation, que recebe um símbolo arbitrário e retorna seu endereço base. Com isso, o endereço de N98E_CRYPTO_get_new_lockid é resolvido e seu deslocamento (0x14E0) é subtraído. Isso resulta no endereço base de libeay32IBM019.dll, que será amplamente utilizado na próxima fase de bypass.
Antes da ROP ser construída, a base é verificada quanto a possíveis caracteres-ruins. Se eles estiverem presentes, o aplicativo vulnerável é reiniciado ao estourar o buffer e sobrescrever eip com o valor sem sentido de 0x90909090. Depois disso, o aplicativo é sondado até que esteja online novamente, reiniciando o ciclo.
Uma cadeia ROP é construída usando a base adquirida na fase de bypass anterior. Esta cadeia ROP invoca o WriteProcessMemory e copia o conteúdo do "invite" para a code-cave da seção .text em libeay32IBM019.dll.
Quando a cadeia ROP é construída, todo o seu conteúdo (resolvido) é novamente verificado quanto a possíveis caracteres-ruins. Se estes estiverem presentes, o aplicativo é reiniciado da mesma forma que na fase de bypass anterior, e o ciclo recomeça.
[!NOTE] Para evitar um loop infinito durante a fase de bypass, o PoC foi configurado para tentar novamente o bypass por no máximo 10 minutos. Após isso, o exploit será encerrado porque o tempo limite foi atingido.
Após as mitigações do exploit terem sido contornadas, a ACE genérica já é alcançada. Essa ACE é aproveitada para executar um shellcode específico que cria um processo de CMD.exe com CreateProcessA. Os argumentos dessa chamada são definidos para redirecionar todos os pipes (STDIN, STDOUT, STDERR) para uma conexão socket que está conectada com o localhost.
Simultaneamente, o PoC inicia um listener no localhost que captura a requisição de entrada do host remoto e inicia uma interface CLI muito básica para interagir com o processo CMD.exe criado.
graph
a("Start")
b("Buffer overflow: crash")
c("Buffer overflow: hijack")
subgraph sa["ASLR Bypass"]
a1["Resolve API with 'SymbolOperation'"]
a2["Subtract offset (0x14E0)"]
a3{"Base contains bad-chars?"}
a1 -->| N98E_CRYPTO_get_new_lockid | a2
a2 -->| libeay32IBM019.dll | a3
end
subgraph sb["DEP Bypass"]
b1["Construct ROP"]
b2{"ROP contains bad-chars?"}
b3["Locate shellcode"]
b4["Locate code-cave"]
b5["Invoke WriteProcessMemory"]
b6["Return to shellcode"]
b1 --> b2
b2 -->| no | b3
b3 --> b4
b4 --> b5
b5 --> b6
end
subgraph sc["Reverse Shell"]
c1["(Remote) connect to localhost"]
c2["(Local) listen on available port"]
c3["(Local) accept connection"]
c4["(Local) loop over CMDs"]
c1 --> c2
c2 --> c3
c3 --> c4
end
a3 -->| no | sb
b2 -->| yes | b
a3 -->| yes | b
a --> sa
b --> a
b6 --> c --> sc
| campo | descrição | alvo |
|---|
123 | tamanho | pacote |
ABC | opcode | função |
AAA, 111 | offset, tamanho | buffer (1) |
BBB, 222 | offset, tamanho | buffer (2) |
CCC, 333 | offset, tamanho | buffer (3) |