; -----------------------------------------------------------------------------
; ÆÄÀϸí: realip_finder.asm
; ºôµå ¹æ¹ý:
; nasm -f elf64 realip_finder.asm -o realip_finder.o
; gcc realip_finder.o -o realip_finder -no-pie
; -----------------------------------------------------------------------------
extern printf
extern sprintf
extern snprintf
extern popen
extern pclose
extern fgets
extern getaddrinfo
extern freeaddrinfo
extern inet_pton
extern inet_ntop
extern strchr
extern strcspn
extern strncpy
extern atoi
extern memset
extern exit
extern perror
section .data
; »ö»ó ÄÚµå
color_red db 0x1b, "[31m", 0
color_green db 0x1b, "[32m", 0
color_reset db 0x1b, "[0m", 0
; ¸Þ½ÃÁö
msg_usage db "»ç¿ë¹ý: %s <target-domain>", 10, 0
msg_start db 0x1b, "[32m=== Auto Real-IP Detector Started ===", 0x1b, "[0m", 10, 0
msg_target db "Target: %s", 10, 0
msg_scan db "Scanning subdomains using 'subfinder'...", 10, 10, 0
msg_err_cmd db "Subfinder ½ÇÇà ½ÇÆÐ", 0
msg_done db 10, 0x1b, "[32m=== Scan Completed ===", 0x1b, "[0m", 10, 0
fmt_cf db "[CF] %s -> %s", 10, 0
fmt_real db 0x1b, "[31m[REAL] %s -> %s (Target Found!)", 0x1b, "[0m", 10, 0
cmd_fmt db "subfinder -d %s -silent", 0
mode_r db "r", 0
newline db 10, 0
; Cloudflare IP Ranges
cf_r1 db "173.245.48.0/20", 0
cf_r2 db "103.21.244.0/22", 0
cf_r3 db "103.22.200.0/22", 0
cf_r4 db "103.31.4.0/22", 0
cf_r5 db "141.101.64.0/18", 0
cf_r6 db "108.162.192.0/18", 0
cf_r7 db "190.93.240.0/20", 0
cf_r8 db "188.114.96.0/20", 0
cf_r9 db "197.234.240.0/22", 0
cf_r10 db "198.41.128.0/17", 0
cf_r11 db "162.158.0.0/15", 0
cf_r12 db "104.16.0.0/13", 0
cf_r13 db "104.24.0.0/14", 0
cf_r14 db "172.64.0.0/13", 0
cf_r15 db "131.0.72.0/22", 0
cf_ranges dq cf_r1, cf_r2, cf_r3, cf_r4, cf_r5, cf_r6, cf_r7, cf_r8
dq cf_r9, cf_r10, cf_r11, cf_r12, cf_r13, cf_r14, cf_r15, 0
section .bss
cmd_buf resb 512
line_buf resb 256
section .text
global main
; -----------------------------------------------------------------------------
; ÇÔ¼ö: is_ip_in_cidr
; ¼³¸í: CIDR °è»ê ¹× ºñ±³
; -----------------------------------------------------------------------------
is_ip_in_cidr:
push rbp
mov rbp, rsp
; ½ºÅà Á¤·Ä: push rbx(8) + push r12(8) + push r13(8) + sub 72 = 96 (16ÀÇ ¹è¼ö)
push rbx
push r12
push r13
sub rsp, 72 ; ·ÎÄà º¯¼ö °ø°£
mov r12, rdi ; ip_str º¸Á¸
mov r13, rsi ; cidr_str º¸Á¸
; 1. CIDR º¹»ç
lea rdi, [rbp-48] ; cidr_copy (32 bytes)
mov rsi, r13
mov rdx, 31
call strncpy
mov byte [rbp-48+31], 0
; 2. ½½·¡½Ã ã±â
lea rdi, [rbp-48]
mov esi, '/'
call strchr
test rax, rax
jz .ret_false
mov byte [rax], 0 ; '/' -> NULL
inc rax
mov rdi, rax
call atoi
mov [rbp-52], eax ; prefix_len
; 3. IP º¯È¯ (inet_pton)
mov edi, 2 ; AF_INET
mov rsi, r12 ; ip_str
lea rdx, [rbp-56] ; &ip_addr
call inet_pton
cmp eax, 1
jne .ret_false
mov edi, 2 ; AF_INET
lea rsi, [rbp-48] ; cidr_copy
lea rdx, [rbp-60] ; &net_addr
call inet_pton
cmp eax, 1
jne .ret_false
; 4. ºñÆ® ºñ±³
mov eax, [rbp-56] ; ip
bswap eax
mov ebx, eax ; ebx = ip (host)
mov eax, [rbp-60] ; net
bswap eax
mov r12d, eax ; r12d = net (host)
mov ecx, [rbp-52] ; prefix
cmp ecx, 0
je .mask_zero
mov edx, 32
sub edx, ecx
mov ecx, edx
mov eax, -1
shl eax, cl
jmp .do_compare
.mask_zero:
xor eax, eax
.do_compare:
and ebx, eax
and r12d, eax
cmp ebx, r12d
je .ret_true
.ret_false:
xor eax, eax
jmp .cleanup
.ret_true:
mov eax, 1
.cleanup:
add rsp, 72
pop r13
pop r12
pop rbx
leave
ret
; -----------------------------------------------------------------------------
; ÇÔ¼ö: check_if_cloudflare
; -----------------------------------------------------------------------------
check_if_cloudflare:
push rbp
mov rbp, rsp
; ½ºÅà Á¤·Ä: push rbx(8) + push r12(8) = 16 (Á¤·ÄµÊ)
push rbx
push r12
mov r12, rdi ; ip_str
xor ebx, ebx ; index
.cf_loop:
lea rax, [cf_ranges]
mov rsi, [rax + rbx*8]
test rsi, rsi
jz .cf_not_found
mov rdi, r12
call is_ip_in_cidr
test eax, eax
jnz .cf_found
inc rbx
jmp .cf_loop
.cf_found:
mov eax, 1
jmp .cf_end
.cf_not_found:
xor eax, eax
.cf_end:
pop r12
pop rbx
leave
ret
; -----------------------------------------------------------------------------
; ÇÔ¼ö: analyze_domain (¿©±â°¡ °¡Àå Áß¿ä: ½ºÅà Á¤·Ä ¼öÁ¤µÊ)
; -----------------------------------------------------------------------------
analyze_domain:
push rbp
mov rbp, rsp
; [Áß¿ä] ½ºÅà Á¤·Ä °è»ê
; Call ÁøÀÔ ½Ã RSP ³¡ÀÚ¸®: 8 (Return Address)
; push rbp: 0 (16¹ÙÀÌÆ® Á¤·ÄµÊ)
; push rbx: 8 (Á¤·Ä ±úÁü)
; sub rsp, 72: 80 (16 * 5 = 80 -> Á¤·ÄµÊ!)
; ÃÑ °ø°£: 72¹ÙÀÌÆ® (·ÎÄú¯¼ö¿ë)
push rbx
sub rsp, 72
; [rbp-48]: struct addrinfo hints (48 bytes max)
; [rbp-56]: struct addrinfo *res (8 bytes)
; [rbp-72]: char ip_str[16] (16 bytes)
; Total needed: ~72 bytes.
mov rbx, rdi ; domain string
; 1. °³Çà Á¦°Å
mov rdi, rbx
lea rsi, [newline]
call strcspn
mov byte [rbx + rax], 0
; 2. memset hints
lea rdi, [rbp-48]
xor esi, esi
mov edx, 48 ; sizeof(hints)
call memset
; 3. hints ¼³Á¤
mov dword [rbp-48+4], 2 ; ai_family = AF_INET
mov dword [rbp-48+8], 1 ; ai_socktype = SOCK_STREAM
; 4. getaddrinfo
mov rdi, rbx ; node
xor esi, esi ; service
lea rdx, [rbp-48] ; hints
lea rcx, [rbp-56] ; res
call getaddrinfo
test eax, eax
jnz .ad_cleanup ; ½ÇÆÐ ½Ã ¸®ÅÏ
; 5. IP ̧̉
mov rax, [rbp-56] ; res
mov rax, [rax + 24] ; res->ai_addr -> struct sockaddr_in *
lea rsi, [rax + 4] ; &sin_addr (offset 4)
mov edi, 2 ; AF_INET
lea rdx, [rbp-72] ; dst (ip_str buffer)
mov ecx, 16 ; size
call inet_ntop
; 6. CF È®ÀÎ
lea rdi, [rbp-72]
call check_if_cloudflare
test eax, eax
jnz .print_cf
; REAL IP ¹ß°ß
lea rdi, [fmt_real]
mov rsi, rbx
lea rdx, [rbp-72]
xor eax, eax
call printf
jmp .free_res
.print_cf:
lea rdi, [fmt_cf]
mov rsi, rbx
lea rdx, [rbp-72]
xor eax, eax
call printf
.free_res:
mov rdi, [rbp-56]
call freeaddrinfo
.ad_cleanup:
add rsp, 72
pop rbx
leave
ret
; -----------------------------------------------------------------------------
; Main
; -----------------------------------------------------------------------------
main:
push rbp
mov rbp, rsp
sub rsp, 16 ; RSP Á¤·ÄµÊ (push rbp ÈÄ 0 -> sub 16 -> 0)
cmp edi, 2
je .run
lea rdi, [msg_usage]
mov rsi, [rsi]
xor eax, eax
call printf
mov eax, 1
leave
ret
.run:
mov rbx, [rsi + 8] ; argv[1]
lea rdi, [msg_start]
xor eax, eax
call printf
lea rdi, [msg_target]
mov rsi, rbx
xor eax, eax
call printf
lea rdi, [msg_scan]
xor eax, eax
call printf
; ¸í·É¾î »ý¼º
lea rdi, [cmd_buf]
mov rsi, 512
lea rdx, [cmd_fmt]
mov rcx, rbx
xor eax, eax
call snprintf
; popen
lea rdi, [cmd_buf]
lea rsi, [mode_r]
call popen
test rax, rax
jz .fail
mov [rbp-8], rax ; FILE *fp
.read:
lea rdi, [line_buf]
mov esi, 256
mov rdx, [rbp-8]
call fgets
test rax, rax
jz .close
lea rdi, [line_buf]
call analyze_domain
jmp .read
.close:
mov rdi, [rbp-8]
call pclose
lea rdi, [msg_done]
xor eax, eax
call printf
xor eax, eax
leave
ret
.fail:
lea rdi, [msg_err_cmd]
call perror
mov eax, 1
leave
ret |