There are some stack overflow vulnerability in cisco IOS system like CVE-2017-6736 and CVE-2018-0171,but there are little exp or analysis for those vulnerability .So it’s hard to develop a rop chain. Recently I develop a CVE-2017-6736 exp for c2600, I want to record the analysis for this.
Firstly, we can enable the cisco debug output using debug all
command, when we connect the 23 port with telnet, we can see the string AAA/LOCAL: exec
, follow the string, we can find the function process aaa auth like this:
After some debug, I find that when the call of p_ptr
return 1, we can get lv1 shell directly. So the first step for rop is overwrite the p_ptr
to a gadget which return 1. Like this:
.text:80008210 loc_80008210: # CODE XREF: sub_8000819C+24↑j
.text:80008210 li r3, 1
.text:80008214 blr
Notice: the end of the gadget must be blr , becase the call of powerpc always be bctrl
, which set the lr register, so we must choose the instruction that jmp to the lr register.
After get lv1 shell, we must get lv15 privilege to control the switch. I notice that when I use enable
command and input the wrong password, it will print Bad secrets
. So I find the xrefs for it. After some debug ,I find some interesting things:
when the wtf_flag
is 0, and the function pointer
off_8234AC7C
return 1 , the function can returns 1 then we can get lv15 shell. Then I overwrite those memory and success get the lv15 shell.
But there are some tricks for ppc rop develop. Firstly, CVE-2017-6736 can’t overflow much byte, so we can’t overwrite those memory with only one time. After overwrite one address , we must ensure that the snmp server run normally. A good way for this is return to the snmp thread function, it’s easy to find:
For gadget choose, there must be the instruction which get return address from stack and set the lr register like this:
.text:805CF304 stw r4, 0(r3)
.text:805CF308 li r3, 1
.text:805CF30C
.text:805CF30C loc_805CF30C: # CODE XREF: sub_805CF2C4+3C↑j
.text:805CF30C lwz r0, 12(r1)
.text:805CF310 mtlr r0
.text:805CF314 addi r1, r1, 8
.text:805CF318 blr
the gadget store the r4 register to [r3], and get the return address from 12(r1)( the r1 register is the stack pointer ).
others like this,is useless for rop development:
.text:817D235C lwz r9, 8(r1)
.text:817D2360 lwz r0, 0x10(r1)
.text:817D2364 stw r0, 0x34(r9)
.text:817D2368 addi r1, r1, 0x18
.text:817D236C blr
It seems like complete address in one gadget, but we can’t control the lr register , so it while be a endless loop or crash.