다른 프로세스가 ServerSocket에 연결하는 것을 막을 수 있다고 생각하지 않지만 사용자가 또는 다른 프로세스에 속하는지 확실하게 결정할 수있는 연결을 허용합니다.
InetSocketAddress remoteAddress = (InetSocketAddress) socket.getRemoteSocketAddress();
String hostname = remoteAddress.getHostName();
if (!hostname.equals("localhost")) { socket.close(); }
이 또는 당신이 (EJP 언급처럼) 127.0.0.1 또는 0.0.0.0과 같은 루프백 주소로 소켓을 바인딩하고이 단계를 건너 뛸 수 있습니다 : 첫 번째 단계는 연결이 로컬 호스트에서 유래 경우 알아낼 수 있습니다. localhost에서 연결이되었다는 것을 알게되면 원격 포트를 찾아 프로세스가 소유하고 있는지 파악해야합니다.
int remotePort = remoteAddress.getPort();
if (ownPort(remotePort) == 1) { socket.close(); }
는 지금까지 내가 아는 한, 자바는 프로세스 포트를 나열하는 데 사용할 수있는 API가없는하지만 당신은 JNI를 통해 그렇게 확실히 할 수 있습니다.
private native int doOwnPort(int port);
그리고 네이티브 쪽 :
JNIEXPORT jint JNICALL Java_something_doOwnPort(JNIEnv *env, jobject object, jint port) {
long totalFDs = getdtablesize();
struct sockaddr_in sa;
struct stat sb;
// Iterate through all file descriptors
for (int i = 0; i < totalFDs; ++i) {
// Check if "i" is a valid FD
memset(&sb, 0, sizeof(sb));
if (fstat(i, &sb) < 0)
continue;
// Check if "i" is a socket
if (!S_ISSOCK(sb.st_mode))
continue;
// Get local address of socket with FD "i"
memset(&sa, 0, sizeof(sa));
socklen_t sa_len = sizeof(sa);
getsockname(i, (struct sockaddr*) &sa, &sa_len);
// Check if the port matches
if (sa.sin_port == port)
return 1; // We own the port
}
return -1; // We don't own the port
}
PS :이 코드는 리눅스입니다하지만 너무 안드로이드/윈도우/OSX에서 작동해야 자바에 당신이 뭔가를해야합니다.
아마도 FD가 테이블을 반복하지 않아도 포트가 현재 프로세스에 의해 소유되어 있는지 확인하는 더 직접적이고 효율적인 방법이 있지만 별개의 문제입니다. HTH! Android Security Tips에서
안드로이드에서'getdtablesize()'를 찾지 못했습니다. 정의 된 위치를 보여줄 수 있습니까? –
'#include'을 사용하거나 직접 정의하십시오 여기에 : https://github.com/OpenWireSec/metasploit/blob/master/external/source/meterpreter/source/bionic/libc/unistd/getdtablesize.c –
예! 작동합니다! 분명히 Android NDK에는 'ge tdtablesize()'를'unistd.h'에서 사용했지만 다른 구현체를 사용했기 때문에 작동합니다. –