칼리리눅스 2.0에서 IPTIME의 N150UA USB무선랜카드 사용하는 방법을 소개하겠다.

아래 삭제된 내용과 같이 글을 썼었는데, 왜인지 모르겠으나 rt28xx_get_wireless_stats() 함수에서 커널 패닉이 종종 일어나는 것을 확인하였다.

조금 더 뒤적뒤적해본 결과 리눅스 커널 4.2부터 MT7601U가 지원된다는 것을 확인할 수 있었다. 하지만 칼리리눅스 2.0의 기본 커널 버전은 4.0이었다. 따라서 커널컴파일을 해서 커널 업그레이드를 시도해보았다.

현재 kernel.org에서 stable한 버전은 4.4.2버전이므로 이 버전으로 업그레이드를 진행하였다. http://docs.kali.org/development/recompiling-the-kali-linux-kernel를 참고하였다.

커널 컴파일을 본격적으로 진행하기 전에 실패할 경우를 대비해 SNAPSHOT을 꼭 찍어두길 바란다.

apt-get install kernel-package ncurses-dev fakeroot

로 필요한 것들을 받아준다. 그리고 kernel.org에서 linux-4.4.2.tar.xz 등 최신 stable 버전을 받아준다.

tar -xvf linux-4.4.2.tar.xz
cd linux-4.4.2

로 압축을 푼 뒤 폴더로 이동한다.

cp /boot/config-4.0.0-kali1-amd64 .config

로 기본 설정을 복사해준 뒤

make menuconfig

를 이용해 세부 설정을 해준다. 이 때, MT7601U는 기본으로 설치되지 않아 설정이 필요하다.

Device drivers - Network device support - Wireless LAN - Mediatek Wireless LAN support

로 들어가 이를 체크해주고, 이 하위로 들어가 Mediatek MT7601U (USB) support도 체크해준다. 하위 옵션으로 이동시에는 엔터를, 체크에는 스페이스바를 이용하면 된다. 체크를 해준 뒤 save를 해서 콘솔로 빠져나온다.


export CONCURRENCY_LEVEL=$(cat /proc/cpuinfo | grep processor | wc -l)

를 통해 멀티코어를 이용해 컴파일을 할 수 있다.

make-kpkg clean

로 이전 패키지가 존재한다면 삭제하고,

fakeroot make-kpkg kernel_image

를 이용해 컴파일한다. 이 때 컴파일 시간이 환경에 따라 몇 시간까지 걸릴 수 있으니 자고 오거나 하면 된다.

컴파일이 완료되면 다음과 같이 입력해주면 된다.

dpkg -i ../linux-image-4.4.2_4.4.2-10.00.Custom_amd64.deb
update-initramfs -c -k 4.4.2
update-grub2
reboot

버전이나 deb 파일명은 알아서 조절하면 된다. 재부팅 이후에 바로 될줄 알았는데 firmware를 설치해주어야 한다.

wget -O /lib/firmware/mt7601u.bin https://git.kernel.org/cgit/linux/kernel/git/firmware/linux-firmware.git/plain/mt7601u.bin

deprecated: https://github.com/porjo/mt7601/raw/master/src/mcu/bin/MT7601.bin)

그리고 다시 재부팅하면 잘 되는 것을 확인할 수 있다.


혹시 커널컴파일이 귀찮은 분들을 위해 deb파일을 올려두겠다. 다시 한번 말하지만 실패할 경우를 대비해 꼭 SNAPSHOT을 찍어두길 바란다.

linux-image-4.4.2_4.4.2-10.00.Custom_amd64.7z.001

linux-image-4.4.2_4.4.2-10.00.Custom_amd64.7z.002

linux-image-4.4.2_4.4.2-10.00.Custom_amd64.7z.003

linux-image-4.4.2_4.4.2-10.00.Custom_amd64.7z.004


=== 16.02.24 업데이트로 삭제된 내용 (사유: 잦은 커널 패닉) ===

칼리리눅스에 N150UA를 연결한 뒤 lsusb를 입력하면 MT7601U를 볼 수 있다.

하지만 iwconfig를 쳐보면 인식이 되지 않는다. 드라이버를 설치해야 한다.

N150UA Linux용 드라이버는 http://www.mediatek.com/en/downloads1/downloads/?sort=os 에서 MT7601U USB를 선택해 다운받을 수 있다.

먼저 

apt-get install linux-headers-$(uname -r) build-essential

로 필요한 헤더와 프로그램 등을 다운받는다.

압축을 푼 뒤 이를 컴파일해서 install해야하는데, 오래된 소스이다보니 make를 그냥 하면 몇 군데 에러가 뜬다.

총 두 군데를 고쳐야한다.

1. sta/sta_cfg.c

__DATE__와 __TIME__ 매크로에서 에러가 난다. 따라서 5766번째 줄을 다음과 같이 수정한다.


2. os/linux/rt_linux.c

type casting이 지원이 되지 않아 에러가 난다. 강제 casting을 해준다.


그런 다음 make와 make install을 차례대로 실행 후 reboot한 뒤 modprobe mt7601Usta해주면 잘 된다.

pip는 python 2.7.9 이후에는 내장되어있다. Windows에서 pip로 모듈을 설치하다보면 

File "C:\Python27\lib\ntpath.py", line 85, in join

  result_path = result_path + p_path

UnicodeDecodeError: 'ascii' codec can't decode byte 0xbd in position 0: ordinal not in range(128)

과 같은 에러가 뜰 때가 있다. (byte 0xbd와 position 0은 달라질 수 있음)

이 때 확인해봐야 할 것은 경로명에 한글이 있는지(예: C:\Users\홍길동), 그리고 hostname(PC명)에 한글이 있는지 확인해보아야 한다.

hostname은 내컴퓨터의 시스템속성(프로세서, RAM같은거 써있고 컴퓨터 성능 별점매길수 있는 페이지)에서 확인할 수 있다.

hostname에 한글이 있다면(정확히는 ascii가 아닌 글자가 있다면) 이를 영어로 바꿔주자.

단, hostname을 바꾸면 인터넷뱅킹같은거 할 때 귀찮아질 수도 있다.. (새로은 PC로 인식해 다시 등록하라고 할 수 있음. 사실 안 해봐서 확답은 못 드림)

1. 평소와 다른 인터넷 [100]

--to be added--


2. 0-day is not zeroday [200]

파일을 winhex로 열면 0x200부터 0x2a1까지 이상한 값으로 채워진 것을 볼 수 있는데, 78 9C로 시작하는 것으로 보아 zlib으로 압축된 것을 알 수 있다.

이를 파이썬으로 압축을 풀면 이상한 문자열이 나온다.

이를 hex로 encode해서 출력하면 69210710으로 도배되어있고, 중간에 셸코드 비스무리한게 있는 것을 볼 수 있다.

이를 새로운 바이너리에 붙여넣고 IDA로 열면 결과가 다음과 같다.

0x57주소에서부터 push를 여러번 하는 것을 볼 수 있는데, 값을 보니 문자열인 듯하다. 이를 해석하면 flag를 얻을 수 있다.

print ' RjFORF83SDROS1kwVQ=='.decode('base64')


Flag: F1ND_7H4NKY0U


3. 무엇을 숨기고 있는 걸까 [200]

app-release.apk파일이 주어진다. 확장자를 zip으로 바꿔서 dex파일을 추출하고 dex2jar을 이용하 jar로 변환한 뒤 jdgui를 통해 jar의 소스를 볼 수 있다. 앱을 디컴파일하는 방법은 구글에도 많이 나와있다.

j함수는 파이썬으로 바꿔서 실행하면 다음과 같다.

print "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[27] +\
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[15] +\
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[8] + \
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[49] +\
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[2] + \
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[11] +\
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[4] + \
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[40] +\
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[7] + \
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[3] + \
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[18] +\
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[14] +\
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[3] + \
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[8] + \
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[6] + \
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_?"[9]
# WhoBestGirlgroup

또 a함수를 살펴보면 paramString1을 paramString2로 복호화하는 것을 알 수 있고, onClick 함수를 살펴보면 a(j, i)를 호출한다.

그런데 i는 비어있으므로 j를 어떻게해서든 복호화시켜야 할 것으로 보인다.

처음엔 j를 복호화하면 WhoBestGirlgroup이 되는 줄 알고 AES known plaintext attack을 찾아보는데 이는 불가능하다그래서 좌절하다가 이미 알고 있는 문자열(j, k, "WhoBestGirlgroup")가지고 P와 C를 이리저리 바꿔보다가 다음을 발견했다.

from Crypto.Cipher import AES

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS) 
unpad = lambda s : s[0:-ord(s[-1])]

def decode(c, key):
	d = AES.new(key, AES.MODE_CBC, "\x00"*16)
	return d.decrypt(c)

print decode('BHNRDV1XGb49eg2fgKiExfJ4l5UyBNpVEUQtcDxciEc='.decode('base64'), "WhoBestGirlgroup")
# AoAisGirlgroup!!

따라서 AoAisGirlgroup!! 가 flag인줄 알고 시도해봤는데 틀렸다고나와서 멘붕에 빠졌는데, 이 문자열을 key로 또다시 이것저것 하다가 다음을 발견했다.

print decode('2qydvlQqANT8eI7gok5jPQ=='.decode('base64'), "AoAisGirlgroup!!")
# Hdc0nisAwesome

약간의 guessing이 필요한 문제였다.

Flag: Hdc0nisAwesome


+ Recent posts