Dahua Login Bypass Tool - Chrome Extension

bp2008

Staff member
Mar 10, 2014
12,770
14,297
USA
I have built a Chrome extension that exploits the recently disclosed Dahua vulnerabilities discussed here to log you in to Dahua cameras without needing to know the password. There is a technical description of the vulnerabilities here which shows how easy this is.

This is meant to be a tool to recover devices with lost password, but it also serves as a reminder to everyone to NOT EXPOSE THEIR CAMERAS/NVR TO THE INTERNET.

Click here to get the Chrome extension from GitHub

I am not publishing this on Google's extension store, but you can sideload it fairly easily.

Installation

Download the .zip file from the releases section.
  1. Extract the folder from this zip somewhere.
  2. Go to chrome's extensions page ( chrome:/extensions ).
  3. Enable the Developer mode option at the top right.
  4. Click Load unpacked and choose the DahuaLoginBypass folder you extracted.
Usage Instructions

Go to the login page of a Dahua IP camera and click the extension's icon ( image ) to the right of your address bar. This should add new buttons to the page for you to use.

image

Resetting Passwords

You can't change the password of an existing account without knowing its current password. To restore normal access, you either need to add a new account or factory reset the device.

Notes
  • Method 1 worked on all the cameras I tried. It does not give direct access to live video feeds, but you could use it to add or edit an existing user account to give you full access.
  • I could never get Method 2 to work on my cameras.
 
Last edited:
Very nice work bp2008.

I tried it against two Dahua cameras I have, and it was able to log into both with Method 1.
I tried it against a relatively recent DVR/NVR/XVR and it said 'not detected as a camera' and was unable to login.

Once logged into the camera, is there a way to change the admin account password or see the password in plaintext? Currently it seems like I would have to factory reset or add another admin-level account to 'take control' of the camera.
 
Hmm... You're right, the Modify Password function seems to require the old password to be sent. What the heck were they thinking? I guess you would need to create a new account like you said.

I tried having the extension create the new account, but Dahua's API was broken and the account that gets created can't be used for anything. (Dahua's web interface uses a different API which works correctly but uses encrypted arguments which makes it a lot more work to implement as a third-party).
 
  • Wow
Reactions: sebastiantombs
So, I've tried a number of other API calls now. The generic "modifyUser" command does not let you change the password either. And apparently it can add the "reserved" flag (which prevents the account from being deleted) but it can't remove that flag, so now I have some extra permanent accounts on my test camera unless I factory reset it. Yay for buggy software.

I've updated the original post with a section explaining it is impossible to reset lost passwords (at least not by any method known to me) and the only recourse is to create a new account or factory reset the camera.
 
  • Like
Reactions: adamg
I tried it against a relatively recent DVR/NVR/XVR and it said 'not detected as a camera' and was unable to login.

I don't have a Dahua DVR/NVR/XVR so I can't do much. I'm guessing they just used different html element IDs for the login form. If you could copy the page source of the login page, I could probably update the extension to work with it :)
 
When I click load unpacked and browses the folder no files show?
 
When I click load unpacked and browses the folder no files show?

It should unzip like this. You unblocked the zip after downloading and before unpacking?
There's also a chance a anti-virus app on your computer deleted the files soon after they were unpacked. Maybe check for logs in your AV software.
1634059745605.png
 
I don't have a Dahua DVR/NVR/XVR so I can't do much. I'm guessing they just used different html element IDs for the login form. If you could copy the page source of the login page, I could probably update the extension to work with it :)

1634060216470.png



1634060394662.png
 
Last edited:
@adamg that page source unfortunately came from before the page got rendered by javascript. Try opening the developer console (F12 or ctrl + shift + i) and in the console tab, paste document.body.innerHTML. This will print out the current content of the document body and you can push the copy button to put it on the clipboard.
 
@adamg that page source unfortunately came from before the page got rendered by javascript. Try opening the developer console (F12 or ctrl + shift + i) and in the console tab, paste document.body.innerHTML. This will print out the current content of the document body and you can push the copy button to put it on the clipboard.

Is this it?

HTML:
'<div class="x-component ux-wallpaper x-fit-item x-component-default" style="position: absolute; overflow: hidden; z-index: -1; margin: 0px; width: 2005px; height: 1329px;" id="wallpaper-1013"><img src="/baseProj/images/bg.jpg" id="ext-gen1043" style="width: 100%; height: 100%;"></div><div class="x-panel x-fit-item x-panel-default" id="ext-comp-1009" style="right: auto; left: 0px; top: 0px; margin: 0px; width: 2005px; height: 1329px;"><div id="ext-comp-1009-body" class="x-panel-body x-panel-body-default x-box-layout-ct x-panel-body-default" style="width: 2005px; height: 1329px; left: 0px; top: 0px;"><div id="ext-comp-1009-innerCt" class="x-box-inner " role="presentation" style="width: 2005px; height: 1329px;"><div id="ext-comp-1009-targetEl" class="x-box-target" style="width: 2005px;"><div class="h-login-window x-box-item h-login-window-default" style="width: 320px; height: 550px; right: auto; left: 842.5px; top: 390px; margin: 0px;" id="panel-1011"><div id="panel-1011-body" class="h-login-window-body h-login-window-body-default x-box-layout-ct h-login-window-body-default" style="width: 320px; height: 550px; left: 0px; top: 0px;"><div id="panel-1011-innerCt" class="x-box-inner " role="presentation" style="height: 550px; width: 320px;"><div id="panel-1011-targetEl" class="x-box-target" style="width: 320px;"><div class="x-img login_logo x-box-item x-img-default" id="image-1010" style="right: auto; left: 0px; margin: 0px; width: 320px; top: 15px;"><img id="image-1010-img" src="/custom_logo/web_logo.png?v=1634061974249"></div><table class="undefined align-left x-table-plain x-form-item x-form-type-text x-box-item -default x-vbox-form-item x-form-dirty" style="width: 320px; height: 40px; table-layout: fixed; right: auto; left: 0px; margin: 0px; top: 140px;" cellpadding="0" id="loginUsername"><tbody><tr role="presentation" id="loginUsername-inputRow" class="x-form-item-input-row"><td role="presentation" id="loginUsername-labelCell" style="display:none;" valign="top" halign="left" width="185" class="x-field-label-cell"><label id="loginUsername-labelEl" for="loginUsername-inputEl" class="x-form-item-label textlabel x-unselectable textlabel-left cuttitle" style="width:180px;margin-right:5px;" unselectable="on" title=""></label></td><td role="presentation" class="x-form-item-body  " id="loginUsername-bodyEl" colspan="3" style="width: 100%;"><input id="loginUsername-inputEl" type="text" size="1" name="loginUsername-inputEl" placeholder="Username" class="login_input login_username x-form-text" autocomplete="off" aria-invalid="false" data-errorqtip="" style="width: 100%; height: 40px;"></td></tr></tbody></table><table class="x-field x-table-plain x-form-item x-form-type-text x-form-dirty x-box-item x-field-default x-vbox-form-item" style="width: 260px; height: 38px; display: none;" cellpadding="0" id="loginUserSelect"><tbody><tr role="presentation" id="loginUserSelect-inputRow" class="x-form-item-input-row"><td role="presentation" id="loginUserSelect-labelCell" style="display:none;" valign="top" halign="left" width="185" class="x-field-label-cell"><label id="loginUserSelect-labelEl" for="loginUserSelect-inputEl" class="x-form-item-label combo-label x-unselectable cuttitle" style="width:180px;margin-right:5px;" unselectable="on" title=""></label></td><td role="presentation" class="x-form-item-body  " id="loginUserSelect-bodyEl" colspan="3"><table id="loginUserSelect-triggerWrap" class="x-form-trigger-wrap" cellpadding="0" cellspacing="0"><tbody><tr><td id="loginUserSelect-inputCell" class="x-form-trigger-input-cell"><div class="x-hide-display x-form-data-hidden" role="presentation" id="ext-gen1046"></div><input id="loginUserSelect-inputEl" type="text" class="login_input login_netInput x-form-text x-trigger-noedit" autocomplete="off" name="loginUserSelect-inputEl" readonly="readonly" aria-invalid="false"></td><td valign="top" class=" x-trigger-cell x-unselectable" style="width:22px;" id="ext-gen1045"><div class="x-trigger-index-0 x-form-trigger combo-select x-form-trigger-first" role="button" id="ext-gen1044"></div></td></tr></tbody></table></td></tr></tbody></table><table class="x-field x-table-plain x-form-item x-form-type-text x-form-dirty x-box-item x-field-default x-vbox-form-item" style="width: 260px; height: 38px; display: none;" cellpadding="0" id="loginUDongSelect"><tbody><tr role="presentation" id="loginUDongSelect-inputRow" class="x-form-item-input-row"><td role="presentation" id="loginUDongSelect-labelCell" style="display:none;" valign="top" halign="left" width="185" class="x-field-label-cell"><label id="loginUDongSelect-labelEl" for="loginUDongSelect-inputEl" class="x-form-item-label combo-label x-unselectable cuttitle" style="width:180px;margin-right:5px;" unselectable="on" title=""></label></td><td role="presentation" class="x-form-item-body  " id="loginUDongSelect-bodyEl" colspan="3"><table id="loginUDongSelect-triggerWrap" class="x-form-trigger-wrap" cellpadding="0" cellspacing="0"><tbody><tr><td id="loginUDongSelect-inputCell" class="x-form-trigger-input-cell"><div class="x-hide-display x-form-data-hidden" role="presentation" id="ext-gen1056"></div><input id="loginUDongSelect-inputEl" type="text" class="login_input login_netInput x-form-text x-trigger-noedit" autocomplete="off" name="loginUDongSelect-inputEl" readonly="readonly" aria-invalid="false"></td><td valign="top" class=" x-trigger-cell x-unselectable" style="width:22px;" id="ext-gen1055"><div class="x-trigger-index-0 x-form-trigger combo-select x-form-trigger-first" role="button" id="ext-gen1054"></div></td></tr></tbody></table></td></tr></tbody></table><table class="undefined align-left x-table-plain x-form-item x-form-type-text x-box-item -default x-vbox-form-item" style="width: 260px; height: 32px; display: none;" cellpadding="0" id="loginPinCode"><tbody><tr role="presentation" id="loginPinCode-inputRow" class="x-form-item-input-row"><td role="presentation" id="loginPinCode-labelCell" style="display:none;" valign="top" halign="left" width="185" class="x-field-label-cell"><label id="loginPinCode-labelEl" for="loginPinCode-inputEl" class="x-form-item-label textlabel x-unselectable" style="width:180px;margin-right:5px;" unselectable="on"></label></td><td role="presentation" class="x-form-item-body  " id="loginPinCode-bodyEl" colspan="3"><input id="loginPinCode-inputEl" type="text" size="1" name="loginPinCode-inputEl" placeholder="PIN Code" class="x-form-field x-form-empty-field x-form-text" autocomplete="off" aria-invalid="false"></td></tr></tbody></table><table class="x-field x-table-plain x-form-item x-form-type-password x-box-item x-field-default x-vbox-form-item" style="width: 320px; height: 38px; table-layout: fixed; right: auto; left: 0px; margin: 0px; top: 200px;" cellpadding="0" id="loginPassword"><tbody><tr role="presentation" id="loginPassword-inputRow" class="x-form-item-input-row"><td role="presentation" id="loginPassword-labelCell" style="display:none;" valign="top" halign="left" width="185" class="x-field-label-cell"><label id="loginPassword-labelEl" for="loginPassword-inputEl" class="x-form-item-label x-unselectable x-form-item-label-left cuttitle" style="width:180px;margin-right:5px;" unselectable="on" title=""></label></td><td role="presentation" class="x-form-item-body  " id="loginPassword-bodyEl" colspan="3" style="width: 100%;"><table id="loginPassword-triggerWrap" class="x-form-trigger-wrap" cellpadding="0" cellspacing="0" style="width: 100%; table-layout: fixed;"><tbody><tr><td id="loginPassword-inputCell" class="x-form-trigger-input-cell" style="width: 100%;"><input id="loginPassword-inputEl" type="password" size="1" name="loginPassword-inputEl" placeholder="Password" maxlength="32" class="login_input login_password x-form-empty-field x-form-text" autocomplete="off" aria-invalid="false" data-errorqtip="" style="width: 100%; height: 38px;"></td><td valign="top" class=" x-trigger-cell x-unselectable" style="width:22px;" id="ext-gen1058"><div class="x-trigger-index-0 x-form-trigger login_eyeOpen x-form-trigger-first" role="button" id="ext-gen1057"></div></td></tr></tbody></table></td></tr></tbody></table><table class="x-field x-table-plain x-form-item x-form-type-text x-form-dirty x-box-item x-field-default x-vbox-form-item" style="width: 320px; height: 38px; table-layout: fixed; right: auto; left: 0px; margin: 0px; top: 258px;" cellpadding="0" id="loginNetSelect"><tbody><tr role="presentation" id="loginNetSelect-inputRow" class="x-form-item-input-row"><td role="presentation" id="loginNetSelect-labelCell" style="display:none;" valign="top" halign="left" width="185" class="x-field-label-cell"><label id="loginNetSelect-labelEl" for="loginNetSelect-inputEl" class="x-form-item-label combo-label x-unselectable cuttitle combo-label-left" style="width:180px;margin-right:5px;" unselectable="on" title=""></label></td><td role="presentation" class="x-form-item-body  " id="loginNetSelect-bodyEl" colspan="3" style="width: 100%;"><table id="loginNetSelect-triggerWrap" class="x-form-trigger-wrap" cellpadding="0" cellspacing="0" style="width: 100%; table-layout: fixed;"><tbody><tr><td id="loginNetSelect-inputCell" class="x-form-trigger-input-cell" style="width: 100%;"><div class="x-hide-display x-form-data-hidden" role="presentation" id="ext-gen1061"></div><input id="loginNetSelect-inputEl" type="text" class="login_input login_netInput x-form-text x-trigger-noedit cuttitle" autocomplete="off" value="TCP" name="loginNetSelect-inputEl" readonly="readonly" aria-invalid="false" data-errorqtip="" title="" style="width: 100%; height: 38px;"></td><td valign="top" class=" x-trigger-cell x-unselectable" style="width:22px;" id="ext-gen1060"><div class="x-trigger-index-0 x-form-trigger combo-select x-form-trigger-first" role="button" id="ext-gen1059"></div></td></tr></tbody></table></td></tr></tbody></table><a class="x-btn login_forgetPwd x-unselectable x-box-item x-btn-default-small x-noicon x-btn-noicon x-btn-default-small-noicon hyperlinklogin_forgetPwd" style="height: 40px; right: auto; left: 0px; margin: 0px; width: 320px; top: 316px; display: none;" role="button" hidefocus="on" unselectable="on" tabindex="0" id="loginForgetPwd"><span id="loginForgetPwd-btnWrap" class="x-btn-wrap" unselectable="on" style="height: 34px;"><span id="loginForgetPwd-btnEl" class="x-btn-button" style="height: 34px;"><span id="loginForgetPwd-btnInnerEl" class="x-btn-inner x-btn-inner-center cuttitle" unselectable="on" style="line-height: normal; padding-top: 8px;"><span t="com.Forgetsecret">Forgot password?</span></span><span role="img" id="loginForgetPwd-btnIconEl" class="x-btn-icon-el  " unselectable="on" style=""></span></span></span></a><a class="x-btn login_button x-unselectable x-box-item x-btn-default-small x-noicon x-btn-noicon x-btn-default-small-noicon button" style="height: 40px; right: auto; left: 0px; margin: 0px; width: 320px; top: 316px;" role="button" hidefocus="on" unselectable="on" tabindex="0" id="loginButton"><span id="loginButton-btnWrap" class="x-btn-wrap" unselectable="on" style="height: 32px;"><span id="loginButton-btnEl" class="x-btn-button" style="height: 32px;"><span id="loginButton-btnInnerEl" class="x-btn-inner x-btn-inner-center cuttitle" unselectable="on" style="line-height: normal; padding-top: 3px;"><span t="com.Login">Login</span></span><span role="img" id="loginButton-btnIconEl" class="x-btn-icon-el  " unselectable="on" style=""></span></span></span></a></div></div></div></div></div></div></div></div> <\script type="text/javascript" src="./pluginVersion.js"><\/script> <\script type="text/javascript" src="./webVersion.js"><\/script> <\script type="text/javascript" src="./cap.js"><\/script> <div class="x-textmetrics" id="ext-gen1047" style="font-size: 16px; font-style: normal; font-weight: 400; font-family: arial, &quot;Microsoft YaHei&quot;; line-height: 24px; text-transform: none; letter-spacing: normal; position: absolute; right: auto; left: -1000px; top: -1000px; visibility: hidden; width: auto;"></div><div class="x-tip x-layer x-tip-default x-border-box" id="ext-quicktips-tip" style="display: none;"><div class="x-tip-header x-header x-header-horizontal x-docked x-unselectable x-tip-header-default x-horizontal x-tip-header-horizontal x-tip-header-default-horizontal x-top x-tip-header-top x-tip-header-default-top x-docked-top x-tip-header-docked-top x-tip-header-default-docked-top" id="ext-quicktips-tip_header"><div id="ext-quicktips-tip_header-body" class="x-header-body x-tip-header-body x-tip-header-body-default x-tip-header-body-horizontal x-tip-header-body-default-horizontal x-tip-header-body-top x-tip-header-body-default-top x-tip-header-body-docked-top x-tip-header-body-default-docked-top x-box-layout-ct x-tip-header-body-default-horizontal x-tip-header-body-default-top x-tip-header-body-default-docked-top"><div id="ext-quicktips-tip_header-innerCt" class="x-box-inner " role="presentation"><div id="ext-quicktips-tip_header-targetEl" class="x-box-target"><div class="x-component x-header-text-container x-tip-header-text-container x-tip-header-text-container-default x-box-item x-component-default" unselectable="on" id="ext-quicktips-tip_header_hd"><span id="ext-quicktips-tip_header_hd-textEl" class="x-header-text x-tip-header-text x-tip-header-text-default" unselectable="on">&nbsp;</span></div></div></div></div></div><div id="ext-quicktips-tip-body" class="x-tip-body x-tip-body-default x-tip-body-default"><span id="ext-quicktips-tip-outerCt" style="display:table;"><div id="ext-quicktips-tip-innerCt" style="display:table-cell;height:100%;vertical-align:top;" class=""></div></span></div><div class="x-tip-anchor x-tip-anchor-top" id="ext-gen1053"></div></div>'
 
Try version 2. It should recognize NVRs matching the html that @adamg provided, and it should also be usable now on pages that are not recognized; it simply will not try to mount its GUI below the login button or auto-fill the credentials and click the login button for you in that case.
 
bp2008, v2 doesn't get me into the XVR that I posted specs of above. Perhaps it's version is too new and not vulnerable.
If you are on MS Teams I can probably do a screen share to demonstrate, PM me.
 
Method 1 will not work on NVR/DVR/XVR.. etc, but will work when using http(s) on vulnerable IPC/VTO/VTH.. etc.
Method 2 will not work at all with any device when using http(s), as it requires DHIP protocol - then it will work on vulnerable IPC/VTO/VTH/NVR/DVR/XVR... etc.
 
I didn't find documentation of the DHIP protocol so I assumed that was just what you were calling Dahua's internal RPC API (as opposed to the publicly documented API that goes through /cgi-bin/). Apparently it is something entirely different.
 
No probs, wanted to spare you (and others) some headache, besides, I wrote what protocol was needed for each CVE - but maybe it wasn't clear enough.

I hope they are paying you for finding this stuff.

Nobody paying me for this, I actually spending way to much of my free time and money on this, but that's the curious life of researching.
(CTF never been interesting for me, as you "know" there is something pretty obvious, with Dahua there is "always" something, but not so obvious)

Cool extension to Chrome, exactly what I was thinking (but never did) back in the days with Dahua backdoor! :)