Page Menu
Home
Sealhub
Search
Configure Global Search
Log In
Files
F10361127
index.html
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
12 KB
Referenced Files
None
Subscribers
None
index.html
View Options
<!doctype html>
<
html
lang
=
"en"
>
<
head
style
=
"height: 100vh"
>
<
meta
charset
=
"UTF-8"
/>
<
title
>
Rentgen android
</
title
>
<
script
src
=
"/htmx.js"
></
script
>
<
style
>
main
{
display
:
flex
;
}
.
log-section
{
height
:
auto
;
width
:
400
px
;
overflow
:
auto
;
display
:
flex
;
flex-direction
:
column
;
margin-left
:
20
px
;
}
.
screen
{
display
:
inline-block
;
cursor
:
pointer
;
}
.
screen-buttons
{
display
:
flex
;
justify-content
:
space-around
;
margin-top
:
5
px
;
gap
:
10
px
;
}
.
screen-buttons
button
{
font-size
:
1.1
rem
;
padding
:
10
px
20
px
;
width
:
100
%
;
cursor
:
pointer
;
background-color
:
transparent
;
}
.
screen-buttons
button
:
hover
{
background-color
:
aqua
;
}
#
clicks-log
{
font-family
:
Menlo
,
Consolas
,
Monaco
,
Liberation
Mono
,
Lucida
Console
,
monospace
;
}
.
tab
{
border
:
1
px
solid
#ccc
;
background-color
:
#f1f1f1
;
}
/* Style the buttons that are used to open the tab content */
.
tab
button
{
background-color
:
inherit
;
float
:
left
;
border
:
none
;
outline
:
none
;
cursor
:
pointer
;
padding
:
14
px
16
px
;
transition
:
0.3
s
;
}
/* Change background color of buttons on hover */
.
tab
button
:
hover
{
background-color
:
#ddd
;
}
/* Create an active/current tablink class */
.
tab
button
.
active
{
background-color
:
#ccc
;
}
.
tabcontent
.
active
{
display
:
flex
;
flex-direction
:
column
;
flex-grow
:
1
;
}
/* Style the tab content */
.
tabcontent
{
display
:
none
;
padding
:
6
px
12
px
;
border
:
1
px
solid
#ccc
;
border-top
:
none
;
}
html
,
body
,
main
{
width
:
100
%
;
height
:
100
%
;
overflow
:
hidden
;
margin
:
0
;
}
main
{
display
:
flex
;
flex-direction
:
row
;
align-items
:
stretch
;
}
#
logs-tab
{
overflow
:
auto
;
text-wrap
:
wrap
;
}
.
screen-section
{
display
:
flex
;
flex-direction
:
column
;
}
.
screen-section
#
screen
,
.
screen-section
.
screen_buttons
{
flex-grow
:
0
;
}
#
screen
{
user-select
:
none
;
}
.
tab-section
{
display
:
flex
;
flex-direction
:
column
;
flex-grow
:
1
;
}
#
resp
{
display
:
none
;
}
#
upload_form
{
display
:
flex
;
flex-direction
:
column
;
}
#
upload_form
button
,
#
upload_form
label
{
border
:
2
px
solid
#ccc
;
background-color
:
#f1f1f1
;
cursor
:
pointer
;
padding
:
3
px
10
px
;
transition
:
0.3
s
;
}
#
upload_form
button
:
hover
,
#
upload_form
label
:
hover
{
background-color
:
#ddd
;
}
#
notifications
{
width
:
40
%
;
margin-left
:
60
%
;
position
:
absolute
;
}
</
style
>
</
head
>
<
body
>
<
div
id
=
"notifications"
></
div
>
<
div
id
=
"resp"
style
=
"display: none"
></
div
>
<
main
>
<
section
class
=
"screen-section"
>
<
img
id
=
"screen"
alt
=
"android screen"
src
=
""
draggable
=
"false"
class
=
"screen"
style
=
"flex-grow: 0"
tabindex
=
"0"
/>
<
div
class
=
"screen-buttons"
style
=
"flex-grow: 0"
>
<
button
class
=
"screen-buttons-home"
>
home
</
button
>
<
button
class
=
"screen-buttons-back"
>
back
</
button
>
</
div
>
<
form
id
=
"upload_form"
hx-post
=
"/upload_apk"
enctype
=
"multipart/form-data"
hx-target
=
"#resp"
>
<
label
id
=
"upload_input"
for
=
"app"
>
Select file
<
input
type
=
"file"
id
=
"app"
name
=
"app"
accept
=
".apk"
required
multiple
/>
</
label
>
<
button
type
=
"submit"
>
Install the app
</
button
>
</
form
>
</
section
>
<
div
class
=
"tab-section"
>
<
div
class
=
"tab"
>
<
button
class
=
"tablinks active"
onclick
=
"open_tab(event, 'httptoolkit-tab')"
>
HttpToolkit UI
</
button
>
<
button
class
=
"tablinks"
onclick
=
"open_tab(event, 'logs-tab')"
>
Logs
</
button
>
<
button
class
=
"tablinks"
onclick
=
"open_tab(event, 'controls-tab')"
>
Device Controls
</
button
>
</
div
>
<
div
class
=
"tabcontent"
id
=
"logs-tab"
>
<
p
id
=
"clicks-log"
class
=
"log-section"
></
p
>
<
p
id
=
"traffic-log"
class
=
"log-section"
></
p
>
</
div
>
<
div
class
=
"tabcontent active"
id
=
"httptoolkit-tab"
>
<
iframe
id
=
"httptoolkit-frame"
style
=
"flex-grow: 1"
src
=
"http://localhost:9080/"
title
=
"httptoolkit"
></
iframe
>
</
div
>
<
div
class
=
"tabcontent"
id
=
"controls-tab"
>
<
form
id
=
"set_coords"
onsubmit
=
"coords_handler(event)"
>
<
label
>
Latitude:
<
input
type
=
"text"
name
=
"lat"
/>
</
label
>
<
label
>
Longitude:
<
input
type
=
"text"
name
=
"lon"
/>
</
label
>
<
button
type
=
"submit"
>
Submit coords
</
button
>
</
form
>
<
button
id
=
"reset_adid_btn"
onclick
=
"reset_adid_handler(event)"
>
Reset ADID
</
button
>
<
table
>
<
thead
></
thead
>
<
tbody
>
<
tr
>
<
td
>
ADID:
</
td
>
<
td
id
=
"adid_priv_info_table"
>
UNKNOWN
</
td
>
</
tr
>
<
tr
>
<
td
>
Longitude:
</
td
>
<
td
id
=
"lon_priv_info_table"
>
UNKNOWN
</
td
>
</
tr
>
<
tr
>
<
td
>
Latitude:
</
td
>
<
td
id
=
"lat_priv_info_table"
>
UNKNOWN
</
td
>
</
tr
>
</
tbody
>
</
table
>
</
div
>
</
div
>
</
main
>
<
script
src
=
"/socket.io.js"
></
script
>
<
script
>
var
socket
=
io
();
function
reset_adid_handler
(
e
)
{
socket
.
emit
(
"reset_adid"
);
}
function
coords_handler
(
e
)
{
e
.
preventDefault
();
const
form_data
=
new
FormData
(
e
.
target
);
console
.
log
(
form_data
);
socket
.
emit
(
"setcoord"
,
{
lon
:
Number
.
parseFloat
(
form_data
.
get
(
"lon"
)),
lat
:
Number
.
parseFloat
(
form_data
.
get
(
"lat"
)),
});
}
function
open_tab
(
evt
,
tab_name
)
{
let
i
,
tabcontent
,
tablinks
;
// Get all elements with class="tabcontent" and hide them
tabcontent
=
document
.
getElementsByClassName
(
"tabcontent"
);
for
(
i
=
0
;
i
<
tabcontent
.
length
;
i
++
)
{
if
(
tabcontent
[
i
].
id
!=
tab_name
)
{
tabcontent
[
i
].
classList
.
remove
(
"active"
);
}
else
{
tabcontent
[
i
].
classList
.
add
(
"active"
);
}
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks
=
document
.
getElementsByClassName
(
"tablinks"
);
for
(
i
=
0
;
i
<
tablinks
.
length
;
i
++
)
{
tablinks
[
i
].
classList
.
remove
(
"active"
);
}
// Show the current tab, and add an "active" class to the button that opened the tab
evt
.
currentTarget
.
classList
.
add
(
"active"
);
}
var
screen
=
document
.
getElementById
(
"screen"
);
var
clicksLog
=
document
.
getElementById
(
"clicks-log"
);
const
homeButton
=
document
.
querySelector
(
".screen-buttons-home"
);
const
backButton
=
document
.
querySelector
(
".screen-buttons-back"
);
let
lastTouch
=
new
Date
().
getTime
();
const
calculateElapsedTime
=
(
last
)
=>
{
const
currentTouch
=
new
Date
().
getTime
();
const
elapsedTime
=
currentTouch
-
lastTouch
;
const
elapsedSec
=
Math
.
round
(
elapsedTime
/
1000
);
lastTouch
=
currentTouch
;
return
elapsedSec
;
};
const
waitToLog
=
(
clickInfoText
)
=>
{
const
clickInfo
=
document
.
createElement
(
"span"
);
const
waitInfo
=
document
.
createElement
(
"span"
);
waitInfo
.
textContent
=
`await wait(
${
calculateElapsedTime
(
lastTouch
)}
);`
;
clicksLog
.
appendChild
(
waitInfo
);
clickInfo
.
textContent
=
clickInfoText
;
clicksLog
.
appendChild
(
clickInfo
);
};
const
registerClick
=
({
path
,
logText
,
body
})
=>
{
const
clicksLog
=
document
.
getElementById
(
"clicks-log"
);
const
span
=
document
.
createElement
(
"span"
);
waitToLog
(
logText
);
socket
.
emit
(
path
,
body
?
body
:
{});
};
homeButton
.
addEventListener
(
"click"
,
()
=>
registerClick
({
path
:
"home"
,
logText
:
"await homeButton();"
})
);
backButton
.
addEventListener
(
"click"
,
()
=>
registerClick
({
path
:
"back"
,
logText
:
"await backButton();"
})
);
socket
.
on
(
"screenshot_data"
,
(
data
)
=>
{
try
{
const
blob
=
new
Blob
([
data
]);
screen
.
src
=
URL
.
createObjectURL
(
blob
);
}
catch
(
error
)
{
console
.
error
(
"Error fetching image: "
,
error
);
}
});
socket
.
on
(
"private_info"
,
(
data
)
=>
{
console
.
log
(
"private_info"
);
adid_priv_info_table
.
textContent
=
data
.
adid
;
lat_priv_info_table
.
textContent
=
data
.
latitude
;
lon_priv_info_table
.
textContent
=
data
.
longitude
;
});
socket
.
emit
(
"private_info_req"
);
socket
.
onAny
((
ev
,
...
args
)
=>
{
console
.
log
(
"ev: "
,
ev
,
args
);
});
async
function
displayImage
()
{
socket
.
emit
(
"screenshot"
);
}
let
isDragging
=
false
;
const
screenSize
=
[
320
,
640
];
function
calcMousePos
(
event
)
{
let
rect
=
screen
.
getBoundingClientRect
();
let
x
=
((
event
.
clientX
-
rect
.
left
)
/
rect
.
width
)
*
screenSize
[
0
];
let
y
=
((
event
.
clientY
-
rect
.
top
)
/
rect
.
height
)
*
screenSize
[
1
];
x
=
Math
.
min
(
Math
.
max
(
x
,
0
),
screenSize
[
0
]);
y
=
Math
.
min
(
Math
.
max
(
y
,
0
),
screenSize
[
1
]);
return
{
x
,
y
};
}
screen
.
addEventListener
(
"mousemove"
,
(
event
)
=>
{
if
(
!
isDragging
)
return
;
let
pos
=
calcMousePos
(
window
.
event
);
if
(
isDragging
)
{
registerClick
({
path
:
"motionevent"
,
logText
:
`await motionevent({motionType: "MOVE", x:
${
pos
.
x
}
,y:
${
pos
.
y
}
}});`
,
body
:
{
motionType
:
"MOVE"
,
x
:
pos
.
x
,
y
:
pos
.
y
,
},
});
}
},
false
);
const
handleDraggStart
=
(
event
)
=>
{
isDragging
=
true
;
let
pos
=
calcMousePos
(
event
);
registerClick
({
path
:
"motionevent"
,
logText
:
`await motionevent({motionType: "DOWN", x:
${
pos
.
x
}
,y:
${
pos
.
y
}
}});`
,
body
:
{
motionType
:
"DOWN"
,
x
:
pos
.
x
,
y
:
pos
.
y
,
},
});
};
screen
.
addEventListener
(
"mousedown"
,
handleDraggStart
);
document
.
addEventListener
(
"mouseup"
,
(
e
)
=>
{
if
(
!
isDragging
)
return
;
isDragging
=
false
;
let
pos
=
calcMousePos
(
e
);
registerClick
({
path
:
"motionevent"
,
logText
:
`await motionevent({motionType: "MOVE", x:
${
pos
.
x
}
,y:
${
pos
.
y
}
}});`
,
body
:
{
motionType
:
"MOVE"
,
x
:
pos
.
x
,
y
:
pos
.
y
,
},
});
registerClick
({
path
:
"motionevent"
,
logText
:
`await motionevent({motionType: "UP", x:
${
pos
.
x
}
,y:
${
pos
.
y
}
}});`
,
body
:
{
motionType
:
"UP"
,
x
:
pos
.
x
,
y
:
pos
.
y
,
},
});
});
window
.
addEventListener
(
"keydown"
,
(
event
)
=>
{
let
key
=
event
.
key
;
if
(
key
===
"Space"
)
key
=
" "
;
else
if
(
key
!==
"Enter"
&&
key
!==
"Backspace"
&&
key
.
length
!==
1
)
return
;
console
.
log
(
event
.
key
,
key
);
if
(
document
.
getElementById
(
"screen"
).
matches
(
":hover"
))
{
registerClick
({
path
:
"key"
,
logText
:
`await key(
${
event
.
key
}
);`
,
body
:
{
key
},
});
}
});
async
function
sleep
(
time
)
{
return
new
Promise
((
resolve
)
=>
setTimeout
(
resolve
,
time
));
}
async
function
screenshot_loop
()
{
var
before
;
while
(
true
)
{
before
=
performance
.
now
();
await
displayImage
();
while
(
performance
.
now
()
-
before
<
___screenshotDelayMs___
)
await
sleep
(
50
);
}
}
screenshot_loop
();
</
script
>
<
script
src
=
"/trafficLog.js"
></
script
>
<
script
src
=
"/notifications.js"
></
script
>
</
body
>
</
html
>
File Metadata
Details
Attached
Mime Type
text/html
Expires
Sat, Nov 8, 11:20 (20 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1034518
Default Alt Text
index.html (12 KB)
Attached To
Mode
R134 rentgen-android
Attached
Detach File
Event Timeline
Log In to Comment