
┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ ls -alR | grep ftp
-rwxrwxr-x 1 kali kali 52464 Feb 15 20:10 tftpupload
-rw-r--r-- 1 kali kali 5068 Feb 15 20:10 errrftp.htm
lrwxrwxrwx 1 kali kali 17 Feb 15 20:10 ftpd -> ../../bin/busybox
lrwxrwxrwx 1 kali kali 17 Feb 15 20:10 ftpputimage -> ../../bin/busybox
tftpupload, errrftp.htm 검사 결과FTP 서비스
ftpd: /bin/busybox에 대한 심볼릭 링크ftpputimage: /bin/busybox에 대한 심볼릭 링크TFTP 서비스
tftpuploaderrrftp.htmtftpupload 바이너리 분석recvfrom
***tftp server, listen port: 69***
/proc/mtdrmtd support not enable?
/bin/mtd_write -o %d -l %d write %s Kernel
write kernel
/bin/mtd_write -o %d -l %d write %s Bootloader
write bootloader
TFTP(Trivial File Transfer Protocol) 서버가 포트 69에서 실행됨
mtd_write 관련 메시지 포함: 플래시 메모리에 직접 기록하는 기능을 가질 가능성 존재
로그 메시지 및 업로드 실패 처리
cannot open upgrade file !!!
cannot stat upgrade file !!!
cannot mmap upgrade file !!!
upgrade file size is too small!!!
upgrade file with different signature !!!
upgrade file without signature !!!
upgrade file with bad checksum !!!
확인 결과, tftp 서비스가 바로 돌아가는 건 아닌 것으로 보임
RT2860_default_novlan┌──(kali㉿kali)-[~/…/cpio-root/etc_ro/Wireless/RT2860AP]
└─$ cat RT2860_default_novlan
#The word of "Default" must not be removed
Default
WebInit=1
HostName=ralink
Login=admin
Password=admin
...
admin/admin)을 이용해 쉽게 접근할 수 있음┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri "getHEXString" ./etc_ro/web/
./etc_ro/web/function.js:function getHEXString(instr)
./etc_ro/web/advanced.htm: if ((frm.AdminPassword.value == getHEXString(frm.OldPassword.value)) && ((frm.NewPassword.value == frm.RetypePassword.value)))
./etc_ro/web/advanced.htm: if (frm.AdminPassword.value != getHEXString(frm.OldPassword.value))
/etc_ro/web/function.js 에 getHEXString() 함수가 존재advanced.htm에서 getHEXString()을 사용하여 비밀번호를 변환하는 것으로 판단<FORM ACTION="/setSystemAdmin" METHOD="POST" autocomplete="off">
<input type="hidden" name="AdminID" value="admin">
<input type="hidden" name="AdminPassword" value="%%AdminPassword(2);%%">
hidden input)에 저장┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri "getHEXString" ./bin ./sbin ./usr/bin ./usr/sbin
grep: ./bin/alphapd: binary file matches
alphad 파일 분석int __fastcall nipcauserverify(int a1)
{
int v1; // $v1
const char *v3; // $v0
int v4; // $a1
char v5; // $a2
int v6; // $v1
int v7; // $a0
int v8; // $v0
_DWORD v10[16]; // [sp+20h] [-40h] BYREF
v1 = *(_DWORD *)(a1 + 172);
switch ( v1 )
{
case 3:
strcpy((char *)v10, "group=Administrator\r\n");
goto LABEL_8;
case 2:
strcpy((char *)v10, "group=Controller\r\n");
goto LABEL_8;
case 1:
v4 = *(_DWORD *)"group=User\r\n";
v3 = "group=User\r\n";
goto LABEL_6;
}
v3 = "group=None\r\n";
if ( !v1 )
{
v4 = *(_DWORD *)"group=None\r\n";
LABEL_6:
v5 = v3[12];
v6 = *((_DWORD *)v3 + 1);
v7 = *((_DWORD *)v3 + 2);
v10[0] = v4;
v10[1] = v6;
v10[2] = v7;
LOBYTE(v10[3]) = v5;
}
LABEL_8:
v8 = strlen(v10);
websWriteNormalHeader(a1, 200, v8, "application/Dlink-inf", 0);
websWriteFmt(a1, (const char *)v10);
return websConnClose(a1, 200);
}
v1 = *(_DWORD *)(a1 + 172);
a1 + 172 오프셋의 값을 확인하여 사용자 권한 등급(v1)을 판별
switch (v1) 문을 사용하여 v1 값에 따라 다른 그룹을 할당
그룹별 권한 처리
switch (v1)
{
case 3:
strcpy((char *)v10, "group=Administrator\r\n");
goto LABEL_8;
case 2:
strcpy((char *)v10, "group=Controller\r\n");
goto LABEL_8;
case 1:
v4 = *(_DWORD *)"group=User\r\n";
v3 = "group=User\r\n";
goto LABEL_6;
}
v1 == 3 → "Administrator" (최고 권한)
v1 == 2 → "Controller" (중간 관리자)
v1 == 1 → "User" (일반 사용자)
v1 == 0 → "None" (권한 없음)
웹 응답 처리
v8 = strlen(v10);
websWriteNormalHeader(a1, 200, v8, "application/Dlink-inf", 0);
websWriteFmt(a1, (const char *)v10);
return websConnClose(a1, 200);
websWriteNormalHeader(): 웹 서버 응답 헤더 작성websWriteFmt(): 응답 본문에 사용자 그룹 정보를 출력websConnClose(a1, 200);: HTTP 응답을 종료 (200 OK)int websStartAuthentication()
{
int v0; // $v0
v0 = nvram_bufget(0, "AccessControlEnable");
if ( !strcmp(v0, &word_44D1B8) )
websEnableAllUser();
return websEnableHtmlFile();
}
nvram_bufget(0, "AccessControlEnable")
AccessControlEnable 값을 가져옴!strcmp(v0, &word_44D1B8)
word_44D1B8는 비교 대상 문자열AccessControlEnable 값이 특정 값과 일치하면 모든 사용자 인증을 허용(websEnableAllUser)websEnableAllUser();
int __fastcall websGetAuthenticateRealm(int a1)
{
_DWORD *v1; // $s0
char *v3; // $a1
v1 = &websForceAuthenticPathList;
v3 = off_491294;
if ( !off_491294 )
return 0;
while ( webncasestrcmp(*(_DWORD *)(a1 + 136), (int)v3) )
{
v1 += 2;
v3 = (char *)v1[1];
if ( !v3 )
return 0;
}
return *v1;
}
websForceAuthenticPathList) 목록을 확인하여 인증이 필요한지 판단webncasestrcmp(*(_DWORD *)(a1 + 136), (int)v3)0 반환(즉, 인증 우회 가능?)어떤 경로가 보호되고 있는지
websForceAuthenticPathList값을 확인해야 함
int websEndAuthentication()
{
int v0; // $v0
v0 = nvram_bufget(0, "AccessControlEnable");
if ( !strcmp(v0, &word_44D1B8) )
websDisableAllUser();
return websDisableHtmlFile();
}
websStartAuthentication()와 유사하지만, 인증 시스템을 종료하는 역할AccessControlEnable 값이 특정 값이면, 모든 사용자의 인증을 비활성화(websDisableAllUser)AccessControlEnable)을 조작할 경우, 인증이 비활성화될 가능성 존재alphapd 실행 파일에서 명령어 실행 함수 검색┌──(kali㉿kali)-[~/…/_50040.extracted/_3B6000.extracted/cpio-root/bin]
└─$ strings ./alphapd | grep -E "system|popen|exec"
system
execve
please execute nvram_daemon first!
/cgi/system.cgi
/cgi/isystem.cgi
Can't execve %s: %s
Stream CGI process file is not executable
┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri "system" ./etc_ro/web/cgi/
┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri "popen" ./etc_ro/web/cgi/
┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri "exec" ./etc_ro/web/cgi/
./etc_ro/web/cgi/에서 system(), popen(), exec() 함수 호출이 없음┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri "cmd" ./etc_ro/web/
grep: ./etc_ro/web/api/aplug.class: binary file matches
./etc_ro/web/html.htm:1 3 docmd.htm
┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri "shell" ./etc_ro/web/
┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri "ping" ./etc_ro/web/
grep: ./etc_ro/web/api/aplugLiteDL.cab: binary file matches
./etc_ro/web/html.htm: 1 3 docmd.htm"docmd.htm"이 존재하는 것으로 보이며, 이 파일이 명령어 실행과 관련 있을 가능성 존재./etc_ro/web/api/aplugLiteDL.cab가 바이너리 매칭됨ping 관련 코드를 포함한 바이너리가 있을 가능성 존재